drawing demo
authorDan Vanderkam <dan@dygraphs.com>
Sun, 24 Apr 2011 22:26:35 +0000 (18:26 -0400)
committerDan Vanderkam <dan@dygraphs.com>
Sun, 24 Apr 2011 22:26:35 +0000 (18:26 -0400)
tests/drawing.html [new file with mode: 0644]
tests/drawing/cursor-eraser.png [new file with mode: 0755]
tests/drawing/cursor-pencil.png [new file with mode: 0755]
tests/drawing/tool-palette.png [new file with mode: 0644]

diff --git a/tests/drawing.html b/tests/drawing.html
new file mode 100644 (file)
index 0000000..e873b74
--- /dev/null
@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
+    <title>Dygraphs Drawing Demo</title>
+    <!--[if IE]>
+    <script type="text/javascript" src="../excanvas.js"></script>
+    <![endif]-->
+    <script type="text/javascript" src="../strftime/strftime-min.js"></script>
+    <script type="text/javascript" src="../rgbcolor/rgbcolor.js"></script>
+    <script type="text/javascript" src="../dygraph-canvas.js"></script>
+    <script type="text/javascript" src="../dygraph.js"></script>
+
+    <script type="text/javascript">
+    var start_date = new Date("2002/12/29").getTime();
+    var end_date = new Date().getTime();
+    data = [];
+    for (var d = start_date; d < end_date; d += 604800 * 1000) {
+      var millis = d + 2 * 3600 * 1000;
+      data.push( [ new Date(new Date(millis).strftime("%Y/%m/%d")), 50 ]);
+    }
+    </script>
+    <style type="text/css">
+    #tool_zoom {
+      background: url('drawing/tool-palette.png');
+      background-position-x: 0px;
+      width: 32px;
+      height: 33px;
+      margin-left: 50px;
+      display: inline-block;
+    }
+    #tool_pencil {
+      background: url('drawing/tool-palette.png');
+      background-position-x: -32px;
+      width: 32px;
+      height: 33px;
+      display: inline-block;
+    }
+    #tool_eraser {
+      background: url('drawing/tool-palette.png');
+      background-position-x: -64px;
+      width: 33px;
+      height: 33px;
+      display: inline-block;
+    }
+    #toolbar {
+      display: inline-block;
+    }
+    </style>
+</head>
+<body>
+  <h2>Time Series Drawing Demo</h2>
+  <div id='toolbar'>
+    <div id="tool_zoom" onClick='change_tool(this)'></div><div id="tool_pencil" onClick='change_tool(this)'></div><div id="tool_eraser" onClick='change_tool(this)'></div>
+  </div>
+  <div id="draw_div" style="width: 800px; height: 400px;"></div>
+
+  <script type="text/javascript">
+    var isDrawing = false;
+    var lastDrawRow = null, lastDrawValue = null;
+    var tool = 'pencil';
+    var valueRange = [0, 100];
+
+    function setPoint(event, g, context) {
+      var canvasx = Dygraph.pageX(event) - Dygraph.findPosX(g.graphDiv);
+      var canvasy = Dygraph.pageY(event) - Dygraph.findPosY(g.graphDiv);
+      var xy = g.toDataCoords(canvasx, canvasy);
+      var x = xy[0], value = xy[1];
+      var rows = g.numRows();
+      var closest_row = -1;
+      var smallest_diff = -1;
+      // TODO(danvk): binary search
+      for (var row = 0; row < rows; row++) {
+        var date = g.getValue(row, 0);  // millis
+        var diff = Math.abs(date - x);
+        if (smallest_diff < 0 || diff < smallest_diff) {
+          smallest_diff = diff;
+          closest_row = row;
+        }
+      }
+
+      if (closest_row != -1) {
+        if (lastDrawRow === null) {
+          lastDrawRow = closest_row;
+          lastDrawValue = value;
+        }
+        var coeff = (value - lastDrawValue) / (closest_row - lastDrawRow);
+        if (closest_row == lastDrawRow) coeff = 0.0;
+        var minRow = Math.min(lastDrawRow, closest_row);
+        var maxRow = Math.max(lastDrawRow, closest_row);
+        for (var row = minRow; row <= maxRow; row++) {
+          if (tool == 'pencil') {
+            var val = lastDrawValue + coeff * (row - lastDrawRow);
+            val = Math.max(valueRange[0], Math.min(val, valueRange[1]));
+            data[row][1] = val;
+            if (val == null || isNaN(val)) console.log(val);
+          } else if (tool == 'eraser') {
+            data[row][1] = null;
+          }
+        }
+        lastDrawRow = closest_row;
+        lastDrawValue = value;
+        g.updateOptions({ file: data });
+        g.setSelection(closest_row);  // prevents the dot from being finnicky.
+      }
+    }
+
+    function finishDraw() {
+      isDrawing = false;
+      lastDrawRow = null;
+      lastDrawValue = null;
+    }
+
+    function change_tool(tool_div) {
+      var ids = ['tool_pencil', 'tool_zoom', 'tool_eraser'];
+      for (var i = 0; i < ids.length; i++) {
+        document.getElementById(ids[i]).style.backgroundPositionY = 0;
+      }
+      tool_div.style.backgroundPositionY = '-32px';
+      tool = tool_div.id.replace('tool_', '');
+
+      var dg_div = document.getElementById("draw_div");
+      if (tool == 'pencil') {
+        dg_div.style.cursor = 'url(drawing/cursor-pencil.png) 2 30, auto';
+      } else if (tool == 'eraser') {
+        dg_div.style.cursor = 'url(drawing/cursor-eraser.png) 10 30, auto';
+      } else if (tool == 'zoom') {
+        dg_div.style.cursor = 'crosshair';
+      }
+    }
+    change_tool(document.getElementById("tool_pencil"));
+
+    g = new Dygraph(document.getElementById("draw_div"), data,
+        {
+          valueRange: valueRange,
+          labels: [ 'Date', 'Value' ],
+          interactionModel: {
+            mousedown: function (event, g, context) {
+              if (tool == 'zoom') {
+                Dygraph.defaultInteractionModel.mousedown(event, g, context);
+              } else {
+                // prevents mouse drags from selecting page text.
+                if (event.preventDefault) {
+                  event.preventDefault();  // Firefox, Chrome, etc.
+                } else {
+                  event.returnValue = false;  // IE
+                  event.cancelBubble = true;
+                }
+                isDrawing = true;
+                setPoint(event, g, context);
+              }
+            },
+            mousemove: function (event, g, context) {
+              if (tool == 'zoom') {
+                Dygraph.defaultInteractionModel.mousemove(event, g, context);
+              } else {
+                if (!isDrawing) return;
+                setPoint(event, g, context);
+              }
+            },
+            mouseup: function(event, g, context) {
+              if (tool == 'zoom') {
+                Dygraph.defaultInteractionModel.mouseup(event, g, context);
+              } else {
+                finishDraw();
+              }
+            },
+            mouseout: function(event, g, context) {
+              if (tool == 'zoom') {
+                Dygraph.defaultInteractionModel.mouseout(event, g, context);
+              }
+            },
+            dblclick: function(event, g, context) {
+              Dygraph.defaultInteractionModel.dblclick(event, g, context);
+            },
+            mousewheel: function(event, g, context) {
+              var normal = event.detail ? event.detail * -1 : event.wheelDelta / 40;
+              var percentage = normal / 50;
+              var axis = g.xAxisRange();
+              var xOffset = g.toDomCoords(axis[0], null)[0];
+              var x = event.offsetX - xOffset;
+              var w = g.toDomCoords(axis[1], null)[0] - xOffset;
+              var xPct = w == 0 ? 0 : (x / w);
+
+              var delta = axis[1] - axis[0];
+              var increment = delta * percentage;
+              var foo = [increment * xPct, increment * (1 - xPct)];
+              var dateWindow = [ axis[0] + foo[0], axis[1] - foo[1] ];
+
+              g.updateOptions({
+                dateWindow: dateWindow
+              });
+              Dygraph.cancelEvent(event);
+            }
+          },
+          strokeWidth: 1.5,
+          gridLineColor: 'rgb(196, 196, 196)',
+          drawYGrid: false,
+          drawYAxis: false
+        });
+        window.onmouseup = finishDraw;
+  </script>
+
+  <p style='font-size: 10pt'>Toolbar/cursor icons are CC-licensed from <a
+  href="http://www.fatcow.com/free-icons">FatCow</a>.</p>
+</body>
+</html>
diff --git a/tests/drawing/cursor-eraser.png b/tests/drawing/cursor-eraser.png
new file mode 100755 (executable)
index 0000000..bcef6b9
Binary files /dev/null and b/tests/drawing/cursor-eraser.png differ
diff --git a/tests/drawing/cursor-pencil.png b/tests/drawing/cursor-pencil.png
new file mode 100755 (executable)
index 0000000..0ee281c
Binary files /dev/null and b/tests/drawing/cursor-pencil.png differ
diff --git a/tests/drawing/tool-palette.png b/tests/drawing/tool-palette.png
new file mode 100644 (file)
index 0000000..a340045
Binary files /dev/null and b/tests/drawing/tool-palette.png differ