Commits

lf...@lfac-VAIO.zai  committed 4a79924

Made changes relative to flotzai.

  • Participants
  • Parent commits 6ed271c

Comments (0)

Files changed (2)

File src/jqplot.core.js

  * 
  */
 
+/* Plugin for jQuery for working with colors.
+ * 
+ * Version 1.1.
+ * 
+ * Inspiration from jQuery color animation plugin by John Resig.
+ *
+ * Released under the MIT license by Ole Laursen, October 2009.
+ *
+ * Examples:
+ *
+ *   $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
+ *   var c = $.color.extract($("#mydiv"), 'background-color');
+ *   console.log(c.r, c.g, c.b, c.a);
+ *   $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
+ *
+ * Note that .scale() and .add() return the same modified object
+ * instead of making a new one.
+ *
+ * V. 1.1: Fix error handling so e.g. parsing an empty string does
+ * produce a color rather than just crashing.
+ */ 
+(function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]+=I}return G.normalize()};G.scale=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]*=I}return G.normalize()};G.toString=function(){if(G.a>=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return K<J?J:(K>I?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);
+
 (function($) {
     // make sure undefined is undefined
     var undefined;
             return canvas;
         };
 
-        this.freeAllCanvases = function() {
+        this.freeAllCanvases = function(dontFreeEventCanvas) {
+            if(dontFreeEventCanvas){
+                var ec_idx = -1;
             for (var i = 0, l=myCanvases.length; i < l; i++) {
+                    if($($.jqplot.CanvasManager.canvases[myCanvases[i]]).attr('class')!="jqplot-event-canvas"){
                 this.freeCanvas(myCanvases[i]);
             }
+                    else{
+                        ec_idx = myCanvases[i];
+                    }
+                }
+                myCanvases = ec_idx >= 0 ? [ec_idx] : [];
+            }
+            else{
+                for (var i = 0, l=myCanvases.length; i < l; i++) {
+                    this.freeCanvas(myCanvases[i]);
+                }
             myCanvases = [];
+            }
         };
 
         this.freeCanvas = function(idx) {
-            if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
+            if ($.jqplot.use_excanvas) {
                 // excanvas can't be reused, but properly unset
                 window.G_vmlCanvasManager.uninitElement($.jqplot.CanvasManager.canvases[idx]);
                 $.jqplot.CanvasManager.canvases[idx] = null;
         if (this.min != null || this.max != null) {
             this.autoscale = false;
         }
+        // direction
+        this.direction = this.name.indexOf('y') > -1 ? 'y' : 'x';
         // if not set, sync ticks for y axes but not x by default.
         if (this.syncTicks == null && this.name.indexOf('y') > -1) {
             this.syncTicks = true;
     };
     
     Axis.prototype.resetScale = function(opts) {
+        if (this.append && this.append === true) {
+            $.extend(true, this, {min: null, max: null}, opts);
+        } else {
         $.extend(true, this, {min: null, max: null, numberTicks: null, tickInterval: null, _ticks: [], ticks: []}, opts);
+        }
         this.resetDataBounds();
     };
     
                 maxyidx = 2;
             }
             
-            for (var j=0, l=d.length; j<l; j++) { 
+            for (var j=0; j<d.length; j++) { 
                 if (this.name == 'xaxis' || this.name == 'x2axis') {
                     if ((d[j][0] != null && d[j][0] < db.min) || db.min == null) {
                         db.min = d[j][0];
         }
         
         for (j=0; j<$.jqplot.postDrawSeriesHooks.length; j++) {
-            $.jqplot.postDrawSeriesHooks[j].call(this, sctx, options, plot);
+            $.jqplot.postDrawSeriesHooks[j].call(this, sctx, options);
         }
         
         sctx = opts = plot = j = data = gridData = null;
                 if (axis.borderWidth == null) {
                     axis.borderWidth =this.grid.borderWidth;
                 }
+                if (axis.borderColor == null) {
+                    if (n != 'xaxis' && n != 'x2axis' && axis.useSeriesColor === true && axis.show) {
+                        axis.borderColor = axis._series[0].color;
+                    }
+                    else {
+                        axis.borderColor = this.grid.borderColor;
+                    }
+                }
             }
             
             if (typeof this.options.title == 'string') {
             if (clear) {
                 this.destroy();
             }
+            else{
+                this.canvasManager.freeAllCanvases(true);
+                this.target.unbind();
+                this.target.find("[class!=jqplot-event-canvas]").remove();
+            }
+            
             this.reInitialize();
             if (resetAxes) {
                 this.resetAxesScale(resetAxes, opts.axes);
                 }
                 // Need to use filled canvas to capture events in IE.
                 // Also, canvas seems to block selection of other elements in document on FF.
+                var must_do_event_canvas_binding = false;
+                if(!this.eventCanvas._elem || this.eventCanvas._elem.attr('class') != 'jqplot-event-canvas'){
+                    this._gridPadding.left = 50;
                 this.target.append(this.eventCanvas.createElement(this._gridPadding, 'jqplot-event-canvas', null, this));
                 this.eventCanvas.setContext();
                 this.eventCanvas._ctx.fillStyle = 'rgba(0,0,0,0)';
                 this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width, this.eventCanvas._ctx.canvas.height);
+                    this.eventCanvas._elem.css('z-index', 20);
+                    must_do_event_canvas_binding = true;
+                }
             
                 // bind custom event handlers to regular events.
-                this.bindCustomEvents();
+                if(must_do_event_canvas_binding){
+                    this.bindCustomEvents();
+                }
             
                 // draw legend before series if the series needs to know the legend dimensions.
                 if (this.legend.preDraw) {  
                     this.legend.pack(legendPadding);                
                 }
             
-                // register event listeners on the overlay canvas
-                for (var i=0, l=$.jqplot.eventListenerHooks.length; i<l; i++) {
-                    // in the handler, this will refer to the eventCanvas dom element.
-                    // make sure there are references back into plot objects.
-                    this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]);
-                }
+                if(must_do_event_canvas_binding){
+                    // register event listeners on the overlay canvas
+                    for (var i=0, l=$.jqplot.eventListenerHooks.length; i<l; i++) {
+                        // in the handler, this will refer to the eventCanvas dom element.
+                        // make sure there are references back into plot objects.
+                        this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]);
+                    }
             
-                // register event listeners on the overlay canvas
-                for (var i=0, l=this.eventListenerHooks.hooks.length; i<l; i++) {
-                    // in the handler, this will refer to the eventCanvas dom element.
-                    // make sure there are references back into plot objects.
-                    this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[i][0], {plot:this}, this.eventListenerHooks.hooks[i][1]);
+                    // register event listeners on the overlay canvas
+                    for (var i=0, l=this.eventListenerHooks.hooks.length; i<l; i++) {
+                        // in the handler, this will refer to the eventCanvas dom element.
+                        // make sure there are references back into plot objects.
+                        this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[i][0], {plot:this}, this.eventListenerHooks.hooks[i][1]);
+                    }
                 }
 
                 var fb = this.fillBetween;
             this.eventCanvas._elem.bind('mousemove', {plot:this}, this.onMouseMove);
             this.eventCanvas._elem.bind('mouseenter', {plot:this}, this.onMouseEnter);
             this.eventCanvas._elem.bind('mouseleave', {plot:this}, this.onMouseLeave);
+            this.eventCanvas._elem.bind('mousewheel', {plot:this}, this.onMouseWheel);
+            this.eventCanvas._elem.bind('dragstart', {plot:this}, this.onDragStart);
+            this.eventCanvas._elem.bind('drag', {plot:this}, this.onDrag);
+            this.eventCanvas._elem.bind('dragend', {plot:this}, this.onDragEnd);
             if (this.captureRightClick) {
                 this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onRightClick);
                 this.eventCanvas._elem.get(0).oncontextmenu = function() {
             return null;
         }
         
+        this.onDragStart = function(ev) {
+            // Event passed in is normalized and will have data attribute.
+            // Event passed out is unnormalized.
+            var positions = getEventPosition(ev);
+            var p = ev.data.plot;
+            var neighbor = checkIntersection(positions.gridPos, p);
+            var evt = jQuery.Event('jqplotDragStart');
+            evt.pageX = ev.pageX;
+            evt.pageY = ev.pageY;
+            $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]);            
+        }
         
