Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/Scripts/jqPlot/plugins/jqplot.barRenderer.js @ 9646

Last change on this file since 9646 was 9617, checked in by pfleck, 12 years ago

#2063:
Started integrating Hive statistics into statistics web project.
Added jqPlot library for charting.

File size: 31.8 KB
Line 
1/**
2 * jqPlot
3 * Pure JavaScript plotting plugin using jQuery
4 *
5 * Version: 1.0.0b2_r1012
6 *
7 * Copyright (c) 2009-2011 Chris Leonello
8 * jqPlot is currently available for use in all personal or commercial projects
9 * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
10 * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
11 * choose the license that best suits your project and use it accordingly.
12 *
13 * Although not required, the author would appreciate an email letting him
14 * know of any substantial use of jqPlot.  You can reach the author at:
15 * chris at jqplot dot com or see http://www.jqplot.com/info.php .
16 *
17 * If you are feeling kind and generous, consider supporting the project by
18 * making a donation at: http://www.jqplot.com/donate.php .
19 *
20 * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
21 *
22 *     version 2007.04.27
23 *     author Ash Searle
24 *     http://hexmen.com/blog/2007/03/printf-sprintf/
25 *     http://hexmen.com/js/sprintf.js
26 *     The author (Ash Searle) has placed this code in the public domain:
27 *     "This code is unrestricted: you are free to use it however you like."
28 *
29 */
30(function($) {
31   
32    // Class: $.jqplot.BarRenderer
33    // A plugin renderer for jqPlot to draw a bar plot.
34    // Draws series as a line.
35   
36    $.jqplot.BarRenderer = function(){
37        $.jqplot.LineRenderer.call(this);
38    };
39   
40    $.jqplot.BarRenderer.prototype = new $.jqplot.LineRenderer();
41    $.jqplot.BarRenderer.prototype.constructor = $.jqplot.BarRenderer;
42   
43    // called with scope of series.
44    $.jqplot.BarRenderer.prototype.init = function(options, plot) {
45        // Group: Properties
46        //
47        // prop: barPadding
48        // Number of pixels between adjacent bars at the same axis value.
49        this.barPadding = 8;
50        // prop: barMargin
51        // Number of pixels between groups of bars at adjacent axis values.
52        this.barMargin = 10;
53        // prop: barDirection
54        // 'vertical' = up and down bars, 'horizontal' = side to side bars
55        this.barDirection = 'vertical';
56        // prop: barWidth
57        // Width of the bar in pixels (auto by devaul).  null = calculated automatically.
58        this.barWidth = null;
59        // prop: shadowOffset
60        // offset of the shadow from the slice and offset of
61        // each succesive stroke of the shadow from the last.
62        this.shadowOffset = 2;
63        // prop: shadowDepth
64        // number of strokes to apply to the shadow,
65        // each stroke offset shadowOffset from the last.
66        this.shadowDepth = 5;
67        // prop: shadowAlpha
68        // transparency of the shadow (0 = transparent, 1 = opaque)
69        this.shadowAlpha = 0.08;
70        // prop: waterfall
71        // true to enable waterfall plot.
72        this.waterfall = false;
73        // prop: groups
74        // group bars into this many groups
75        this.groups = 1;
76        // prop: varyBarColor
77        // true to color each bar of a series separately rather than
78        // have every bar of a given series the same color.
79        // If used for non-stacked multiple series bar plots, user should
80        // specify a separate 'seriesColors' array for each series.
81        // Otherwise, each series will set their bars to the same color array.
82        // This option has no Effect for stacked bar charts and is disabled.
83        this.varyBarColor = false;
84        // prop: highlightMouseOver
85        // True to highlight slice when moused over.
86        // This must be false to enable highlightMouseDown to highlight when clicking on a slice.
87        this.highlightMouseOver = true;
88        // prop: highlightMouseDown
89        // True to highlight when a mouse button is pressed over a slice.
90        // This will be disabled if highlightMouseOver is true.
91        this.highlightMouseDown = false;
92        // prop: highlightColors
93        // an array of colors to use when highlighting a bar.
94        this.highlightColors = [];
95        // prop: transposedData
96        // NOT IMPLEMENTED YET.  True if this is a horizontal bar plot and
97        // x and y values are "transposed".  Tranposed, or "swapped", data is
98        // required prior to rev. 894 builds of jqPlot with horizontal bars.
99        // Allows backward compatability of bar renderer horizontal bars with
100        // old style data sets.
101        this.transposedData = true;
102        this.renderer.animation = {
103            show: false,
104            direction: 'down',
105            speed: 3000,
106            _supported: true
107        };
108        this._type = 'bar';
109       
110        // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver
111        if (options.highlightMouseDown && options.highlightMouseOver == null) {
112            options.highlightMouseOver = false;
113        }
114       
115        //////
116        // This is probably wrong here.
117        // After going back and forth on wether renderer should be the thing
118        // or extend the thing, it seems that it it best if it is a property
119        // on the thing.  This should be something that is commonized
120        // among series renderers in the future.
121        //////
122        $.extend(true, this, options);
123
124        // really should probably do this
125        $.extend(true, this.renderer, options);
126        // fill is still needed to properly draw the legend.
127        // bars have to be filled.
128        this.fill = true;
129
130        // if horizontal bar and animating, reset the default direction
131        if (this.barDirection === 'horizontal' && this.rendererOptions.animation && this.rendererOptions.animation.direction == null) {
132            this.renderer.animation.direction = 'left';
133        }
134       
135        if (this.waterfall) {
136            this.fillToZero = false;
137            this.disableStack = true;
138        }
139       
140        if (this.barDirection == 'vertical' ) {
141            this._primaryAxis = '_xaxis';
142            this._stackAxis = 'y';
143            this.fillAxis = 'y';
144        }
145        else {
146            this._primaryAxis = '_yaxis';
147            this._stackAxis = 'x';
148            this.fillAxis = 'x';
149        }
150        // index of the currenty highlighted point, if any
151        this._highlightedPoint = null;
152        // total number of values for all bar series, total number of bar series, and position of this series
153        this._plotSeriesInfo = null;
154        // Array of actual data colors used for each data point.
155        this._dataColors = [];
156        this._barPoints = [];
157       
158        // set the shape renderer options
159        var opts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill};
160        this.renderer.shapeRenderer.init(opts);
161        // set the shadow renderer options
162        var sopts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, closePath:this.fill};
163        this.renderer.shadowRenderer.init(sopts);
164       
165        plot.postInitHooks.addOnce(postInit);
166        plot.postDrawHooks.addOnce(postPlotDraw);
167        plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove);
168        plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown);
169        plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp);
170        plot.eventListenerHooks.addOnce('jqplotClick', handleClick);
171        plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick);
172    };
173   
174    // called with scope of series
175    function barPreInit(target, data, seriesDefaults, options) {
176        if (this.rendererOptions.barDirection == 'horizontal') {
177            this._stackAxis = 'x';
178            this._primaryAxis = '_yaxis';
179        }
180        if (this.rendererOptions.waterfall == true) {
181            this._data = $.extend(true, [], this.data);
182            var sum = 0;
183            var pos = (!this.rendererOptions.barDirection || this.rendererOptions.barDirection === 'vertical' || this.transposedData === false) ? 1 : 0;
184            for(var i=0; i<this.data.length; i++) {
185                sum += this.data[i][pos];
186                if (i>0) {
187                    this.data[i][pos] += this.data[i-1][pos];
188                }
189            }
190            this.data[this.data.length] = (pos == 1) ? [this.data.length+1, sum] : [sum, this.data.length+1];
191            this._data[this._data.length] = (pos == 1) ? [this._data.length+1, sum] : [sum, this._data.length+1];
192        }
193        if (this.rendererOptions.groups > 1) {
194            this.breakOnNull = true;
195            var l = this.data.length;
196            var skip = parseInt(l/this.rendererOptions.groups, 10);
197            var count = 0;
198            for (var i=skip; i<l; i+=skip) {
199                this.data.splice(i+count, 0, [null, null]);
200                count++;
201            }
202            for (i=0; i<this.data.length; i++) {
203                if (this._primaryAxis == '_xaxis') {
204                    this.data[i][0] = i+1;
205                }
206                else {
207                    this.data[i][1] = i+1;
208                }
209            }
210        }
211    }
212   
213    $.jqplot.preSeriesInitHooks.push(barPreInit);
214   
215    // needs to be called with scope of series, not renderer.
216    $.jqplot.BarRenderer.prototype.calcSeriesNumbers = function() {
217        var nvals = 0;
218        var nseries = 0;
219        var paxis = this[this._primaryAxis];
220        var s, series, pos;
221        // loop through all series on this axis
222        for (var i=0; i < paxis._series.length; i++) {
223            series = paxis._series[i];
224            if (series === this) {
225                pos = i;
226            }
227            // is the series rendered as a bar?
228            if (series.renderer.constructor == $.jqplot.BarRenderer) {
229                // gridData may not be computed yet, use data length insted
230                nvals += series.data.length;
231                nseries += 1;
232            }
233        }
234        // return total number of values for all bar series, total number of bar series, and position of this series
235        return [nvals, nseries, pos];
236    };
237
238    $.jqplot.BarRenderer.prototype.setBarWidth = function() {
239        // need to know how many data values we have on the approprate axis and figure it out.
240        var i;
241        var nvals = 0;
242        var nseries = 0;
243        var paxis = this[this._primaryAxis];
244        var s, series, pos;
245        var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this);
246        nvals = temp[0];
247        nseries = temp[1];
248        var nticks = paxis.numberTicks;
249        var nbins = (nticks-1)/2;
250        // so, now we have total number of axis values.
251        if (paxis.name == 'xaxis' || paxis.name == 'x2axis') {
252            if (this._stack) {
253                this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals * nseries - this.barMargin;
254            }
255            else {
256                this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/nbins  - this.barPadding * (nseries-1) - this.barMargin*2)/nseries;
257                // this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding - this.barMargin/nseries;
258            }
259        }
260        else {
261            if (this._stack) {
262                this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals * nseries - this.barMargin;
263            }
264            else {
265                this.barWidth = ((paxis._offsets.min - paxis._offsets.max)/nbins  - this.barPadding * (nseries-1) - this.barMargin*2)/nseries;
266                // this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding - this.barMargin/nseries;
267            }
268        }
269        return [nvals, nseries];
270    };
271
272    function computeHighlightColors (colors) {
273        var ret = [];
274        for (var i=0; i<colors.length; i++){
275            var rgba = $.jqplot.getColorComponents(colors[i]);
276            var newrgb = [rgba[0], rgba[1], rgba[2]];
277            var sum = newrgb[0] + newrgb[1] + newrgb[2];
278            for (var j=0; j<3; j++) {
279                // when darkening, lowest color component can be is 60.
280                newrgb[j] = (sum > 570) ?  newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]);
281                newrgb[j] = parseInt(newrgb[j], 10);
282            }
283            ret.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')');
284        }
285        return ret;
286    }
287   
288    $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options) {
289        var i;
290        // Ughhh, have to make a copy of options b/c it may be modified later.
291        var opts = $.extend({}, options);
292        var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
293        var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine;
294        var fill = (opts.fill != undefined) ? opts.fill : this.fill;
295        var xaxis = this.xaxis;
296        var yaxis = this.yaxis;
297        var xp = this._xaxis.series_u2p;
298        var yp = this._yaxis.series_u2p;
299        var pointx, pointy;
300        // clear out data colors.
301        this._dataColors = [];
302        this._barPoints = [];
303       
304        if (this.barWidth == null) {
305            this.renderer.setBarWidth.call(this);
306        }
307       
308        var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this);
309        var nvals = temp[0];
310        var nseries = temp[1];
311        var pos = temp[2];
312    var points = [];
313       
314        if (this._stack) {
315            this._barNudge = 0;
316        }
317        else {
318            this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding);
319        }
320        if (showLine) {
321            var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors);
322            var positiveColors = new $.jqplot.ColorGenerator(this.seriesColors);
323            var negativeColor = negativeColors.get(this.index);
324            if (! this.useNegativeColors) {
325                negativeColor = opts.fillStyle;
326            }
327            var positiveColor = opts.fillStyle;
328      var base;
329      var xstart;
330      var ystart;
331           
332            if (this.barDirection == 'vertical') {
333                for (var i=0; i<gridData.length; i++) {
334                    if (this.data[i][1] == null) {
335                        continue;
336                    }
337                    points = [];
338                    base = gridData[i][0] + this._barNudge;
339                    ystart;
340                   
341                    // stacked
342                    if (this._stack && this._prevGridData.length) {
343                        ystart = this._prevGridData[i][1];
344                    }
345                    // not stacked and first series in stack
346                    else {
347                        if (this.fillToZero) {
348                            ystart = this._yaxis.series_u2p(0);
349                        }
350                        else if (this.waterfall && i > 0 && i < this.gridData.length-1) {
351                            ystart = this.gridData[i-1][1];
352                        }
353                        else if (this.waterfall && i == 0 && i < this.gridData.length-1) {
354                            if (this._yaxis.min <= 0 && this._yaxis.max >= 0) {
355                                ystart = this._yaxis.series_u2p(0);
356                            }
357                            else if (this._yaxis.min > 0) {
358                                ystart = ctx.canvas.height;
359                            }
360                            else {
361                                ystart = 0;
362                            }
363                        }
364                        else if (this.waterfall && i == this.gridData.length - 1) {
365                            if (this._yaxis.min <= 0 && this._yaxis.max >= 0) {
366                                ystart = this._yaxis.series_u2p(0);
367                            }
368                            else if (this._yaxis.min > 0) {
369                                ystart = ctx.canvas.height;
370                            }
371                            else {
372                                ystart = 0;
373                            }
374                        }
375                        else {
376                            ystart = ctx.canvas.height;
377                        }
378                    }
379                    if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) {
380                        if (this.varyBarColor && !this._stack) {
381                            if (this.useNegativeColors) {
382                                opts.fillStyle = negativeColors.next();
383                            }
384                            else {
385                                opts.fillStyle = positiveColors.next();
386                            }
387                        }
388                        else {
389                            opts.fillStyle = negativeColor;
390                        }
391                    }
392                    else {
393                        if (this.varyBarColor && !this._stack) {
394                            opts.fillStyle = positiveColors.next();
395                        }
396                        else {
397                            opts.fillStyle = positiveColor;
398                        }
399                    }
400         
401          if (!this.fillToZero || this._plotData[i][1] >= 0) {
402            points.push([base-this.barWidth/2, ystart]);
403            points.push([base-this.barWidth/2, gridData[i][1]]);
404            points.push([base+this.barWidth/2, gridData[i][1]]);
405            points.push([base+this.barWidth/2, ystart]);
406          }
407          // for negative bars make sure points are always ordered clockwise
408          else {             
409            points.push([base-this.barWidth/2, gridData[i][1]]);
410            points.push([base-this.barWidth/2, ystart]);
411            points.push([base+this.barWidth/2, ystart]);
412            points.push([base+this.barWidth/2, gridData[i][1]]);
413          }
414                    this._barPoints.push(points);
415                    // now draw the shadows if not stacked.
416                    // for stacked plots, they are predrawn by drawShadow
417                    if (shadow && !this._stack) {
418                        var sopts = $.extend(true, {}, opts);
419                        // need to get rid of fillStyle on shadow.
420                        delete sopts.fillStyle;
421                        this.renderer.shadowRenderer.draw(ctx, points, sopts);
422                    }
423                    var clr = opts.fillStyle || this.color;
424                    this._dataColors.push(clr);
425                    this.renderer.shapeRenderer.draw(ctx, points, opts);
426                }
427            }
428           
429            else if (this.barDirection == 'horizontal'){
430                for (var i=0; i<gridData.length; i++) {
431                    if (this.data[i][0] == null) {
432                        continue;
433                    }
434                    points = [];
435                    base = gridData[i][1] - this._barNudge;
436                    xstart;
437                   
438                    if (this._stack && this._prevGridData.length) {
439                        xstart = this._prevGridData[i][0];
440                    }
441                    // not stacked and first series in stack
442                    else {
443                        if (this.fillToZero) {
444                            xstart = this._xaxis.series_u2p(0);
445                        }
446                        else if (this.waterfall && i > 0 && i < this.gridData.length-1) {
447                            xstart = this.gridData[i-1][1];
448                        }
449                        else if (this.waterfall && i == 0 && i < this.gridData.length-1) {
450                            if (this._xaxis.min <= 0 && this._xaxis.max >= 0) {
451                                xstart = this._xaxis.series_u2p(0);
452                            }
453                            else if (this._xaxis.min > 0) {
454                                xstart = 0;
455                            }
456                            else {
457                                xstart = ctx.canvas.width;
458                            }
459                        }
460                        else if (this.waterfall && i == this.gridData.length - 1) {
461                            if (this._xaxis.min <= 0 && this._xaxis.max >= 0) {
462                                xstart = this._xaxis.series_u2p(0);
463                            }
464                            else if (this._xaxis.min > 0) {
465                                xstart = 0;
466                            }
467                            else {
468                                xstart = ctx.canvas.width;
469                            }
470                        }
471                        else {
472                            xstart = 0;
473                        }
474                    }
475                    if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) {
476                        if (this.varyBarColor && !this._stack) {
477                            if (this.useNegativeColors) {
478                                opts.fillStyle = negativeColors.next();
479                            }
480                            else {
481                                opts.fillStyle = positiveColors.next();
482                            }
483                        }
484                    }
485                    else {
486                        if (this.varyBarColor && !this._stack) {
487                            opts.fillStyle = positiveColors.next();
488                        }
489                        else {
490                            opts.fillStyle = positiveColor;
491                        }                   
492                    }
493                   
494
495                    if (!this.fillToZero || this._plotData[i][0] >= 0) {
496                        points.push([xstart, base + this.barWidth / 2]);
497                        points.push([xstart, base - this.barWidth / 2]);
498                        points.push([gridData[i][0], base - this.barWidth / 2]);
499                        points.push([gridData[i][0], base + this.barWidth / 2]);
500                    }
501                    else {
502                        points.push([gridData[i][0], base + this.barWidth / 2]);
503                        points.push([gridData[i][0], base - this.barWidth / 2]);
504                        points.push([xstart, base - this.barWidth / 2]);
505                        points.push([xstart, base + this.barWidth / 2]);
506                    }
507
508                    this._barPoints.push(points);
509                    // now draw the shadows if not stacked.
510                    // for stacked plots, they are predrawn by drawShadow
511                    if (shadow && !this._stack) {
512                        var sopts = $.extend(true, {}, opts);
513                        delete sopts.fillStyle;
514                        this.renderer.shadowRenderer.draw(ctx, points, sopts);
515                    }
516                    var clr = opts.fillStyle || this.color;
517                    this._dataColors.push(clr);
518                    this.renderer.shapeRenderer.draw(ctx, points, opts);
519                } 
520            }
521        }               
522       
523        if (this.highlightColors.length == 0) {
524            this.highlightColors = $.jqplot.computeHighlightColors(this._dataColors);
525        }
526       
527        else if (typeof(this.highlightColors) == 'string') {
528            var temp = this.highlightColors;
529            this.highlightColors = [];
530            for (var i=0; i<this._dataColors.length; i++) {
531                this.highlightColors.push(temp);
532            }
533        }
534       
535    };
536   
537     
538    // for stacked plots, shadows will be pre drawn by drawShadow.
539    $.jqplot.BarRenderer.prototype.drawShadow = function(ctx, gridData, options) {
540        var i;
541        var opts = (options != undefined) ? options : {};
542        var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
543        var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine;
544        var fill = (opts.fill != undefined) ? opts.fill : this.fill;
545        var xaxis = this.xaxis;
546        var yaxis = this.yaxis;
547        var xp = this._xaxis.series_u2p;
548        var yp = this._yaxis.series_u2p;
549        var pointx, points, pointy, nvals, nseries, pos;
550       
551        if (this._stack && this.shadow) {
552            if (this.barWidth == null) {
553                this.renderer.setBarWidth.call(this);
554            }
555       
556            var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this);
557            nvals = temp[0];
558            nseries = temp[1];
559            pos = temp[2];
560       
561            if (this._stack) {
562                this._barNudge = 0;
563            }
564            else {
565                this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding);
566            }
567            if (showLine) {
568           
569                if (this.barDirection == 'vertical') {
570                    for (var i=0; i<gridData.length; i++) {
571                        if (this.data[i][1] == null) {
572                            continue;
573                        }
574                        points = [];
575                        var base = gridData[i][0] + this._barNudge;
576                        var ystart;
577                   
578                        if (this._stack && this._prevGridData.length) {
579                            ystart = this._prevGridData[i][1];
580                        }
581                        else {
582                            if (this.fillToZero) {
583                                ystart = this._yaxis.series_u2p(0);
584                            }
585                            else {
586                                ystart = ctx.canvas.height;
587                            }
588                        }
589                   
590                        points.push([base-this.barWidth/2, ystart]);
591                        points.push([base-this.barWidth/2, gridData[i][1]]);
592                        points.push([base+this.barWidth/2, gridData[i][1]]);
593                        points.push([base+this.barWidth/2, ystart]);
594                        this.renderer.shadowRenderer.draw(ctx, points, opts);
595                    }
596                }
597           
598                else if (this.barDirection == 'horizontal'){
599                    for (var i=0; i<gridData.length; i++) {
600                        if (this.data[i][0] == null) {
601                            continue;
602                        }
603                        points = [];
604                        var base = gridData[i][1] - this._barNudge;
605                        var xstart;
606                   
607                        if (this._stack && this._prevGridData.length) {
608                            xstart = this._prevGridData[i][0];
609                        }
610                        else {
611                            xstart = 0;
612                        }
613                   
614                        points.push([xstart, base+this.barWidth/2]);
615                        points.push([gridData[i][0], base+this.barWidth/2]);
616                        points.push([gridData[i][0], base-this.barWidth/2]);
617                        points.push([xstart, base-this.barWidth/2]);
618                        this.renderer.shadowRenderer.draw(ctx, points, opts);
619                    } 
620                }
621            }   
622           
623        }
624    };
625   
626    function postInit(target, data, options) {
627        for (var i=0; i<this.series.length; i++) {
628            if (this.series[i].renderer.constructor == $.jqplot.BarRenderer) {
629                // don't allow mouseover and mousedown at same time.
630                if (this.series[i].highlightMouseOver) {
631                    this.series[i].highlightMouseDown = false;
632                }
633            }
634        }
635    }
636   
637    // called within context of plot
638    // create a canvas which we can draw on.
639    // insert it before the eventCanvas, so eventCanvas will still capture events.
640    function postPlotDraw() {
641        // Memory Leaks patch   
642        if (this.plugins.barRenderer && this.plugins.barRenderer.highlightCanvas) {
643
644            this.plugins.barRenderer.highlightCanvas.resetCanvas();
645            this.plugins.barRenderer.highlightCanvas = null;
646        }
647         
648        this.plugins.barRenderer = {highlightedSeriesIndex:null};
649        this.plugins.barRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
650       
651        this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-barRenderer-highlight-canvas', this._plotDimensions, this));
652        this.plugins.barRenderer.highlightCanvas.setContext();
653        this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
654    }   
655   
656    function highlight (plot, sidx, pidx, points) {
657        var s = plot.series[sidx];
658        var canvas = plot.plugins.barRenderer.highlightCanvas;
659        canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height);
660        s._highlightedPoint = pidx;
661        plot.plugins.barRenderer.highlightedSeriesIndex = sidx;
662        var opts = {fillStyle: s.highlightColors[pidx]};
663        s.renderer.shapeRenderer.draw(canvas._ctx, points, opts);
664        canvas = null;
665    }
666   
667    function unhighlight (plot) {
668        var canvas = plot.plugins.barRenderer.highlightCanvas;
669        canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height);
670        for (var i=0; i<plot.series.length; i++) {
671            plot.series[i]._highlightedPoint = null;
672        }
673        plot.plugins.barRenderer.highlightedSeriesIndex = null;
674        plot.target.trigger('jqplotDataUnhighlight');
675        canvas =  null;
676    }
677   
678   
679    function handleMove(ev, gridpos, datapos, neighbor, plot) {
680        if (neighbor) {
681            var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
682            var evt1 = jQuery.Event('jqplotDataMouseOver');
683            evt1.pageX = ev.pageX;
684            evt1.pageY = ev.pageY;
685            plot.target.trigger(evt1, ins);
686            if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
687                var evt = jQuery.Event('jqplotDataHighlight');
688                evt.pageX = ev.pageX;
689                evt.pageY = ev.pageY;
690                plot.target.trigger(evt, ins);
691                highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points);
692            }
693        }
694        else if (neighbor == null) {
695            unhighlight (plot);
696        }
697    }
698   
699    function handleMouseDown(ev, gridpos, datapos, neighbor, plot) {
700        if (neighbor) {
701            var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
702            if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
703                var evt = jQuery.Event('jqplotDataHighlight');
704                evt.pageX = ev.pageX;
705                evt.pageY = ev.pageY;
706                plot.target.trigger(evt, ins);
707                highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points);
708            }
709        }
710        else if (neighbor == null) {
711            unhighlight (plot);
712        }
713    }
714   
715    function handleMouseUp(ev, gridpos, datapos, neighbor, plot) {
716        var idx = plot.plugins.barRenderer.highlightedSeriesIndex;
717        if (idx != null && plot.series[idx].highlightMouseDown) {
718            unhighlight(plot);
719        }
720    }
721   
722    function handleClick(ev, gridpos, datapos, neighbor, plot) {
723        if (neighbor) {
724            var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
725            var evt = jQuery.Event('jqplotDataClick');
726            evt.pageX = ev.pageX;
727            evt.pageY = ev.pageY;
728            plot.target.trigger(evt, ins);
729        }
730    }
731   
732    function handleRightClick(ev, gridpos, datapos, neighbor, plot) {
733        if (neighbor) {
734            var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
735            var idx = plot.plugins.barRenderer.highlightedSeriesIndex;
736            if (idx != null && plot.series[idx].highlightMouseDown) {
737                unhighlight(plot);
738            }
739            var evt = jQuery.Event('jqplotDataRightClick');
740            evt.pageX = ev.pageX;
741            evt.pageY = ev.pageY;
742            plot.target.trigger(evt, ins);
743        }
744    }
745   
746   
747})(jQuery);   
Note: See TracBrowser for help on using the repository browser.