[rhmessaging-commits] rhmessaging commits: r3269 - mgmt/trunk/cumin/python/cumin.

rhmessaging-commits at lists.jboss.org rhmessaging-commits at lists.jboss.org
Wed Apr 8 14:33:07 EDT 2009


Author: eallen
Date: 2009-04-08 14:33:07 -0400 (Wed, 08 Apr 2009)
New Revision: 3269

Modified:
   mgmt/trunk/cumin/python/cumin/charts.py
   mgmt/trunk/cumin/python/cumin/collector.py
   mgmt/trunk/cumin/python/cumin/collector.strings
   mgmt/trunk/cumin/python/cumin/stat.py
   mgmt/trunk/cumin/python/cumin/stat.strings
Log:
Stacked value charts

Modified: mgmt/trunk/cumin/python/cumin/charts.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/charts.py	2009-04-08 18:32:22 UTC (rev 3268)
+++ mgmt/trunk/cumin/python/cumin/charts.py	2009-04-08 18:33:07 UTC (rev 3269)
@@ -258,3 +258,62 @@
 
     def write(self, writer):
         self.surface.write_to_png(writer)
+
+class StackedValueChart(TimeSeriesChart):
+    def __init__(self, width, height, legend_height = 0):
+        super(StackedValueChart, self).__init__(width, height)
+
+        if legend_height:
+            self.surface = ImageSurface(FORMAT_ARGB32, width, height + legend_height)
+            self.surface.set_device_offset(1.5, 5.5)
+
+        self.legend_height = legend_height
+        self.bar_width = 2
+
+    def plot_values(self, dt, samples, colors):
+        cr = Context(self.surface)
+        cr.set_line_width(self.bar_width)
+
+        tnow = time()
+        y = self.height
+        v = 0
+        for value, color in zip(samples, colors):
+            if value is None:
+                continue
+
+            t = secs(dt)
+
+            if tnow - t < 0:
+                t = tnow
+
+            x = self.width - ((tnow - t) / float(self.x_max)) * self.width
+            cr.move_to(x, y)
+            cr.set_source_rgba(color[0], color[1], color[2], 0.66)
+
+            v = v + value
+            y = self.height - (v / float(self.y_max)) * self.height
+            cr.line_to(x, y)
+            cr.stroke()
+
+    def plot_legend(self, titles, colors):
+        cr = Context(self.surface)
+
+        for i, item in enumerate(zip(titles, colors)):
+            title, color = item
+            y = self.height + 16 + i * 16
+
+            cr.set_source_rgba(1, 1, 1, 0.75)
+            cr.rectangle(4, y - 12, 16 + 6.5 * len(title), 16)
+            cr.fill()
+            cr.stroke()
+
+            cr.set_source_rgb(*color)
+            cr.rectangle(8, y, 8, -8)
+            cr.fill()
+            cr.stroke()
+
+            cr.move_to(20, y)
+            cr.set_source_rgb(0, 0, 0)
+            cr.show_text(title)
+            cr.stroke()
+

Modified: mgmt/trunk/cumin/python/cumin/collector.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/collector.py	2009-04-08 18:32:22 UTC (rev 3268)
+++ mgmt/trunk/cumin/python/cumin/collector.py	2009-04-08 18:33:07 UTC (rev 3269)
@@ -108,6 +108,23 @@
         self.add_mode(view)
         self.set_view_mode(view)
 
+class CollectorStats(Widget):
+    def __init__(self, app, name):
+        super(CollectorStats, self).__init__(app, name)
+
+        self.add_child(StatSet(app, "stats", "general"))
+
+        chart = self.StackedChart(app, "utilization")
+        chart.stats = ("HostsIdle", "HostsClaimed", "HostsUnclaimed")
+        self.add_child(chart)
+
+    def render_title(self, session):
+        return "Statistics"
+
+    class StackedChart(StatStackedChart):
+        def render_title(self, session, *args):
+            return "Slot Utilization"
+
 class CollectorView(CuminView):
     def __init__(self, app, name):
         super(CollectorView, self).__init__(app, name)
@@ -118,6 +135,9 @@
         self.__tabs = TabbedModeSet(app, "tabs")
         self.add_child(self.__tabs)
 
+        stats = CollectorStats(app, "stats")
+        self.__tabs.add_tab(stats)
+
         details = CuminDetails(app, "details")
         self.__tabs.add_tab(details)
 

