source: Dev/trunk/RGraph/libraries/RGraph.common.annotate.js @ 77

Last change on this file since 77 was 77, checked in by fpvanagthoven, 14 years ago

RGraph

File size: 12.9 KB
Line 
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
18    /**
19    * The function which controls the annotate feature
20    *
21    * @param object obj The graph object
22    */
23    RGraph.Annotate = function (obj)
24    {
25        /**
26        * This installs some event handlers
27        */
28        if (obj.Get('chart.annotatable')) {
29
30            var canvas  = obj.canvas;
31            var context = obj.context;
32           
33            /**
34            * Capture the mouse events so we can set whther the mouse is down or not
35            */
36            var canvas_onmousedown = function (e)
37            {
38                if (e.button == 0) {
39
40                    e.target.__object__.Set('chart.mousedown', true);
41
42                    // Get the context
43                    var obj = e.target.__object__;
44                    var context = obj.context;
45
46                    // Don't want any "joining" lines or colour "bleeding"
47                    context.beginPath();
48
49                    // Accommodate Chrome
50                    var coords = RGraph.getMouseXY(e);
51                    var x      = coords[0];
52                    var y      = coords[1];
53                   
54                    // Clear the annotation recording
55                    RGraph.Registry.Set('annotate.actions', [obj.Get('chart.annotate.color')]);
56
57                    context.strokeStyle = obj.Get('chart.annotate.color');
58
59                    context.moveTo(x, y);
60               
61                    // Set the lineWidth
62                    context.lineWidth = 1;
63                   
64                    RGraph.Registry.Set('started.annotating', false);
65                    RGraph.Registry.Set('chart.annotating', obj);
66                   
67                    /**
68                    * Fire the onannotatebegin event. It also fires an event called ononnotatestart for BC purposes
69                    */
70                    RGraph.FireCustomEvent(obj, 'onannotatestart');
71                    RGraph.FireCustomEvent(obj, 'onannotatebegin');
72                }
73               
74                return false;
75            }
76            canvas.addEventListener('mousedown', canvas_onmousedown, false);
77            RGraph.AddEventListener(canvas.id, 'mousedown', canvas_onmousedown);
78           
79            /**
80            * This cancels annotating for ALL canvases
81            */
82            var window_onmouseup = function (e)
83            {
84                var obj  = RGraph.Registry.Get('chart.annotating');
85                var tags = document.getElementsByTagName('canvas');
86
87                for (var i=0; i<tags.length; ++i) {
88                    if (tags[i].__object__) {
89                        tags[i].__object__.Set('chart.mousedown', false);
90                    }
91                }
92
93                if (e.button != 0 || !obj) {
94                    return;
95                }
96
97                // Store the annotations in browser storage if it's available
98                if (RGraph.Registry.Get('annotate.actions') && RGraph.Registry.Get('annotate.actions').length > 0 && window.localStorage) {
99
100                    var id = '__rgraph_annotations_' + e.target.id + '__';
101                    var annotations  = window.localStorage[id] ? window.localStorage[id] + '|' : '';
102                        annotations += RGraph.Registry.Get('annotate.actions');
103
104                    // Store the annotations information in HTML5 browser storage here
105                    window.localStorage[id] = annotations;
106                }
107               
108                // Clear the recorded annotations
109                RGraph.Registry.Set('annotate.actions', []);
110               
111                /**
112                * Fire the annotate event
113                */
114
115                RGraph.FireCustomEvent(obj, 'onannotateend');
116            }
117            window.addEventListener('mouseup', window_onmouseup, false);
118            RGraph.AddEventListener(canvas.id, 'window_mouseup', window_onmouseup);
119           
120            /**
121            * Canvas onmouseup event
122            */
123            var canvas_onmouseup = function (e)
124            {
125                var obj = e.target.__object__;
126               
127                RGraph.Registry.Set('chart.mousedown', false);
128            }
129            canvas.addEventListener('mouseup', canvas_onmouseup, false);
130            RGraph.AddEventListener(canvas.id, 'mouseup', canvas_onmouseup);
131
132            /**
133            * The canvas onmousemove function
134            */
135            var canvas_onmousemove = function (e)
136            {
137                var e      = RGraph.FixEventObject(e);
138                var obj    = e.target.__object__;
139                var coords = RGraph.getMouseXY(e);
140                var x      = coords[0];
141                var y      = coords[1];
142                var width  = canvas.width;
143                var height = canvas.height;
144
145                obj.context.lineWidth = 1;
146
147                // Don't allow annotating in the gutter
148                //
149                // CHANGED 20TH DECEMBER 2010 TO ALLOW ANNOTATING IN THE GUTTER
150                if (true) {
151               
152                    canvas.style.cursor = 'crosshair';
153               
154                    if (obj.Get('chart.mousedown')) {
155                           
156                       // Special case for HBars and Gantts with their extra wide left gutter
157                       if ( (obj.type != 'hbar' && obj.type != 'gantt') || x > obj.gutterLeft) {
158
159                           /**
160                           * This is here to stop annotating in the gutter
161                           */
162                            if (RGraph.Registry.Get('started.annotating') == false) {
163                                context.moveTo(x, y);
164                                RGraph.Registry.Set('started.annotating', true)
165                            }
166
167                            context.lineTo(x, y);
168
169                            RGraph.Registry.Set('annotate.actions', RGraph.Registry.Get('annotate.actions') + '|' + x + ',' + y);
170
171                            context.stroke();
172
173                            /**
174                            * Fire the annotate event
175                            */
176                            RGraph.FireCustomEvent(obj, 'onannotate');
177                        }
178                    }
179
180                } else {
181                    canvas.style.cursor = 'default';
182                }
183            }
184            canvas.addEventListener('mousemove', canvas_onmousemove, false);
185            RGraph.AddEventListener(canvas.id, 'mousemove', canvas_onmousemove);
186
187            RGraph.ReplayAnnotations(obj);
188        }
189    }
190
191
192    /**
193    * Shows the mini palette used for annotations
194    *
195    * @param object e The event object
196    */
197    RGraph.Showpalette = function (e)
198    {
199        var isSafari = navigator.userAgent.indexOf('Safari') ? true : false;
200
201        e = RGraph.FixEventObject(e);
202
203        var canvas  = e.target.parentNode.__canvas__;
204        var context = canvas.getContext('2d');
205        var obj     = canvas.__object__;
206        var div     = document.createElement('DIV');
207        var coords  = RGraph.getMouseXY(e);
208       
209        div.__object__               = obj; // The graph object
210        div.className                = 'RGraph_palette';
211        div.style.position           = 'absolute';
212        div.style.backgroundColor    = 'white';
213        div.style.border             = '1px solid black';
214        div.style.left               = 0;
215        div.style.top                = 0;
216        div.style.padding            = '3px';
217        div.style.paddingBottom      = 0;
218        div.style.paddingRight       = 0;
219        div.style.opacity            = 0;
220        div.style.boxShadow          = 'rgba(96,96,96,0.5) 3px 3px 3px';
221        div.style.WebkitBoxShadow    = 'rgba(96,96,96,0.5) 3px 3px 3px';
222        div.style.MozBoxShadow       = 'rgba(96,96,96,0.5) 3px 3px 3px';
223        div.style.filter             = 'progid:DXImageTransform.Microsoft.Shadow(color=#666666,direction=135)';
224       
225        var common_css       = 'padding: 1px; display: inline; display: inline-block; width: 15px; height: 15px; margin-right: 3px; cursor: pointer;' + (isSafari ? 'margin-bottom: 3px' : '');
226        var common_mouseover = ' onmouseover="this.style.border = \'1px black solid\'; this.style.padding = 0"';
227        var common_mouseout  = ' onmouseout="this.style.border = 0; this.style.padding = \'1px\'" ';
228
229        var str = '';
230
231        var colors = ['red', 'blue', 'green', 'black', 'yellow', 'magenta', 'pink', 'cyan', 'purple', '#ddf', 'gray', '#36905c'];
232
233        for (i=0; i<colors.length; ++i) {
234            str = str + '<span ' + common_mouseover + common_mouseout + ' style="background-color: ' + colors[i] + '; ' + common_css  + '" onclick="this.parentNode.__object__.Set(\'chart.annotate.color\', this.style.backgroundColor); this.parentNode.style.display = \'none\'; RGraph.FireCustomEvent(this.parentNode.__object__, \'onannotatecolor\')">&nbsp;</span>';
235           
236            // This makes the colours go across two levels
237            if (i == 5) {
238                str += '<br />';
239            }
240        }
241
242        div.innerHTML = str;
243        document.body.appendChild(div);
244       
245        /**
246        * Now the div has been added to the document, move it up and left and set the width and height
247        */
248        div.style.width  = (div.offsetWidth) + 'px';
249        div.style.height = (div.offsetHeight - (RGraph.isIE9up() ? 5 : 5)) + 'px';
250        div.style.left   = Math.max(0, e.pageX - div.offsetWidth - 2) + 'px';
251        div.style.top    = (e.pageY - div.offsetHeight - 2) + 'px';
252
253        /**
254        * Store the palette div in the registry
255        */
256        RGraph.Registry.Set('palette', div);
257       
258        setTimeout("RGraph.Registry.Get('palette').style.opacity = 0.2", 50);
259        setTimeout("RGraph.Registry.Get('palette').style.opacity = 0.4", 100);
260        setTimeout("RGraph.Registry.Get('palette').style.opacity = 0.6", 150);
261        setTimeout("RGraph.Registry.Get('palette').style.opacity = 0.8", 200);
262        setTimeout("RGraph.Registry.Get('palette').style.opacity = 1", 250);
263
264        RGraph.HideContext();
265
266        window.onclick = function ()
267        {
268            RGraph.HidePalette();
269        }
270
271        // Should this be here? Yes. This function is being used as an event handler.
272        e.stopPropagation();
273        return false;
274    }
275   
276   
277    /**
278    * Clears any annotation data from global storage
279    *
280    * @param string id The ID of the canvas
281    */
282    RGraph.ClearAnnotations = function (id)
283    {
284        var canvas = document.getElementById(id);
285        var obj    = canvas.__object__;
286
287        if (window.localStorage && window.localStorage['__rgraph_annotations_' + id + '__'] && window.localStorage['__rgraph_annotations_' + id + '__'].length) {
288            window.localStorage['__rgraph_annotations_' + id + '__'] = [];
289           
290            RGraph.FireCustomEvent(obj, 'onannotateclear');
291        }
292    }
293
294
295    /**
296    * Replays stored annotations
297    *
298    * @param object obj The graph object
299    */
300    RGraph.ReplayAnnotations = function (obj)
301    {
302        // Check for support
303        if (!window.localStorage) {
304            return;
305        }
306
307        var context     = obj.context;
308        var annotations = window.localStorage['__rgraph_annotations_' + obj.id + '__'];
309        var i, len, move, coords;
310
311        context.beginPath();
312        context.lineWidth = 2;
313
314        if (annotations && annotations.length) {
315            annotations = annotations.split('|');
316        } else {
317            return;
318        }
319
320        for (i=0, len=annotations.length; i<len; ++i) {
321            if (!annotations[i].match(/^[0-9]+,[0-9]+$/)) {
322                context.stroke();
323                context.beginPath();
324                context.strokeStyle = annotations[i];
325                move = true;
326                continue;
327            }
328           
329            coords = annotations[i].split(',');
330
331            if (move) {
332                context.moveTo(coords[0], coords[1]);
333                move = false;
334            } else {
335                context.lineTo(coords[0], coords[1]);
336            }
337        }
338       
339        context.stroke();
340    }
Note: See TracBrowser for help on using the repository browser.