+        this.onDrag = function(ev) {
+            // Event passed in is normalized and will have data attribute.
+            // Event passed out is unnormalized.
+            var positions = getEventPosition(ev);
+            var p = ev.data.plot;            
+            var neighbor = checkIntersection(positions.gridPos, p);
+            var evt = jQuery.Event('jqplotDrag');
+            evt.pageX = ev.pageX;
+            evt.pageY = ev.pageY;
+            $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]);            
+        }
+        
+        this.onDragEnd = function(ev) {
+            // Event passed in is normalized and will have data attribute.
+            // Event passed out is unnormalized.
+            var positions = getEventPosition(ev);
+            var p = ev.data.plot;            
+            var neighbor = checkIntersection(positions.gridPos, p);
+            var evt = jQuery.Event('jqplotDragEnd');
+            evt.pageX = ev.pageX;
+            evt.pageY = ev.pageY;
+            $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]);            
+        }
+        
+        this.onMouseWheel = function(ev, delta) {
+            ev.preventDefault();
+            // Event passed in is normalized and will have data attribute.
+            // Event passed out is unnormalized.
+            var positions = getEventPosition(ev);
+            var p = ev.data.plot;
+            var neighbor = checkIntersection(positions.gridPos, p);
+            var evt = jQuery.Event('jqplotMouseWheel');
+            evt.pageX = ev.pageX;
+            evt.pageY = ev.pageY;
+            $(this).trigger(evt, [delta, positions.gridPos, positions.dataPos, neighbor, p]);            
+        };
         
         this.onClick = function(ev) {
             // Event passed in is normalized and will have data attribute.
         yellow: 'rgb(255, 255, 0)',
         yellowgreen: 'rgb(154, 205, 50)'
     };
