Commits

Ralph Bean  committed 780ecd1

streamgraph rules

  • Participants
  • Parent commits a68314b

Comments (0)

Files changed (2)

File tw2/protovis/conventional/samples.py

 The demos implemented here are what is displayed in the tw2.devtools
 WidgetBrowser.
 """
-from widgets import AreaChart, BarChart
+from widgets import AreaChart, BarChart, StreamGraph
+from widgets import js
 from tw2.core import JSSymbol
 
 import math
 
 class DemoBarChart(BarChart):
     p_data = [random.random() for i in range(10)]
+
+# The following are some data generation functions used by the streamgraph demo
+def waves(n, m):
+    def f(i, j):
+        x = 20 * j / m - i / 3
+        if x > 0:
+            return 2 * x * math.exp(x * -0.5)
+        return 0
+    return map(lambda i : map(lambda j : f(i, j), range(m)), range(n))
+
+def layers(n, m):
+    def bump(a):
+        x = 1.0 / (.1 + random.random())
+        y = 2.0 * random.random() - 0.5
+        z = 10.0 / (0.1 + random.random())
+        for i in range(m):
+            w = (float(i) / m - y) * z
+            a[i] += x * math.exp(-w * w)
+        return a
+    def f(*args):
+        a = [0] * m
+        for i in range(5):
+            a = bump(a)
+        return a
+    return map(f, range(n))
+
+
+class DemoStreamGraph(StreamGraph):
+    def prepare(self):
+        self.p_data = layers(20, 400)
+        super(DemoStreamGraph, self).prepare()

File tw2/protovis/conventional/widgets.py

             .strokeStyle("#000")\
           .anchor("bottom").add(pv.Label)\
             .text(js('x.tickFormat'))
+
+class StreamGraph(twp.PVWidget):
+    def prepare(self):
+        self.init_js = js(
+            """
+            var n = 20, m = 400;
+            var data = %s,
+                w = %i,
+                h = %i,
+                x = pv.Scale.linear(0, m - 1).range(0, w),
+                y = pv.Scale.linear(0, 2 * n).range(0, h);
+            """ % (self.p_data, self.p_width, self.p_height))
+
+        # Set up the root panel
+        self.init().width(self.p_width).height(self.p_height) \
+                .bottom(self.p_bottom).top(self.p_top) \
+                .left(self.p_left).right(self.p_right)
+
+        self.add(pv.Layout.Stack)\
+                .layers(js('data'))\
+                .order('inside-out')\
+                .offset('wiggle')\
+                .x(js('x.by(pv.index)'))\
+                .y(js('y'))\
+              .layer.add(pv.Area)\
+                .fillStyle(js('pv.ramp("#aad", "#556").by(Math.random)'))\
+                .strokeStyle(js('function() this.fillStyle().alpha(0.5)'))