source: Dev/branches/jQueryUI/client/RGraph/libraries/RGraph.common.annotate.js @ 249

Last change on this file since 249 was 249, checked in by hendrikvanantwerpen, 13 years ago

This one's for Subversion, because it's so close...

First widget (stripped down sequencer).
Seperated client and server code in two direcotry trees.

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.