+    
+         // Finds the point with the x coordinate closest to the given x.
+   $.jqplot.closest = function(x, serie) {
+        function binSearchPoint(array, x, f_, fail_) {
+            var begin = 0,
+                end = array.length,
+                middle,
+                point,
+                f = f_ || function(value) {return value;},
+                fail = fail_ || function(middle) {return -1;};
 
-    
+            while (begin <= end) {
+                middle = Math.ceil((end - begin) / 2 + begin);
+                point = array[middle] ? array[middle][0] : null;
+
+                // Damn, we've hit a null point. Move middle around
+                // until we found a valid point.
+                if (point === null) {
+                    while (middle > begin && point === null) {
+                        middle -= 1;
+                        point = array[middle] ? array[middle][0] : null;
+                    };
+
+                    // If we can't find a point after begin that is not null,
+                    // move forward. Otherwise, there won't be progress.
+                    if (point === null) {
+                        middle = Math.floor((end - begin) / 2 + begin);
+
+                        while (middle < end && point === null) {
+                            middle += 1;
+                            point = array[middle] ? array[middle][0] : null;
+                        }
+                    }
+
+                    if (point === null) {
+                        break;
+                    }
+                }
+
+                if (x < f(point)) {
+                    end = middle - 1;
+                } else if (x > f(point)) {
+                    begin = middle + 1;
+                } else {
+                    return middle;
+                }
+            }
+
+            return fail(middle);
+        }
+        function minBy(array, f) {
+            var min = array[0];
+            for (var i = 1; i < array.length; i++) {
+                if (f(array[i]) < f(min)) {
+                    min = array[i];
+                }
+            }
+
+            return min;
+        }
+        function closestNeighbour(neighbours) {
+            var distance = function(fst, snd) {
+                return Math.abs(fst - snd);
+            };
+
+            return minBy(neighbours, function (elt) {
+                return elt >= 0 && elt < serie.length
+                    ? distance(x, serie[elt][0]) : Number.POSITIVE_INFINITY;
+            });
+        }
+
+        var idx = binSearchPoint(serie, x,
+                                 null,
+                                 function(middle) {
+                                     return closestNeighbour([middle - 1, middle, middle + 1]);
+                                 });
+        return idx;
+    };
+
+
 })(jQuery);