Modified: mgmt/trunk/cumin/python/cumin/collector.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/collector.strings	2009-04-08 18:32:22 UTC (rev 3268)
+++ mgmt/trunk/cumin/python/cumin/collector.strings	2009-04-08 18:33:07 UTC (rev 3269)
@@ -38,3 +38,18 @@
 
   <div>{hidden_inputs}</div>
 </form>
+
+[CollectorStats.html]
+<table class="twocol">
+  <tbody>
+    <tr>
+      <td>
+        <h2>Collector Stats</h2>
+        {stats}
+      </td>
+      <td>
+    {utilization}
+      </td>
+    </tr>
+  </tbody>
+</table>

Modified: mgmt/trunk/cumin/python/cumin/stat.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/stat.py	2009-04-08 18:32:22 UTC (rev 3268)
+++ mgmt/trunk/cumin/python/cumin/stat.py	2009-04-08 18:33:07 UTC (rev 3269)
@@ -73,7 +73,14 @@
         #else:
 
         return stat.rate_html(object)
+class DurationSwitch(StateSwitch):
+    def __init__(self, app, name):
+        super(DurationSwitch, self).__init__(app, name)
 
+        self.add_state("m", "10 minutes")
+        self.add_state("h", "1 hour")
+        self.add_state("d", "1 day")
+
 class StatValueChart(Widget):
     def __init__(self, app, name):
         super(StatValueChart, self).__init__(app, name)
@@ -112,8 +119,11 @@
         if self.mode:
             params.append("mode=%s" % self.mode)
 
-        return "stats.png?" + ";".join(params)
+        return "%s?" % self.get_chart_name(session) + ";".join(params)
 
+    def get_chart_name(self, session):
+        return "stats.png"
+
     def render_title(self, session, object):
         cls = self.app.model.get_class_by_object(object)
         return getattr(cls, self.stats[0]).title
@@ -145,6 +155,40 @@
     def render_stat_name(self, session, stat, object):
         return stat.name
 
+    def render_width(self, session, object):
+        return 360
+
+    def render_height(self, session, object):
+        return 100
+
+class StatStackedChart(StatValueChart):
+    def __init__(self, app, name):
+        super(StatStackedChart, self).__init__(app, name)
+
+        self.duration = self.JSDurationSwitch(app, "duration")
+        self.add_child(self.duration)
+
+    def get_chart_name(self, session):
+        return "stacked.png"
+
+    def render_height(self, session, object):
+        return 200
+
+    class JSDurationSwitch(DurationSwitch):
+        def render_item_link(self, session, state):
+            href = "javascript:void(0)"
+
+            title = self.get_title(state)
+            hover = self.get_hover(state)
+            class_ = self.get(session) == state and "selected"
+            duration = 600
+            if state == "h":
+                duration = 3600
+            elif state == "d":
+                duration = 86400
+            click = "stackedDuration('%s', this, %i)" % (state, duration)
+            return fmt_link(href, title, class_, link_title=hover, click=click)
+
 class ImageCache(object):
     def __init__(self):
         self.__files = dict() # {name: {"time": time_created, "file": file object, "cookie": (cookie values)}}
@@ -409,10 +453,102 @@
         chart.write(writer)
         return writer.to_string()
 
-class DurationSwitch(StateSwitch):
+from random import *
+class StatStackedPage(StatChartPage):
     def __init__(self, app, name):
-        super(DurationSwitch, self).__init__(app, name)
+        super(StatStackedPage, self).__init__(app, name)
 
