03a9b5050c27153f5018f2fcaf66976409b2cade
[dygraphs.git] / tests / drawing.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <link rel="stylesheet" href="../css/dygraph.css">
5 <title>Dygraphs Drawing Demo</title>
6 <!--
7 For production (minified) code, use:
8 <script type="text/javascript" src="dygraph-combined.js"></script>
9 -->
10 <script type="text/javascript" src="../dist/dygraph.js"></script>
11
12 <script>
13 var start_date = new Date("2002/12/29").getTime();
14 var end_date = new Date().getTime();
15 data = [];
16 for (var d = start_date; d < end_date; d += 604800 * 1000) {
17 var millis = d + 2 * 3600 * 1000;
18 var date = new Date(millis);
19 var yyyy = date.getFullYear(),
20 mm = date.getMonth(),
21 dd = date.getDate();
22 data.push( [ new Date(Date.UTC(yyyy, mm, dd)), 50 ]);
23 }
24 </script>
25
26 <style>
27 #tool_zoom {
28 background: url('drawing/tool-palette.png');
29 background-position: 0px 0px;
30 width: 32px;
31 height: 33px;
32 margin-left: 50px;
33 display: inline-block;
34 }
35 #tool_pencil {
36 background: url('drawing/tool-palette.png');
37 background-position: -32px 0px;
38 width: 32px;
39 height: 33px;
40 display: inline-block;
41 }
42 #tool_eraser {
43 background: url('drawing/tool-palette.png');
44 background-position: -64px 0px;
45 width: 33px;
46 height: 33px;
47 display: inline-block;
48 }
49 #toolbar {
50 display: inline-block;
51 }
52 </style>
53 </head>
54 <body>
55 <h2>Time Series Drawing Demo</h2>
56 <div id='toolbar'>
57 <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>
58 </div>
59 <div id="draw_div" style="width: 800px; height: 400px;"></div>
60
61 <script type="text/javascript">
62 var isDrawing = false;
63 var lastDrawRow = null, lastDrawValue = null;
64 var tool = 'pencil';
65 var valueRange = [0, 100];
66
67 function setPoint(event, g, context) {
68 var pos = Dygraph.findPos(g.graphDiv);
69 var canvasx = Dygraph.pageX(event) - pos.x;
70 var canvasy = Dygraph.pageY(event) - pos.y;
71 var xy = g.toDataCoords(canvasx, canvasy);
72 var x = xy[0], value = xy[1];
73 var rows = g.numRows();
74 var closest_row = -1;
75 var smallest_diff = -1;
76 // TODO(danvk): binary search
77 for (var row = 0; row < rows; row++) {
78 var date = g.getValue(row, 0); // millis
79 var diff = Math.abs(date - x);
80 if (smallest_diff < 0 || diff < smallest_diff) {
81 smallest_diff = diff;
82 closest_row = row;
83 }
84 }
85
86 if (closest_row != -1) {
87 if (lastDrawRow === null) {
88 lastDrawRow = closest_row;
89 lastDrawValue = value;
90 }
91 var coeff = (value - lastDrawValue) / (closest_row - lastDrawRow);
92 if (closest_row == lastDrawRow) coeff = 0.0;
93 var minRow = Math.min(lastDrawRow, closest_row);
94 var maxRow = Math.max(lastDrawRow, closest_row);
95 for (var row = minRow; row <= maxRow; row++) {
96 if (tool == 'pencil') {
97 var val = lastDrawValue + coeff * (row - lastDrawRow);
98 val = Math.max(valueRange[0], Math.min(val, valueRange[1]));
99 data[row][1] = val;
100 if (val == null || isNaN(val)) console.log(val);
101 } else if (tool == 'eraser') {
102 data[row][1] = null;
103 }
104 }
105 lastDrawRow = closest_row;
106 lastDrawValue = value;
107 g.updateOptions({ file: data });
108 g.setSelection(closest_row); // prevents the dot from being finnicky.
109 }
110 }
111
112 function finishDraw() {
113 isDrawing = false;
114 lastDrawRow = null;
115 lastDrawValue = null;
116 }
117
118 function change_tool(tool_div) {
119 var ids = ['tool_zoom', 'tool_pencil', 'tool_eraser'];
120 for (var i = 0; i < ids.length; i++) {
121 var div = document.getElementById(ids[i]);
122 if (div == tool_div) {
123 div.style.backgroundPosition = -(i * 32) + 'px -32px';
124 } else {
125 div.style.backgroundPosition = -(i * 32) + 'px 0px';
126 }
127 }
128 tool = tool_div.id.replace('tool_', '');
129
130 var dg_div = document.getElementById("draw_div");
131 if (tool == 'pencil') {
132 dg_div.style.cursor = 'url(drawing/cursor-pencil.png) 2 30, auto';
133 } else if (tool == 'eraser') {
134 dg_div.style.cursor = 'url(drawing/cursor-eraser.png) 10 30, auto';
135 } else if (tool == 'zoom') {
136 dg_div.style.cursor = 'crosshair';
137 }
138 }
139 change_tool(document.getElementById("tool_pencil"));
140
141 g = new Dygraph(document.getElementById("draw_div"), data,
142 {
143 valueRange: valueRange,
144 labels: [ 'Date', 'Value' ],
145 labelsUTC: true,
146 interactionModel: {
147 mousedown: function (event, g, context) {
148 if (tool == 'zoom') {
149 Dygraph.defaultInteractionModel.mousedown(event, g, context);
150 } else {
151 event.preventDefault(); // Firefox, Chrome, etc.
152 isDrawing = true;
153 setPoint(event, g, context);
154 }
155 },
156 mousemove: function (event, g, context) {
157 if (tool == 'zoom') {
158 } else {
159 if (!isDrawing) return;
160 setPoint(event, g, context);
161 }
162 },
163 mouseup: function(event, g, context) {
164 if (tool == 'zoom') {
165 } else {
166 finishDraw();
167 }
168 },
169 mouseout: function(event, g, context) {
170 if (tool == 'zoom') {
171 }
172 },
173 dblclick: function(event, g, context) {
174 Dygraph.defaultInteractionModel.dblclick(event, g, context);
175 },
176 mousewheel: function(event, g, context) {
177 var normal = event.detail ? event.detail * -1 : event.wheelDelta / 40;
178 var percentage = normal / 50;
179 var axis = g.xAxisRange();
180 var xOffset = g.toDomCoords(axis[0], null)[0];
181 var x = event.offsetX - xOffset;
182 var w = g.toDomCoords(axis[1], null)[0] - xOffset;
183 var xPct = w == 0 ? 0 : (x / w);
184
185 var delta = axis[1] - axis[0];
186 var increment = delta * percentage;
187 var foo = [increment * xPct, increment * (1 - xPct)];
188 var dateWindow = [ axis[0] + foo[0], axis[1] - foo[1] ];
189
190 g.updateOptions({
191 dateWindow: dateWindow
192 });
193 event.preventDefault();
194 }
195 },
196 strokeWidth: 1.5,
197 gridLineColor: 'rgb(196, 196, 196)',
198 axes: {
199 y: {
200 drawAxis: false,
201 drawGrid: false
202 }
203 }
204 });
205 window.onmouseup = finishDraw;
206 </script>
207
208 <p style='font-size: 10pt'>Toolbar/cursor icons are CC-licensed from <a
209 href="http://www.fatcow.com/free-icons">FatCow</a>.</p>
210 </body>
211 </html>