initial commit
[home-automation.git] / libraries / RGraph.common.adjusting.js
1     /**
2     * o------------------------------------------------------------------------------o
3     * | This file is part of the RGraph package - you can learn more at:             |
4     * |                                                                              |
5     * |                          http://www.rgraph.net                               |
6     * |                                                                              |
7     * | This package is licensed under the RGraph license. For all kinds of business |
8     * | purposes there is a small one-time licensing fee to pay and for non          |
9     * | commercial  purposes it is free to use. You can read the full license here:  |
10     * |                                                                              |
11     * |                      http://www.rgraph.net/LICENSE.txt                       |
12     * o------------------------------------------------------------------------------o
13     */
14
15     if (typeof(RGraph) == 'undefined') RGraph = {isRGraph:true,type:'common'};
16
17     RGraph.AllowAdjusting = function (obj)
18     {
19         var canvas  = obj.canvas;
20         var context = obj.context;
21         
22         RGraph.Register(obj);
23             
24         if (obj.type == 'line') {
25             canvas.onmousedown = function (e)
26             {
27                 e = RGraph.FixEventObject(e);
28     
29                 var obj         = e.target.__object__;
30                 var id          = obj.id;
31                 var canvas      = obj.canvas;
32                 var context     = obj.context;
33                 var coords      = obj.coords;
34                 var mouseCoords = RGraph.getMouseXY(e);
35     
36                 RGraph.Redraw();
37     
38                 for (var i=0; i<coords.length; ++i) {
39     
40                     if (   mouseCoords[0] > coords[i][0] - 5
41                         && mouseCoords[1] > coords[i][1] - 5
42                         && mouseCoords[0] < coords[i][0] + 5
43                         && mouseCoords[1] < coords[i][1] + 5
44                        ) {
45
46                         var numDataSeries = obj.original_data.length;
47                         var numDataPoints = obj.original_data[0].length;
48                         var data_series   = i / numDataPoints;
49                             data_series = Math.floor(data_series);
50     
51     
52     
53                       canvas.style.cursor = 'ns-resize';
54                       RGraph.Registry.Set('chart.adjusting.line.' + id, [obj, i, [coords[i][0], coords[i][1]], data_series]);
55     
56                       return;
57                     }
58                 }
59             }
60     
61     
62             canvas.onmousemove = function (e)
63             {
64                 e = RGraph.FixEventObject(e);
65                 var id = e.target.__object__.id;
66     
67                 var state = RGraph.Registry.Get('chart.adjusting.line.' + id);
68     
69                 if (state) {
70                     var obj         = state[0];
71                     var idx         = state[1];
72                     var canvas      = obj.canvas;
73                     var context     = obj.context;
74                     var data_series = state[3];
75                     var points      = obj.original_data[data_series];
76                     var mouseCoords = RGraph.getMouseXY(e);
77                     var x           = mouseCoords[0];
78                     var y           = mouseCoords[1];
79     
80                     if (y >= (obj.canvas.height - obj.Get('chart.gutter'))) {
81                         y = obj.canvas.height - obj.Get('chart.gutter');
82                     } else if (y <= obj.Get('chart.gutter')) {
83                         y = obj.Get('chart.gutter');
84                     }
85     
86                     var pos   = obj.canvas.height - (2 * obj.Get('chart.gutter'));
87                         pos   = pos - (y - obj.Get('chart.gutter'));
88                     var value = (obj.max / (obj.canvas.height - (2 * obj.Get('chart.gutter')))) * pos;
89     
90                     // Adjust the index so that it's applicable to the correct data series
91                     for (var i=0; i<data_series; ++i) {
92                         idx -= obj.original_data[0].length;
93                     }
94     
95                     obj.original_data[data_series][idx] = value;
96     
97                     obj.Set('chart.ymax', obj.max);
98                     canvas.style.cursor = 'ns-resize';
99                     RGraph.Redraw();
100
101                     /**
102                     * Fire the onadjust event
103                     */
104                     RGraph.FireCustomEvent(obj, 'onadjust');
105     
106                     return;
107     
108                 } else {
109                     
110                     var canvas  = e.target;
111                     var context = canvas.__object__.context;
112                     var obj     = canvas.__object__;
113                     var mouseCoords = RGraph.getMouseXY(e);
114                     var x       = mouseCoords[0];
115                     var y       = mouseCoords[1];
116     
117                     for (var i=0; i<obj.coords.length; ++i) {
118     
119                         if (   x > obj.coords[i][0] - 5
120                             && y > obj.coords[i][1] - 5
121                             && x < obj.coords[i][0] + 5
122                             && y < obj.coords[i][1] + 5
123                            ) {
124     
125                            canvas.style.cursor = 'ns-resize';
126                            return;
127                         }
128                     }
129                 }
130                 
131                 e.target.style.cursor = null;
132             }
133     
134     
135             canvas.onmouseup = function (e)
136             {
137                 var id = e.target.__object__.id;
138
139                 RGraph.Registry.Set('chart.adjusting.line.' + id, null);
140                 e.target.style.cursor = null;
141             }
142     
143     
144             canvas.onmouseout = function (e)
145             {
146                 canvas.onmouseup(e);
147             }
148         
149         /**
150         * Progress bar
151         */
152         } else if (obj.type == 'hprogress') {
153
154             
155             canvas.onmousedown = function (e)
156             {
157                 var id = e.target.__object__.id;
158
159                 RGraph.Registry.Set('chart.adjusting.progress.' + id, [true]);
160                 
161                 canvas.onmousemove(e);
162             }
163
164
165             canvas.onmousemove = function (e)
166             {
167                 var id    = e.target.__object__.id;
168                 var state = RGraph.Registry.Get('chart.adjusting.progress.' + id);
169
170                 if (state && state.length) {
171                     var obj     = e.target.__object__;
172                     var canvas  = obj.canvas;
173                     var context = obj.context;
174                     
175                     if (obj.type == 'hprogress') {
176                     
177                         var coords = RGraph.getMouseXY(e);
178                             coords[0] = Math.max(0, coords[0] - obj.Get('chart.gutter'));
179                         var barWidth  = canvas.width - (2 * obj.Get('chart.gutter'));
180                         
181                         // Work out the new value
182                         var value  = (coords[0] / barWidth) * (obj.max - obj.Get('chart.min'));
183                             value += obj.Get('chart.min');
184                         
185                         obj.value = Math.max(0, value.toFixed());
186                         RGraph.Clear(obj.canvas);
187                         obj.Draw();
188
189                     } else if (obj.type == 'vprogress') {
190
191                         var coords = RGraph.getMouseXY(e);
192                             coords[1] = Math.max(0, coords[1] - obj.Get('chart.gutter'));
193                         var barHeight = canvas.height - (2 * obj.Get('chart.gutter'));
194                         
195                         // Work out the new value
196                         var value = ( (barHeight - coords[1]) / barHeight) * obj.max;
197                         
198                         obj.value = Math.max(0, value.toFixed());
199                         RGraph.Clear(obj.canvas);
200                         obj.Draw();
201                     }
202
203                     /**
204                     * Fire the onadjust event
205                     */
206                     RGraph.FireCustomEvent(obj, 'onadjust');
207                 }
208             }
209             
210             
211             canvas.onmouseup = function (e)
212             {
213                 var id = e.target.__object__.id;
214                 RGraph.Registry.Set('chart.adjusting.progress.' + id, null);
215             }
216     
217     
218             canvas.onmouseout = function (e)
219             {
220                 canvas.onmouseup(e);
221             }
222         
223         /**
224         * Rose chart
225         */
226         } else if (obj.type == 'rose') {
227
228
229             obj.Set('chart.ymax', obj.max);
230
231
232             canvas.onmousemove = function (e)
233             {
234                 var obj     = e.target.__object__;
235                 var id      = obj.id;
236                 var canvas  = obj.canvas;
237                 var context = obj.context;
238                 var coords  = RGraph.getMouseXY(e);
239                 var segment = RGraph.Registry.Get('chart.adjusting.rose.' + id);
240                 var x       = Math.abs(coords[0] - obj.centerx);
241                 var y       = Math.abs(coords[1] - obj.centery);
242                 var theta   = Math.atan(y / x) * (180 / Math.PI); // theta is now in DEGREES
243
244
245                 // Account for the correct quadrant
246                 if (coords[0] >= obj.centerx && coords[1] < obj.centery) {
247                     theta = 90 - theta;
248                 } else if (coords[0] >= obj.centerx && coords[1] >= obj.centery) {
249                     theta += 90;
250                 } else if (coords[0] < obj.centerx && coords[1] >= obj.centery) {
251                     theta = 90 - theta;
252                     theta = 180 + theta;
253                     
254                 } else if (coords[0] < obj.centerx && coords[1] < obj.centery) {
255                     theta = theta + 270;
256                 }
257
258                 var Opp = y;
259                 var Adj = x;
260                 var Hyp = Math.abs(Adj / Math.sin(theta / (180 / Math.PI)));
261
262                 for (var i=0; i<obj.angles.length; ++i) {
263                     if (
264                            theta > obj.angles[i][0]
265                         && theta < obj.angles[i][1] ) {
266
267                         if (RGraph.Registry.Get('chart.adjusting.rose.' + id) && i == segment[5]) {
268                             var newvalue  = (Hyp / (obj.radius - 25) ) * obj.max;
269                             obj.data[i]   = Math.min(newvalue, obj.max);
270
271                             RGraph.Clear(obj.canvas);
272                             obj.Draw();
273
274                             /**
275                             * Fire the onadjust event
276                             */
277                             RGraph.FireCustomEvent(obj, 'onadjust');
278                         }
279                         
280                         if (Hyp <= (obj.angles[i][2] + 5) && Hyp >= (obj.angles[i][2] - 5) ) {
281                             canvas.style.cursor = 'move';
282                             return;
283                         
284                         } else if (obj.Get('chart.tooltips') && Hyp <= (obj.angles[i][2] - 5) ) {
285                             canvas.style.cursor = 'pointer';
286                             return;
287                         }
288
289                     }
290                 }
291
292                 canvas.style.cursor = 'default';
293             }
294
295
296             canvas.onmousedown = function (e)
297             {
298                 var obj     = e.target.__object__;
299                 var id      = obj.id;
300                 var canvas  = obj.canvas;
301                 var context = obj.context;
302                 var coords  = RGraph.getMouseXY(e);
303                 var segment = RGraph.getSegment(e, 5);
304
305                 if (segment && segment.length && !RGraph.Registry.Get('chart.adjusting.rose.' + id)) {
306                     var x = Math.abs(coords[0] - obj.centerx);
307                     var y = Math.abs(coords[1] - obj.centery);
308
309                     var a = Math.atan(y / x) * (180 / Math.PI); // a is now in DEGREES
310
311                     // Account for the correct quadrant
312                     if (coords[0] >= obj.centerx && coords[1] < obj.centery) {
313                         a  = 90 - a;
314                         a += 270;
315                     } else if (coords[0] >= obj.centerx && coords[1] >= obj.centery) {
316                         // Nada
317                     } else if (coords[0] < obj.centerx && coords[1] >= obj.centery) {
318                          a  = 90 - a;
319                          a += 90;
320                     } else if (coords[0] < obj.centerx && coords[1] < obj.centery) {
321                         a += 180;
322                     }
323
324                     var hyp = Math.abs(y / Math.sin(a / 57.3));
325
326                     if (hyp >= (segment[2] - 10) ) {
327
328                         /**
329                         * Hide any currently shown tooltip
330                         */
331                         if (RGraph.Registry.Get('chart.tooltip')) {
332                             RGraph.Registry.Get('chart.tooltip').style.display = 'none';
333                             RGraph.Registry.Set('chart.tooltip', null);
334                         }
335                         
336                         RGraph.Registry.Set('chart.adjusting.rose.' + id, segment);
337                         
338                         e.stopPropagation();
339                     }
340                 }
341             }
342
343
344             canvas.onmouseup = function (e)
345             {
346                 var obj = e.target.__object__;
347                 var id  = obj.id;
348
349                 if (RGraph.Registry.Get('chart.adjusting.rose.' + id)) {
350
351                     RGraph.Registry.Set('chart.adjusting.rose.' + id, null);
352                     e.stopPropagation();
353                     
354                     return false;
355                 }
356             }
357     
358     
359             canvas.onmouseout = function (e)
360             {
361                 canvas.onmouseup(e);
362             }
363
364         /**
365         * Bar chart
366         */
367         } else if (obj.type == 'bar') {
368         
369             // Stacked bar charts not supported
370             if (obj.Get('chart.grouping') == 'stacked') {
371                 alert('[BAR] Adjusting stacked bar charts is not supported');
372                 return;
373             }
374
375
376             var canvas  = obj.canvas;
377             var context = obj.context;
378
379
380             canvas.onmousemove = function (e)
381             {
382                 var obj     = e.target.__object__;
383                 var id      = obj.id;
384                 var canvas  = obj.canvas;
385                 var context = obj.context;
386                 var mouse   = RGraph.getMouseXY(e);
387                 var mousex  = mouse[0];
388                 var mousey  = mouse[1]; // mousey, mousey...
389
390                 // Loop through the coords to see if the mouse position is at the top of a bar
391                 for (var i=0; i<obj.coords.length; ++i) {
392                     if (mousex > obj.coords[i][0] && mousex < (obj.coords[i][0] + obj.coords[i][2])) {
393                         
394                         // Change the mouse pointer
395                         if (mousey > (obj.coords[i][1] - 5) && mousey < (obj.coords[i][1] + 5)) {
396                             canvas.style.cursor = 'ns-resize';
397                         } else {
398                             canvas.style.cursor = 'default';
399                         }
400
401                         var idx = RGraph.Registry.Get('chart.adjusting.bar.' + id)
402                         
403                         if (typeof(idx) == 'number') {
404                             var newheight = obj.grapharea - (mousey - obj.Get('chart.gutter'));
405                             var newvalue  = (newheight / obj.grapharea) * obj.max;
406                             
407                             // Top and bottom boundaries
408                             if (newvalue > obj.max) newvalue = obj.max;
409                             if (newvalue < 0)       newvalue = 0;
410
411                             ///////////////// This was fun to work out... /////////////////
412                             for (var j=0, index=0; j<obj.data.length; ++j,++index) {
413                                 if (typeof(obj.data[j]) == 'object') {
414                                     for (var k=0; k<obj.data[j].length && index <= idx; ++k, ++index) {
415                                         if (index == idx) {
416                                             obj.data[j][k] = newvalue;
417                                             var b = true;
418                                             break;
419                                         }
420                                     }
421                                     
422                                     --index;
423                                 } else if (typeof(obj.data[j]) == 'number') {
424                             
425                                     if (index == idx) {
426                                         obj.data[j] = newvalue;
427                                         // No need to set b
428                                         break;
429                                     }
430                                 }
431                                 
432                                 if (b) {
433                                     break;
434                                 }
435                             }
436                             ///////////////////////////////////////////////////////////////
437
438                             RGraph.Clear(canvas);
439                             obj.Draw();
440
441                             /**
442                             * Fire the onadjust event
443                             */
444                             RGraph.FireCustomEvent(obj, 'onadjust');
445                         }
446
447                         return;
448                     }
449                 }
450                 
451                 canvas.style.cursor = 'default';
452             }
453
454
455
456             canvas.onmousedown = function (e)
457             {
458                 var obj     = e.target.__object__;
459                 var id      = obj.id;
460                 var canvas  = obj.canvas;
461                 var context = obj.context;
462                 var mouse   = RGraph.getMouseXY(e);
463                 var mousex  = mouse[0];
464                 var mousey  = mouse[1]; // mousey, mousey...
465
466                 // Loop through the coords to see if the mouse position is at the top of a bar
467                 for (var i=0; i<obj.coords.length; ++i) {
468                     if (
469                            mousex > obj.coords[i][0] && mousex < (obj.coords[i][0] + obj.coords[i][2])
470                         
471                        ) {
472
473                         obj.Set('chart.ymax', obj.max);
474                         RGraph.Registry.Set('chart.adjusting.bar.' + id, i);
475                         canvas.onmousemove(e);
476                     }
477                 }
478             }
479
480
481
482             canvas.onmouseup = function (e)
483             {
484                 var id = e.target.__object__.id;
485                 
486                 RGraph.Registry.Set('chart.adjusting.bar.' + id, null);
487             }
488
489
490             canvas.onmouseout = function (e)
491             {
492                 canvas.onmouseup(e);
493             }
494
495
496         /**
497         * The Tradar chart
498         */
499         } else if (obj.type == 'tradar') {
500
501
502             var canvas = obj.canvas;
503             var context = obj.context;
504             
505             
506             canvas.onmousemove = function (e)
507             {
508                 var obj         = e.target.__object__;
509                 var id          = obj.id;
510                 var canvas      = obj.canvas;
511                 var context     = obj.context;
512                 var mouseDown   = RGraph.Registry.Get('chart.adjusting.tradar.' + id);
513                 var mouseCoords = RGraph.getMouseXY(e);
514
515
516                 if (mouseDown) {
517
518                     canvas.style.cursor = 'move';
519
520                     var dx  = mouseCoords[0] - obj.centerx;
521                     var dy  = mouseCoords[1] - obj.centery;
522                     var hyp = Math.sqrt((dx * dx) + (dy * dy));
523
524                     var newvalue = (hyp / (obj.size / 2)) * obj.max;
525                     
526                     newvalue = Math.min(obj.max, newvalue);
527                     newvalue = Math.max(0, newvalue);
528
529                     /**
530                     * Only redraw the graph if the mouse is in the same quadrant as the point
531                     */
532                     if ( (dx >= 0 ? true : false) == mouseDown[1] && (dy >= 0 ? true : false) == mouseDown[2]) {
533                         obj.data[mouseDown[0]] = newvalue;
534                         RGraph.Clear(canvas);
535                         obj.Draw();
536
537                         /**
538                         * Fire the onadjust event
539                         */
540                         RGraph.FireCustomEvent(obj, 'onadjust');
541                     }
542
543
544                 } else {
545
546                     // Determine if the mouse is near a point, and if so, change the pointer
547                     for (var i=0; i<obj.coords.length; ++i) {
548                         
549                         var dx = Math.abs(mouseCoords[0] - obj.coords[i][0]);
550                         var dy = Math.abs(mouseCoords[1] - obj.coords[i][1]);
551                         var a  = Math.atan(dy / dx);
552     
553                         
554                         var hyp = Math.sqrt((dx * dx) + (dy * dy));
555     
556                         if (hyp <= 5) {
557                             canvas.style.cursor = 'move';
558                             return;
559                         }
560                     }
561
562                     canvas.style.cursor = 'default';
563                 }
564             }
565             
566             
567             canvas.onmousedown = function (e)
568             {
569                 e = RGraph.FixEventObject(e);
570                 
571                 var obj         = e.target.__object__;
572                 var id          = obj.id;
573                 var canvas      = obj.canvas;
574                 var context     = obj.context;
575                 var mouseCoords = RGraph.getMouseXY(e);
576
577
578                 // Determine if the mouse is near a point
579                 for (var i=0; i<obj.coords.length; ++i) {
580                     
581                     var dx = Math.abs(mouseCoords[0] - obj.coords[i][0]);
582                     var dy = Math.abs(mouseCoords[1] - obj.coords[i][1]);
583                     var a  = Math.atan(dy / dx);
584
585                     
586                     var hyp = Math.sqrt((dx * dx) + (dy * dy));
587
588                     if (hyp <= 5) {
589                         canvas.style.cursor = 'pointer';
590                         RGraph.Registry.Set('chart.adjusting.tradar.' + id, [i, obj.coords[i][0] > obj.centerx, obj.coords[i][1] > obj.centery]);
591                         return;
592                     }
593                 }
594                     
595                 canvas.style.cursor = 'default';
596             }
597
598
599             canvas.onmouseup = function (e)
600             {
601                 RGraph.Registry.Set('chart.adjusting.tradar.' + e.target.id, null);
602                 canvas.style.cursor = 'default';
603             }
604     
605     
606             canvas.onmouseout = function (e)
607             {
608                 canvas.onmouseup(e);
609             }
610         }
611     }
612
613
614     /**
615     * Returns 1 or -1 depening on whether the given number is positive or negative.
616     * Zero is considered positive.
617     * 
618     * @param  int num The number
619     * @return int     1 if the number is positive or zero, -1 if it's negative
620     */
621     //RGraph.getSign = function (num)
622     //{
623     //    return num >= 0 ? 1 : -1;
624     //}