-        self.add_state("m", "10 minutes")
-        self.add_state("h", "1 hour")
-        self.add_state("d", "1 day")
+        self.container_width = IntegerParameter(app, "width")
+        self.container_width.default = 360
+        self.add_parameter(self.container_width)
+
+        self.container_height = IntegerParameter(app, "height")
+        self.container_height.default = 100
+        self.add_parameter(self.container_height)
+
+    def fake_samples(self, count, t, diff):
+        start = randrange(1, 100)
+
+        return [ (t+timedelta(seconds=-i*diff), start + randrange(-5, 5)) for i in range(0, count) ]
+
+    def do_render(self, session, object):
+        chart = StackedValueChart(self.container_width.get(session), self.container_height.get(session), 100)
+
+        cls = self.class_.get(session)
+        stats = [getattr(cls, x) for x in self.stats.get(session)]
+
+        samples = dict()
+        values = dict()
+
+        duration = self.duration.get(session)
+
+        #XXX fake stats for now
+        count = self.container_width.get(session) / 3
+        t = datetime.now()
+        seed(1)
+        for stat in stats:
+            samples[stat] = self.fake_samples(min(count, 200), t, 10)
+
+            #samples[stat] = stat.samples(object, duration)
+
+        points = dict()
+        for stat in stats:
+            for sample in samples[stat]:
+                t = sample[0]
+                if not t in points:
+                    points[t] = list()
+                points[t].append(sample[1])
+
+        for t in points:
+            values[t] = 0
+            for v in points[t]:
+                values[t] = values[t] + v
+
+        max_value = 1
+        min_value = 0
+
+        for t in points:
+            vals = values[t]
+            if vals:
+                max_value = max(nvl(vals, 0), max_value)
+                min_value = min(nvl(vals, 0), min_value)
+
+        max_value = round(max_value * 1.1 + 1)
+
+        if min_value < 0:
+            min_value = round(min_value * 1.1 - 1)
+
+        chart.x_max = duration
+        chart.x_min = 0
+        chart.y_max = max_value
+        chart.y_min = min_value
+
+        x_intervals = 8
+        x_step = 2
+
+        if chart.x_max == 600:
+            x_intervals = 10
+
+        y_intervals = 6
+        y_step = 2
+
+        if chart.y_max < 3:
+            y_step = 3
+
+        chart.plot_x_axis(x_intervals, x_step)
+        chart.plot_y_axis(y_intervals, y_step)
+
+        colors = ((1,0,0), (0,0,1), (0,1,0), (1,0,1), (1,1,0), (0,1,1), (0,0,0))
+
+        for t in points:
+            chart.plot_values(t, points[t], colors)
+
+        chart.plot_frame()
+
+        titles = [x.title for x in stats]
+
+        chart.plot_legend(reversed(titles), reversed(colors[:len(titles)]))
+
+        writer = Writer()
+        chart.write(writer)
+        return writer.to_string()

Modified: mgmt/trunk/cumin/python/cumin/stat.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/stat.strings	2009-04-08 18:32:22 UTC (rev 3268)
+++ mgmt/trunk/cumin/python/cumin/stat.strings	2009-04-08 18:33:07 UTC (rev 3269)
@@ -78,7 +78,7 @@
 
   <div class="duration">{duration}</div>
 
-  <img id="{id}" src="{href}" height="100" width="360" alt="stats" />
+  <img id="{id}" src="{href}" height="{height}" width="{width}" alt="stats" />
 </div>
 <script type="text/javascript">
 (function() {
@@ -95,3 +95,58 @@
   <span class="swatch" style="background-color: {stat_color}">&nbsp;</span>
   &nbsp; <span class="ph" statname="{stat_name}" statmode="{mode}">{stat_value}</span>
 </li>
+
+[StatStackedChart.html]
+<div class="StatValueChart fullpageable" id="{id}">
+  <h2>{title}</h2>
+
+  <div class="duration">{duration}</div>
+
+  <img id="{id}" src="{href}" alt="Stacked Value Chart" />
+</div>
+<script type="text/javascript">
+//<![CDATA[
+(function() {
+    function update() {
+        cumin.updateChart("{id}");
+    }
+
+    wooly.addPageUpdateListener(update);
+}())
+function stackedNotify(full, width, height) {
+    var oImg = document.images['{id}'];
+    if (oImg) {
+        var src = oImg.src;
+        var branch = wooly.session.branch(src);
+        branch.width = Math.max(width - 100, 360);
+        branch.height = Math.max(height - 100, 100);
+        src = branch.marshal();
+
+        src = cumin.refreshTime(src);
+        oImg.style.visibility = "hidden"
+        oImg.src = src;
+    }
+}
+function stackedDuration(state, a, duration) {
+    li = a.parentNode;
+    ul = li.parentNode;
+    as = ul.getElementsByTagName('a');
+    for (var i=0; i < as.length; i++) {
+        as[i].className = (as[i].firstChild.nodeValue.indexOf(state) != -1) ?  "selected" : "";
+    }
+    var oImg = document.images['{id}'];
+    if (oImg) {
+        var src = oImg.src;
+        var branch = wooly.session.branch(src);
+        branch.duration = duration;
+        src = branch.marshal();
+        src = cumin.refreshTime(src);
+        oImg.src = src;
+    }
+}
+    $('{id}').onfullpage = function (width, height) { stackedNotify(true, width, height); };
+    $('{id}').onrestore = function () { stackedNotify(false, {width}, 100); };
+    document.images['{id}'].onload = function () {this.style.visibility = "visible"};
+    document.images['{id}'].ondblclick = function () {fullpage(this.parentNode.parentNode.parentNode.getElementsByTagName('p')[0])};
+//]]>
+</script>




More information about the rhmessaging-commits mailing list