File src/plugins/jqplot.cursor.js

         var c = this.plugins.cursor;
 
         if (c.show) {
-            $.jqplot.eventListenerHooks.push(['jqplotMouseEnter', handleMouseEnter]);
-            $.jqplot.eventListenerHooks.push(['jqplotMouseLeave', handleMouseLeave]);
-            $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMouseMove]);
+            $.jqplot.eventListenerHooks.push(['jqplotMouseEnter', handleMouseEnter, target]);
+            $.jqplot.eventListenerHooks.push(['jqplotMouseLeave', handleMouseLeave, target]);
+            $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMouseMove, target]);
             
             if (c.showCursorLegend) {              
                 opts.legend = opts.legend || {};
             }
             
             if (c.zoom) {
-                $.jqplot.eventListenerHooks.push(['jqplotMouseDown', handleMouseDown]);
+                $.jqplot.eventListenerHooks.push(['jqplotMouseDown', handleMouseDown, target]);
                 
                 if (c.clickReset) {
-                    $.jqplot.eventListenerHooks.push(['jqplotClick', handleClick]);
+                    $.jqplot.eventListenerHooks.push(['jqplotClick', handleClick, target]);
                 }
                 
                 if (c.dblClickReset) {
-                    $.jqplot.eventListenerHooks.push(['jqplotDblClick', handleDblClick]);
+                    $.jqplot.eventListenerHooks.push(['jqplotDblClick', handleDblClick, target]);
                 }             
             }
     
         var min, max, dp, span,
             newmin, newmax, curax, _numberTicks, ret;
         var ctx = plot.plugins.cursor.zoomCanvas._ctx;
+        var selection = { };
         // don't zoom if zoom area is too small (in pixels)
         if ((c.constrainZoomTo == 'none' && Math.abs(gridpos.x - c._zoom.start[0]) > 6 && Math.abs(gridpos.y - c._zoom.start[1]) > 6) || (c.constrainZoomTo == 'x' && Math.abs(gridpos.x - c._zoom.start[0]) > 6) ||  (c.constrainZoomTo == 'y' && Math.abs(gridpos.y - c._zoom.start[1]) > 6)) {
             if (!plot.plugins.cursor.zoomProxy) {
                 for (var ax in datapos) {
+                    
+                    selection[ax] = { };
+                    
+                    if (plot.plugins.zoom && plot.plugins.zoom._zoom.isZoomed == true) {
+                        axes[ax].reset();
+                        axes[ax]._ticks = [];
+                    }
                     // make a copy of the original axes to revert back.
                     if (c._zoom.axes[ax] == undefined) {
                         c._zoom.axes[ax] = {};
                                 axes[ax].min = newmin;
                                 axes[ax].max = newmax;
                                 axes[ax].tickInterval = null;
-                                axes[ax].numberTicks = null;
                                 // for date axes...
                                 axes[ax].daTickInterval = null;
                             }
                         }
                     }
                             
+                    selection[ax].from = axes[ax].min;
+                    selection[ax].to = axes[ax].max;
+                    
+                    if (plot.plugins.zoom && plot.plugins.zoom.hasOverview) {
+                        plot.plugins.zoom.overviewPlot.setSelection(selection);
+                    }
                     // if ((c.constrainZoomTo == 'x' && ax.charAt(0) == 'y' && c.autoscaleConstraint) || (c.constrainZoomTo == 'y' && ax.charAt(0) == 'x' && c.autoscaleConstraint)) {
                     //     dp = datapos[ax];
                     //     if (dp != null) {