Author: eallen
Date: 2009-07-06 12:55:10 -0400 (Mon, 06 Jul 2009)
New Revision: 3478
Modified:
mgmt/trunk/cumin/python/cumin/grid/collector.py
mgmt/trunk/cumin/python/cumin/grid/pool.py
mgmt/trunk/cumin/python/cumin/stat.py
Log:
Implementing stacked area charts (in lieu of stacked bar charts)
Modified: mgmt/trunk/cumin/python/cumin/grid/collector.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/collector.py 2009-07-04 18:17:09 UTC (rev 3477)
+++ mgmt/trunk/cumin/python/cumin/grid/collector.py 2009-07-06 16:55:10 UTC (rev 3478)
@@ -83,20 +83,22 @@
chart = self.JobStackedChart(app, "jobs")
chart.stats = ("RunningJobs", "IdleJobs")
+ chart.chart_type = "stacked"
self.add_child(chart)
chart = self.SlotStackedChart(app, "slots")
chart.stats = ("HostsClaimed", "HostsUnclaimed",
"HostsOwner")
+ chart.chart_type = "stacked"
self.add_child(chart)
def render_title(self, session):
return "Statistics"
- class JobStackedChart(StatStackedChart):
+ class JobStackedChart(StatFlashChart):
def render_title(self, session, *args):
return "Job Status"
- class SlotStackedChart(StatStackedChart):
+ class SlotStackedChart(StatFlashChart):
def render_title(self, session, *args):
return "Slot State"
Modified: mgmt/trunk/cumin/python/cumin/grid/pool.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/pool.py 2009-07-04 18:17:09 UTC (rev 3477)
+++ mgmt/trunk/cumin/python/cumin/grid/pool.py 2009-07-06 16:55:10 UTC (rev 3478)
@@ -261,11 +261,12 @@
chart = self.JobStackedChart(app, "jobs")
chart.duration.param.default = "3600"
chart.stats = ("RunningJobs", "IdleJobs")
+ chart.chart_type = "stacked"
self.add_child(chart)
- chart = self.SlotStackedChart(app, "slots")
- chart.duration.param.default = "3600"
+ chart = self.SlotFlashChart(app, "slots")
chart.stats = ("HostsClaimed", "HostsUnclaimed",
"HostsOwner")
+ chart.chart_type = "stacked"
self.add_child(chart)
def render_title(self, session):
@@ -283,14 +284,14 @@
def get_args(self, session):
return self.parent.get_collector_args(session)
- class JobStackedChart(StatStackedChart):
+ class JobStackedChart(StatFlashChart):
def render_title(self, session, *args):
return "Job Status"
def get_args(self, session):
return self.parent.get_collector_args(session)
- class SlotStackedChart(StatStackedChart):
+ class SlotFlashChart(StatFlashChart):
def render_title(self, session, *args):
return "Slot State"
Modified: mgmt/trunk/cumin/python/cumin/stat.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/stat.py 2009-07-04 18:17:09 UTC (rev 3477)
+++ mgmt/trunk/cumin/python/cumin/stat.py 2009-07-06 16:55:10 UTC (rev 3478)
@@ -810,96 +810,14 @@
return y_axis, y_axis_right
-class StackedChart(FlashChart):
+class AreaChart(FlashChart):
def __init__(self, app, name, page):
- super(StackedChart, self).__init__(app, name, page)
+ super(AreaChart, self).__init__(app, name, page)
- self.points = self.Points(app, "points")
- self.add_attribute(self.points)
+ self.alpha = 0.3
def fetch_samples(self, object, dur, interval, method, mode, delta, stats):
samples = dict()
-
- # don't average for stacked charts
- interval = 1
- for stat in stats:
- samples[stat] = stat.samples(object, dur, interval, method)
- return samples
-
- def get_max_min(self, session, stats, samples):
- max_value = 0
- min_value = 0
- points = dict()
- values = dict()
- collapsed = dict()
-
- for stat in stats:
- for sample in samples[stat]:
- collapsed[sample[0]] = sample[1]
-
- for t in collapsed:
- if not t in points:
- points[t] = list()
- values[t] = 0
- points[t].append(collapsed[t])
- values[t] = values[t] + collapsed[t]
- max_value = max(values[t], max_value)
- min_value = min(values[t], min_value)
-
- # save the accumulated values for each timestamp
- self.points.set(session, points)
-
- max_value = round(max_value * 1.1 + 1)
- if min_value < 0:
- min_value = round(min_value * 1.1 - 1)
-
- return max_value, min_value
-
- def get_chart(self, session, stats, samples, duration, max_value, min_value,
append):
- time_period = self.page.duration.get(session)
- chart = Chart()
- chart.title.text = ""
- chart.bg_colour = "#FFFFFF"
- chart.elements = list()
- element = Element()
- element.type = "bar_stack"
- element.colours = list(self.colors)
-
- points = self.points.get(session)
- values = list()
- for point in points:
- values.append(points[point])
- element.values = values
-
- keys = list()
- for stat, color in zip(stats, self.colors):
- key = dict()
- key['colour'] = color
- key['text'] = stat.title
- keys.append(key)
- element.keys = keys
-
- element.tip = "#key#: #val#<br>Total: #total#"
- chart.elements.append(element)
-
- if append:
- chart.append = self.get_elapsed(session)['value']
- #print "append: time_period=%i duration=%i elapsed=%f" %
(time_period, duration, float(self.get_elapsed(session)['value']))
- return chart
- #chart.x_axis = self.get_x_axis(duration)
- y_axis, y_axis_right = self.get_y_axis(max_value, min_value)
- chart.y_axis = y_axis
- chart.y_axis_right = y_axis_right
-
- return chart
-
- class Points(Attribute):
- def get_default(self, session):
- return dict()
-
-class AreaChart(FlashChart):
- def fetch_samples(self, object, dur, interval, method, mode, delta, stats):
- samples = dict()
if mode == "rate":
method = None # don't do averaging
if delta: # need more than 1 point for calculating rate
@@ -943,8 +861,18 @@
return max_value, min_value
- def get_chart(self, session, stats, samples, duration, max_value, min_value,
append):
+ def get_vals(self, session, samples, stat, text):
+ tnow = time()
time_period = self.page.duration.get(session)
+ vals = [{"x":int(time_period -(tnow - secs(dt))),
+ "y":value,
+ "uid": dt.strftime("%m%d%Y%H%M%S"),
+ "tip": "<br>%s: #val#<br>Time: %s" % (text,
dt.strftime("%m/%d/%Y %H:%M:%S"))}
+ for dt, value, dev in reversed(samples[stat])
+ if value is not None]
+ return vals
+
+ def get_chart(self, session, stats, samples, duration, max_value, min_value,
append):
mode = self.page.mode.get(session)
width = self.page.container_width.get(session)
@@ -959,12 +887,11 @@
chart = Chart()
chart.bg_colour = "#FFFFFF"
chart.elements = list()
- tnow = time()
- for stat, color in zip(stats, self.colors):
+ for stat, color in reversed(zip(stats, self.colors)):
line = Element()
line.type = "area"
line.fill = color
- line.fill_alpha = 0.3
+ line.fill_alpha = self.alpha
line.on_show.type = "No"
line.dot_style = {"type": "solid-dot",
@@ -974,18 +901,12 @@
line.width = line_width
line.text = mode == "rate" and "%s / sec" % stat.title or
stat.title
- vals = [{"x":int(time_period -(tnow - secs(dt))),
- "y":value,
- "uid": dt.strftime("%m%d%Y%H%M%S"),
- "tip": "<br>%s: #val#<br>Time: %s" %
(line.text, dt.strftime("%m/%d/%Y %H:%M:%S"))}
- for dt, value, dev in reversed(samples[stat])
- if value is not None]
- line.values = vals
+ line.values = self.get_vals(session, samples, stat, line.text)
chart.elements.append(line)
if append:
chart.append = self.get_elapsed(session)['value']
- #print "append: time_period=%i duration=%i elapsed=%f" %
(time_period, duration, float(self.get_elapsed(session)['value']))
+ #print "append: duration=%i elapsed=%f" % (duration,
float(self.get_elapsed(session)['value']))
return chart
chart.title.text = ""
@@ -1005,6 +926,67 @@
#print "sending entire sample set with y_axis.max=%i" %
chart.y_axis["max"]
return chart
+class StackedAreaChart(AreaChart):
+ def __init__(self, app, name, page):
+ super(StackedAreaChart, self).__init__(app, name, page)
+
+ self.points = self.Points(app, "points")
+ self.add_attribute(self.points)
+
+ self.alpha = 1
+
+ def get_max_min(self, session, stats, samples):
+ max_value = 0
+ min_value = 0
+ points = dict()
+ totals = dict()
+ collapsed = dict()
+
+ for stat in stats:
+ last_dt = None
+ for dt, value, dev in samples[stat]:
+ if dt == last_dt:
+ continue
+ last_dt = dt
+ if stat not in points:
+ points[stat] = list()
+ if dt not in totals:
+ totals[dt] = 0
+ totals[dt] += value
+ points[stat].append((dt, value, totals[dt]))
+
+ max_value = max(totals[dt], max_value)
+ min_value = min(totals[dt], min_value)
+
+ # save the accumulated values for each timestamp
+ self.points.set(session, points)
+
+ max_value = round(max_value * 1.1 + 1)
+ if min_value < 0:
+ min_value = round(min_value * 1.1 - 1)
+
+ return max_value, min_value
+
+ def get_vals(self, session, samples, stat, text):
+ tnow = time()
+ time_period = self.page.duration.get(session)
+ points = self.points.get(session)
+ vals = list()
+
+ if points:
+ vals = [{"x":int(time_period -(tnow - secs(dt))),
+ "y":stacked_value,
+ "uid": dt.strftime("%m%d%Y%H%M%S"),
+ "tip": "<br>%s: %s<br>Time: %s" % (text,
str(value), dt.strftime("%m/%d/%Y %H:%M:%S"))}
+ for dt, value, stacked_value in reversed(points[stat])
+ if value is not None]
+
+ return vals
+
+ class Points(Attribute):
+ def get_default(self, session):
+ return dict()
+
class StatFlashPage(StatChartPage):
def __init__(self, app, name):
super(StatFlashPage, self).__init__(app, name)
@@ -1043,7 +1025,8 @@
if chart_type == "area":
chart_obj = AreaChart(self.app, chart_type, self)
elif chart_type == "stacked":
- chart_obj = StackedChart(self.app, chart_type, self)
+ chart_obj = StackedAreaChart(self.app, chart_type, self)
+ #chart_obj = StackedChart(self.app, chart_type, self)
return chart_obj