| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| (function($) { |
| |
| |
| |
| $.jqplot.LineRenderer = function(){ |
| this.shapeRenderer = new $.jqplot.ShapeRenderer(); |
| this.shadowRenderer = new $.jqplot.ShadowRenderer(); |
| }; |
| |
| |
| $.jqplot.LineRenderer.prototype.init = function(options, plot) { |
| |
| |
| options = options || {}; |
| this._type='line'; |
| this.renderer.animation = { |
| show: false, |
| direction: 'left', |
| speed: 2500, |
| _supported: true |
| }; |
| |
| |
| |
| |
| |
| this.renderer.smooth = false; |
| this.renderer.tension = null; |
| |
| |
| |
| |
| this.renderer.constrainSmoothing = true; |
| |
| this.renderer._smoothedData = []; |
| |
| this.renderer._smoothedPlotData = []; |
| this.renderer._hiBandGridData = []; |
| this.renderer._lowBandGridData = []; |
| this.renderer._hiBandSmoothedData = []; |
| this.renderer._lowBandSmoothedData = []; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| this.renderer.bandData = []; |
|
|
| |
| |
| this.renderer.bands = { |
| |
| |
| |
| show: false, |
| hiData: [], |
| lowData: [], |
| |
| |
| color: this.color, |
| |
| |
| showLines: false, |
| |
| |
| fill: true, |
| |
| |
| fillColor: null, |
| _min: null, |
| _max: null, |
| |
| |
| |
| |
| interval: '3%' |
| }; |
|
|
|
|
| var lopts = {highlightMouseOver: options.highlightMouseOver, highlightMouseDown: options.highlightMouseDown, highlightColor: options.highlightColor}; |
| |
| delete (options.highlightMouseOver); |
| delete (options.highlightMouseDown); |
| delete (options.highlightColor); |
| |
| $.extend(true, this.renderer, options); |
|
|
| this.renderer.options = options; |
|
|
| |
| if (this.renderer.bandData.length > 1 && (!options.bands || options.bands.show == null)) { |
| this.renderer.bands.show = true; |
| } |
|
|
| |
| else if (options.bands && options.bands.show == null && options.bands.interval != null) { |
| this.renderer.bands.show = true; |
| } |
|
|
| |
| if (this.fill) { |
| this.renderer.bands.show = false; |
| } |
|
|
| if (this.renderer.bands.show) { |
| this.renderer.initBands.call(this, this.renderer.options, plot); |
| } |
|
|
|
|
| |
| if (this._stack) { |
| this.renderer.smooth = false; |
| } |
|
|
| |
| var opts = {lineJoin:this.lineJoin, lineCap:this.lineCap, fill:this.fill, isarc:false, strokeStyle:this.color, fillStyle:this.fillColor, lineWidth:this.lineWidth, linePattern:this.linePattern, closePath:this.fill}; |
| this.renderer.shapeRenderer.init(opts); |
|
|
| var shadow_offset = options.shadowOffset; |
| |
| if (shadow_offset == null) { |
| |
| if (this.lineWidth > 2.5) { |
| shadow_offset = 1.25 * (1 + (Math.atan((this.lineWidth/2.5))/0.785398163 - 1)*0.6); |
| |
| } |
| |
| else { |
| shadow_offset = 1.25 * Math.atan((this.lineWidth/2.5))/0.785398163; |
| } |
| } |
| |
| var sopts = {lineJoin:this.lineJoin, lineCap:this.lineCap, fill:this.fill, isarc:false, angle:this.shadowAngle, offset:shadow_offset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.lineWidth, linePattern:this.linePattern, closePath:this.fill}; |
| this.renderer.shadowRenderer.init(sopts); |
| this._areaPoints = []; |
| this._boundingBox = [[],[]]; |
| |
| if (!this.isTrendline && this.fill || this.renderer.bands.show) { |
| |
| |
| |
| |
| |
| this.highlightMouseOver = true; |
| |
| |
| |
| this.highlightMouseDown = false; |
| |
| |
| this.highlightColor = null; |
| |
| if (lopts.highlightMouseDown && lopts.highlightMouseOver == null) { |
| lopts.highlightMouseOver = false; |
| } |
| |
| $.extend(true, this, {highlightMouseOver: lopts.highlightMouseOver, highlightMouseDown: lopts.highlightMouseDown, highlightColor: lopts.highlightColor}); |
| |
| if (!this.highlightColor) { |
| var fc = (this.renderer.bands.show) ? this.renderer.bands.fillColor : this.fillColor; |
| this.highlightColor = $.jqplot.computeHighlightColors(fc); |
| } |
| |
| if (this.highlighter) { |
| this.highlighter.show = false; |
| } |
| } |
| |
| if (!this.isTrendline && plot) { |
| plot.plugins.lineRenderer = {}; |
| plot.postInitHooks.addOnce(postInit); |
| plot.postDrawHooks.addOnce(postPlotDraw); |
| plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); |
| plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); |
| plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); |
| plot.eventListenerHooks.addOnce('jqplotClick', handleClick); |
| plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); |
| } |
|
|
| }; |
|
|
| $.jqplot.LineRenderer.prototype.initBands = function(options, plot) { |
| |
| |
| var bd = options.bandData || []; |
| var bands = this.renderer.bands; |
| bands.hiData = []; |
| bands.lowData = []; |
| var data = this.data; |
| bands._max = null; |
| bands._min = null; |
| |
| if (bd.length == 2) { |
| |
| |
| if ($.isArray(bd[0][0])) { |
| |
|
|
| var p; |
| var bdminidx = 0, bdmaxidx = 0; |
| for (var i = 0, l = bd[0].length; i<l; i++) { |
| p = bd[0][i]; |
| if ((p[1] != null && p[1] > bands._max) || bands._max == null) { |
| bands._max = p[1]; |
| } |
| if ((p[1] != null && p[1] < bands._min) || bands._min == null) { |
| bands._min = p[1]; |
| } |
| } |
| for (var i = 0, l = bd[1].length; i<l; i++) { |
| p = bd[1][i]; |
| if ((p[1] != null && p[1] > bands._max) || bands._max == null) { |
| bands._max = p[1]; |
| bdmaxidx = 1; |
| } |
| if ((p[1] != null && p[1] < bands._min) || bands._min == null) { |
| bands._min = p[1]; |
| bdminidx = 1; |
| } |
| } |
|
|
| if (bdmaxidx === bdminidx) { |
| bands.show = false; |
| } |
|
|
| bands.hiData = bd[bdmaxidx]; |
| bands.lowData = bd[bdminidx]; |
| } |
| |
| |
| |
| else if (bd[0].length === data.length && bd[1].length === data.length) { |
| var hi = (bd[0][0] > bd[1][0]) ? 0 : 1; |
| var low = (hi) ? 0 : 1; |
| for (var i=0, l=data.length; i < l; i++) { |
| bands.hiData.push([data[i][0], bd[hi][i]]); |
| bands.lowData.push([data[i][0], bd[low][i]]); |
| } |
| } |
|
|
| |
| else { |
| bands.show = false; |
| } |
| } |
|
|
| |
| |
| |
| else if (bd.length > 2 && !$.isArray(bd[0][0])) { |
| var hi = (bd[0][0] > bd[0][1]) ? 0 : 1; |
| var low = (hi) ? 0 : 1; |
| for (var i=0, l=bd.length; i<l; i++) { |
| bands.hiData.push([data[i][0], bd[i][hi]]); |
| bands.lowData.push([data[i][0], bd[i][low]]); |
| } |
| } |
|
|
| |
| else { |
| var intrv = bands.interval; |
| var a = null; |
| var b = null; |
| var afunc = null; |
| var bfunc = null; |
|
|
| if ($.isArray(intrv)) { |
| a = intrv[0]; |
| b = intrv[1]; |
| } |
| else { |
| a = intrv; |
| } |
|
|
| if (isNaN(a)) { |
| |
| if (a.charAt(a.length - 1) === '%') { |
| afunc = 'multiply'; |
| a = parseFloat(a)/100 + 1; |
| } |
| } |
|
|
| else { |
| a = parseFloat(a); |
| afunc = 'add'; |
| } |
|
|
| if (b !== null && isNaN(b)) { |
| |
| if (b.charAt(b.length - 1) === '%') { |
| bfunc = 'multiply'; |
| b = parseFloat(b)/100 + 1; |
| } |
| } |
|
|
| else if (b !== null) { |
| b = parseFloat(b); |
| bfunc = 'add'; |
| } |
|
|
| if (a !== null) { |
| if (b === null) { |
| b = -a; |
| bfunc = afunc; |
| if (bfunc === 'multiply') { |
| b += 2; |
| } |
| } |
|
|
| |
| if (a < b) { |
| var temp = a; |
| a = b; |
| b = temp; |
| temp = afunc; |
| afunc = bfunc; |
| bfunc = temp; |
| } |
|
|
| for (var i=0, l = data.length; i < l; i++) { |
| switch (afunc) { |
| case 'add': |
| bands.hiData.push([data[i][0], data[i][1] + a]); |
| break; |
| case 'multiply': |
| bands.hiData.push([data[i][0], data[i][1] * a]); |
| break; |
| } |
| switch (bfunc) { |
| case 'add': |
| bands.lowData.push([data[i][0], data[i][1] + b]); |
| break; |
| case 'multiply': |
| bands.lowData.push([data[i][0], data[i][1] * b]); |
| break; |
| } |
| } |
| } |
|
|
| else { |
| bands.show = false; |
| } |
| } |
|
|
| var hd = bands.hiData; |
| var ld = bands.lowData; |
| for (var i = 0, l = hd.length; i<l; i++) { |
| if ((hd[i][1] != null && hd[i][1] > bands._max) || bands._max == null) { |
| bands._max = hd[i][1]; |
| } |
| } |
| for (var i = 0, l = ld.length; i<l; i++) { |
| if ((ld[i][1] != null && ld[i][1] < bands._min) || bands._min == null) { |
| bands._min = ld[i][1]; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
|
|
| |
| |
| |
|
|
| if (bands.fillColor === null) { |
| var c = $.jqplot.getColorComponents(bands.color); |
| |
| c[3] = c[3] * 0.5; |
| bands.fillColor = 'rgba(' + c[0] +', '+ c[1] +', '+ c[2] +', '+ c[3] + ')'; |
| } |
| }; |
|
|
| function getSteps (d, f) { |
| return (3.4182054+f) * Math.pow(d, -0.3534992); |
| } |
|
|
| function computeSteps (d1, d2) { |
| var s = Math.sqrt(Math.pow((d2[0]- d1[0]), 2) + Math.pow ((d2[1] - d1[1]), 2)); |
| return 5.7648 * Math.log(s) + 7.4456; |
| } |
|
|
| function tanh (x) { |
| var a = (Math.exp(2*x) - 1) / (Math.exp(2*x) + 1); |
| return a; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| function computeConstrainedSmoothedData (gd) { |
| var smooth = this.renderer.smooth; |
| var dim = this.canvas.getWidth(); |
| var xp = this._xaxis.series_p2u; |
| var yp = this._yaxis.series_p2u; |
| var steps =null; |
| var _steps = null; |
| var dist = gd.length/dim; |
| var _smoothedData = []; |
| var _smoothedPlotData = []; |
|
|
| if (!isNaN(parseFloat(smooth))) { |
| steps = parseFloat(smooth); |
| } |
| else { |
| steps = getSteps(dist, 0.5); |
| } |
|
|
| var yy = []; |
| var xx = []; |
|
|
| for (var i=0, l = gd.length; i<l; i++) { |
| yy.push(gd[i][1]); |
| xx.push(gd[i][0]); |
| } |
|
|
| function dxx(x1, x0) { |
| if (x1 - x0 == 0) { |
| return Math.pow(10,10); |
| } |
| else { |
| return x1 - x0; |
| } |
| } |
|
|
| var A, B, C, D; |
| |
| var nmax = gd.length - 1; |
| for (var num = 1, gdl = gd.length; num<gdl; num++) { |
| var gxx = []; |
| var ggxx = []; |
| |
| for (var j = 0; j < 2; j++) { |
| var i = num - 1 + j; |
|
|
| if (i == 0 || i == nmax) { |
| gxx[j] = Math.pow(10, 10); |
| } |
| else if (yy[i+1] - yy[i] == 0 || yy[i] - yy[i-1] == 0) { |
| gxx[j] = 0; |
| } |
| else if (((xx[i+1] - xx[i]) / (yy[i+1] - yy[i]) + (xx[i] - xx[i-1]) / (yy[i] - yy[i-1])) == 0 ) { |
| gxx[j] = 0; |
| } |
| else if ( (yy[i+1] - yy[i]) * (yy[i] - yy[i-1]) < 0 ) { |
| gxx[j] = 0; |
| } |
|
|
| else { |
| gxx[j] = 2 / (dxx(xx[i + 1], xx[i]) / (yy[i + 1] - yy[i]) + dxx(xx[i], xx[i - 1]) / (yy[i] - yy[i - 1])); |
| } |
| } |
|
|
| |
| if (num == 1) { |
| |
| gxx[0] = 3 / 2 * (yy[1] - yy[0]) / dxx(xx[1], xx[0]) - gxx[1] / 2; |
| } |
| else if (num == nmax) { |
| |
| gxx[1] = 3 / 2 * (yy[nmax] - yy[nmax - 1]) / dxx(xx[nmax], xx[nmax - 1]) - gxx[0] / 2; |
| } |
|
|
| |
| ggxx[0] = -2 * (gxx[1] + 2 * gxx[0]) / dxx(xx[num], xx[num - 1]) + 6 * (yy[num] - yy[num - 1]) / Math.pow(dxx(xx[num], xx[num - 1]), 2); |
| ggxx[1] = 2 * (2 * gxx[1] + gxx[0]) / dxx(xx[num], xx[num - 1]) - 6 * (yy[num] - yy[num - 1]) / Math.pow(dxx(xx[num], xx[num - 1]), 2); |
|
|
| |
| D = 1 / 6 * (ggxx[1] - ggxx[0]) / dxx(xx[num], xx[num - 1]); |
| C = 1 / 2 * (xx[num] * ggxx[0] - xx[num - 1] * ggxx[1]) / dxx(xx[num], xx[num - 1]); |
| B = (yy[num] - yy[num - 1] - C * (Math.pow(xx[num], 2) - Math.pow(xx[num - 1], 2)) - D * (Math.pow(xx[num], 3) - Math.pow(xx[num - 1], 3))) / dxx(xx[num], xx[num - 1]); |
| A = yy[num - 1] - B * xx[num - 1] - C * Math.pow(xx[num - 1], 2) - D * Math.pow(xx[num - 1], 3); |
|
|
| var increment = (xx[num] - xx[num - 1]) / steps; |
| var temp, tempx; |
|
|
| for (var j = 0, l = steps; j < l; j++) { |
| temp = []; |
| tempx = xx[num - 1] + j * increment; |
| temp.push(tempx); |
| temp.push(A + B * tempx + C * Math.pow(tempx, 2) + D * Math.pow(tempx, 3)); |
| _smoothedData.push(temp); |
| _smoothedPlotData.push([xp(temp[0]), yp(temp[1])]); |
| } |
| } |
|
|
| _smoothedData.push(gd[i]); |
| _smoothedPlotData.push([xp(gd[i][0]), yp(gd[i][1])]); |
|
|
| return [_smoothedData, _smoothedPlotData]; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| function computeHermiteSmoothedData (gd) { |
| var smooth = this.renderer.smooth; |
| var tension = this.renderer.tension; |
| var dim = this.canvas.getWidth(); |
| var xp = this._xaxis.series_p2u; |
| var yp = this._yaxis.series_p2u; |
| var steps =null; |
| var _steps = null; |
| var a = null; |
| var a1 = null; |
| var a2 = null; |
| var slope = null; |
| var slope2 = null; |
| var temp = null; |
| var t, s, h1, h2, h3, h4; |
| var TiX, TiY, Ti1X, Ti1Y; |
| var pX, pY, p; |
| var sd = []; |
| var spd = []; |
| var dist = gd.length/dim; |
| var min, max, stretch, scale, shift; |
| var _smoothedData = []; |
| var _smoothedPlotData = []; |
| if (!isNaN(parseFloat(smooth))) { |
| steps = parseFloat(smooth); |
| } |
| else { |
| steps = getSteps(dist, 0.5); |
| } |
| if (!isNaN(parseFloat(tension))) { |
| tension = parseFloat(tension); |
| } |
|
|
| for (var i=0, l = gd.length-1; i < l; i++) { |
|
|
| if (tension === null) { |
| slope = Math.abs((gd[i+1][1] - gd[i][1]) / (gd[i+1][0] - gd[i][0])); |
|
|
| min = 0.3; |
| max = 0.6; |
| stretch = (max - min)/2.0; |
| scale = 2.5; |
| shift = -1.4; |
|
|
| temp = slope/scale + shift; |
|
|
| a1 = stretch * tanh(temp) - stretch * tanh(shift) + min; |
|
|
| |
| if (i > 0) { |
| slope2 = Math.abs((gd[i][1] - gd[i-1][1]) / (gd[i][0] - gd[i-1][0])); |
| } |
| temp = slope2/scale + shift; |
|
|
| a2 = stretch * tanh(temp) - stretch * tanh(shift) + min; |
|
|
| a = (a1 + a2)/2.0; |
|
|
| } |
| else { |
| a = tension; |
| } |
| for (t=0; t < steps; t++) { |
| s = t / steps; |
| h1 = (1 + 2*s)*Math.pow((1-s),2); |
| h2 = s*Math.pow((1-s),2); |
| h3 = Math.pow(s,2)*(3-2*s); |
| h4 = Math.pow(s,2)*(s-1); |
| |
| if (gd[i-1]) { |
| TiX = a * (gd[i+1][0] - gd[i-1][0]); |
| TiY = a * (gd[i+1][1] - gd[i-1][1]); |
| } else { |
| TiX = a * (gd[i+1][0] - gd[i][0]); |
| TiY = a * (gd[i+1][1] - gd[i][1]); |
| } |
| if (gd[i+2]) { |
| Ti1X = a * (gd[i+2][0] - gd[i][0]); |
| Ti1Y = a * (gd[i+2][1] - gd[i][1]); |
| } else { |
| Ti1X = a * (gd[i+1][0] - gd[i][0]); |
| Ti1Y = a * (gd[i+1][1] - gd[i][1]); |
| } |
| |
| pX = h1*gd[i][0] + h3*gd[i+1][0] + h2*TiX + h4*Ti1X; |
| pY = h1*gd[i][1] + h3*gd[i+1][1] + h2*TiY + h4*Ti1Y; |
| p = [pX, pY]; |
|
|
| _smoothedData.push(p); |
| _smoothedPlotData.push([xp(pX), yp(pY)]); |
| } |
| } |
| _smoothedData.push(gd[l]); |
| _smoothedPlotData.push([xp(gd[l][0]), yp(gd[l][1])]); |
|
|
| return [_smoothedData, _smoothedPlotData]; |
| } |
| |
| |
| |
| |
| |
| $.jqplot.LineRenderer.prototype.setGridData = function(plot) { |
| |
| var xp = this._xaxis.series_u2p; |
| var yp = this._yaxis.series_u2p; |
| var data = this._plotData; |
| var pdata = this._prevPlotData; |
| this.gridData = []; |
| this._prevGridData = []; |
| this.renderer._smoothedData = []; |
| this.renderer._smoothedPlotData = []; |
| this.renderer._hiBandGridData = []; |
| this.renderer._lowBandGridData = []; |
| this.renderer._hiBandSmoothedData = []; |
| this.renderer._lowBandSmoothedData = []; |
| var bands = this.renderer.bands; |
| var hasNull = false; |
| for (var i=0, l=data.length; i < l; i++) { |
| |
| if (data[i][0] != null && data[i][1] != null) { |
| this.gridData.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]); |
| } |
| |
| else if (data[i][0] == null) { |
| hasNull = true; |
| this.gridData.push([null, yp.call(this._yaxis, data[i][1])]); |
| } |
| else if (data[i][1] == null) { |
| hasNull = true; |
| this.gridData.push([xp.call(this._xaxis, data[i][0]), null]); |
| } |
| |
| if (pdata[i] != null && pdata[i][0] != null && pdata[i][1] != null) { |
| this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), yp.call(this._yaxis, pdata[i][1])]); |
| } |
| |
| else if (pdata[i] != null && pdata[i][0] == null) { |
| this._prevGridData.push([null, yp.call(this._yaxis, pdata[i][1])]); |
| } |
| else if (pdata[i] != null && pdata[i][0] != null && pdata[i][1] == null) { |
| this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), null]); |
| } |
| } |
|
|
| |
| if (hasNull) { |
| this.renderer.smooth = false; |
| if (this._type === 'line') { |
| bands.show = false; |
| } |
| } |
|
|
| if (this._type === 'line' && bands.show) { |
| for (var i=0, l=bands.hiData.length; i<l; i++) { |
| this.renderer._hiBandGridData.push([xp.call(this._xaxis, bands.hiData[i][0]), yp.call(this._yaxis, bands.hiData[i][1])]); |
| } |
| for (var i=0, l=bands.lowData.length; i<l; i++) { |
| this.renderer._lowBandGridData.push([xp.call(this._xaxis, bands.lowData[i][0]), yp.call(this._yaxis, bands.lowData[i][1])]); |
| } |
| } |
|
|
| |
| if (this._type === 'line' && this.renderer.smooth && this.gridData.length > 2) { |
| var ret; |
| if (this.renderer.constrainSmoothing) { |
| ret = computeConstrainedSmoothedData.call(this, this.gridData); |
| this.renderer._smoothedData = ret[0]; |
| this.renderer._smoothedPlotData = ret[1]; |
|
|
| if (bands.show) { |
| ret = computeConstrainedSmoothedData.call(this, this.renderer._hiBandGridData); |
| this.renderer._hiBandSmoothedData = ret[0]; |
| ret = computeConstrainedSmoothedData.call(this, this.renderer._lowBandGridData); |
| this.renderer._lowBandSmoothedData = ret[0]; |
| } |
|
|
| ret = null; |
| } |
| else { |
| ret = computeHermiteSmoothedData.call(this, this.gridData); |
| this.renderer._smoothedData = ret[0]; |
| this.renderer._smoothedPlotData = ret[1]; |
|
|
| if (bands.show) { |
| ret = computeHermiteSmoothedData.call(this, this.renderer._hiBandGridData); |
| this.renderer._hiBandSmoothedData = ret[0]; |
| ret = computeHermiteSmoothedData.call(this, this.renderer._lowBandGridData); |
| this.renderer._lowBandSmoothedData = ret[0]; |
| } |
|
|
| ret = null; |
| } |
| } |
| }; |
| |
| |
| |
| |
| |
| |
| |
| $.jqplot.LineRenderer.prototype.makeGridData = function(data, plot) { |
| |
| var xp = this._xaxis.series_u2p; |
| var yp = this._yaxis.series_u2p; |
| var gd = []; |
| var pgd = []; |
| this.renderer._smoothedData = []; |
| this.renderer._smoothedPlotData = []; |
| this.renderer._hiBandGridData = []; |
| this.renderer._lowBandGridData = []; |
| this.renderer._hiBandSmoothedData = []; |
| this.renderer._lowBandSmoothedData = []; |
| var bands = this.renderer.bands; |
| var hasNull = false; |
| for (var i=0; i<data.length; i++) { |
| |
| if (data[i][0] != null && data[i][1] != null) { |
| gd.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]); |
| } |
| |
| else if (data[i][0] == null) { |
| hasNull = true; |
| gd.push([null, yp.call(this._yaxis, data[i][1])]); |
| } |
| else if (data[i][1] == null) { |
| hasNull = true; |
| gd.push([xp.call(this._xaxis, data[i][0]), null]); |
| } |
| } |
|
|
| |
| if (hasNull) { |
| this.renderer.smooth = false; |
| if (this._type === 'line') { |
| bands.show = false; |
| } |
| } |
|
|
| if (this._type === 'line' && bands.show) { |
| for (var i=0, l=bands.hiData.length; i<l; i++) { |
| this.renderer._hiBandGridData.push([xp.call(this._xaxis, bands.hiData[i][0]), yp.call(this._yaxis, bands.hiData[i][1])]); |
| } |
| for (var i=0, l=bands.lowData.length; i<l; i++) { |
| this.renderer._lowBandGridData.push([xp.call(this._xaxis, bands.lowData[i][0]), yp.call(this._yaxis, bands.lowData[i][1])]); |
| } |
| } |
|
|
| if (this._type === 'line' && this.renderer.smooth && gd.length > 2) { |
| var ret; |
| if (this.renderer.constrainSmoothing) { |
| ret = computeConstrainedSmoothedData.call(this, gd); |
| this.renderer._smoothedData = ret[0]; |
| this.renderer._smoothedPlotData = ret[1]; |
|
|
| if (bands.show) { |
| ret = computeConstrainedSmoothedData.call(this, this.renderer._hiBandGridData); |
| this.renderer._hiBandSmoothedData = ret[0]; |
| ret = computeConstrainedSmoothedData.call(this, this.renderer._lowBandGridData); |
| this.renderer._lowBandSmoothedData = ret[0]; |
| } |
|
|
| ret = null; |
| } |
| else { |
| ret = computeHermiteSmoothedData.call(this, gd); |
| this.renderer._smoothedData = ret[0]; |
| this.renderer._smoothedPlotData = ret[1]; |
|
|
| if (bands.show) { |
| ret = computeHermiteSmoothedData.call(this, this.renderer._hiBandGridData); |
| this.renderer._hiBandSmoothedData = ret[0]; |
| ret = computeHermiteSmoothedData.call(this, this.renderer._lowBandGridData); |
| this.renderer._lowBandSmoothedData = ret[0]; |
| } |
|
|
| ret = null; |
| } |
| } |
| return gd; |
| }; |
| |
|
|
| |
| $.jqplot.LineRenderer.prototype.draw = function(ctx, gd, options, plot) { |
| var i; |
| |
| var opts = $.extend(true, {}, options); |
| var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; |
| var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; |
| var fill = (opts.fill != undefined) ? opts.fill : this.fill; |
| var fillAndStroke = (opts.fillAndStroke != undefined) ? opts.fillAndStroke : this.fillAndStroke; |
| var xmin, ymin, xmax, ymax; |
| ctx.save(); |
| if (gd.length) { |
| if (showLine) { |
| |
| if (fill) { |
| if (this.fillToZero) { |
| |
| var negativeColor = this.negativeColor; |
| if (! this.useNegativeColors) { |
| negativeColor = opts.fillStyle; |
| } |
| var isnegative = false; |
| var posfs = opts.fillStyle; |
| |
| |
| if (fillAndStroke) { |
| var fasgd = gd.slice(0); |
| } |
| |
| if (this.index == 0 || !this._stack) { |
| |
| var tempgd = []; |
| var pd = (this.renderer.smooth) ? this.renderer._smoothedPlotData : this._plotData; |
| this._areaPoints = []; |
| var pyzero = this._yaxis.series_u2p(this.fillToValue); |
| var pxzero = this._xaxis.series_u2p(this.fillToValue); |
|
|
| opts.closePath = true; |
| |
| if (this.fillAxis == 'y') { |
| tempgd.push([gd[0][0], pyzero]); |
| this._areaPoints.push([gd[0][0], pyzero]); |
| |
| for (var i=0; i<gd.length-1; i++) { |
| tempgd.push(gd[i]); |
| this._areaPoints.push(gd[i]); |
| |
| if (pd[i][1] * pd[i+1][1] <= 0) { |
| if (pd[i][1] < 0) { |
| isnegative = true; |
| opts.fillStyle = negativeColor; |
| } |
| else { |
| isnegative = false; |
| opts.fillStyle = posfs; |
| } |
| |
| var xintercept = gd[i][0] + (gd[i+1][0] - gd[i][0]) * (pyzero-gd[i][1])/(gd[i+1][1] - gd[i][1]); |
| tempgd.push([xintercept, pyzero]); |
| this._areaPoints.push([xintercept, pyzero]); |
| |
| if (shadow) { |
| this.renderer.shadowRenderer.draw(ctx, tempgd, opts); |
| } |
| this.renderer.shapeRenderer.draw(ctx, tempgd, opts); |
| |
| tempgd = [[xintercept, pyzero]]; |
| |
| } |
| } |
| if (pd[gd.length-1][1] < 0) { |
| isnegative = true; |
| opts.fillStyle = negativeColor; |
| } |
| else { |
| isnegative = false; |
| opts.fillStyle = posfs; |
| } |
| tempgd.push(gd[gd.length-1]); |
| this._areaPoints.push(gd[gd.length-1]); |
| tempgd.push([gd[gd.length-1][0], pyzero]); |
| this._areaPoints.push([gd[gd.length-1][0], pyzero]); |
| } |
| |
| if (shadow) { |
| this.renderer.shadowRenderer.draw(ctx, tempgd, opts); |
| } |
| this.renderer.shapeRenderer.draw(ctx, tempgd, opts); |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| else { |
| var prev = this._prevGridData; |
| for (var i=prev.length; i>0; i--) { |
| gd.push(prev[i-1]); |
| |
| } |
| if (shadow) { |
| this.renderer.shadowRenderer.draw(ctx, gd, opts); |
| } |
| this._areaPoints = gd; |
| this.renderer.shapeRenderer.draw(ctx, gd, opts); |
| } |
| } |
| |
| |
| |
| else { |
| |
| if (fillAndStroke) { |
| var fasgd = gd.slice(0); |
| } |
| |
| if (this.index == 0 || !this._stack) { |
| |
| var gridymin = ctx.canvas.height; |
| |
| gd.unshift([gd[0][0], gridymin]); |
| var len = gd.length; |
| gd.push([gd[len - 1][0], gridymin]); |
| } |
| |
| else { |
| var prev = this._prevGridData; |
| for (var i=prev.length; i>0; i--) { |
| gd.push(prev[i-1]); |
| } |
| } |
| this._areaPoints = gd; |
| |
| if (shadow) { |
| this.renderer.shadowRenderer.draw(ctx, gd, opts); |
| } |
| |
| this.renderer.shapeRenderer.draw(ctx, gd, opts); |
| } |
| if (fillAndStroke) { |
| var fasopts = $.extend(true, {}, opts, {fill:false, closePath:false}); |
| this.renderer.shapeRenderer.draw(ctx, fasgd, fasopts); |
| |
| |
| |
| |
| |
| |
| if (this.markerRenderer.show) { |
| if (this.renderer.smooth) { |
| fasgd = this.gridData; |
| } |
| for (i=0; i<fasgd.length; i++) { |
| this.markerRenderer.draw(fasgd[i][0], fasgd[i][1], ctx, opts.markerOptions); |
| } |
| } |
| } |
| } |
| else { |
|
|
| if (this.renderer.bands.show) { |
| var bdat; |
| var bopts = $.extend(true, {}, opts); |
| if (this.renderer.bands.showLines) { |
| bdat = (this.renderer.smooth) ? this.renderer._hiBandSmoothedData : this.renderer._hiBandGridData; |
| this.renderer.shapeRenderer.draw(ctx, bdat, opts); |
| bdat = (this.renderer.smooth) ? this.renderer._lowBandSmoothedData : this.renderer._lowBandGridData; |
| this.renderer.shapeRenderer.draw(ctx, bdat, bopts); |
| } |
|
|
| if (this.renderer.bands.fill) { |
| if (this.renderer.smooth) { |
| bdat = this.renderer._hiBandSmoothedData.concat(this.renderer._lowBandSmoothedData.reverse()); |
| } |
| else { |
| bdat = this.renderer._hiBandGridData.concat(this.renderer._lowBandGridData.reverse()); |
| } |
| this._areaPoints = bdat; |
| bopts.closePath = true; |
| bopts.fill = true; |
| bopts.fillStyle = this.renderer.bands.fillColor; |
| this.renderer.shapeRenderer.draw(ctx, bdat, bopts); |
| } |
| } |
|
|
| if (shadow) { |
| this.renderer.shadowRenderer.draw(ctx, gd, opts); |
| } |
| |
| this.renderer.shapeRenderer.draw(ctx, gd, opts); |
| } |
| } |
| |
| var xmin = xmax = ymin = ymax = null; |
| for (i=0; i<this._areaPoints.length; i++) { |
| var p = this._areaPoints[i]; |
| if (xmin > p[0] || xmin == null) { |
| xmin = p[0]; |
| } |
| if (ymax < p[1] || ymax == null) { |
| ymax = p[1]; |
| } |
| if (xmax < p[0] || xmax == null) { |
| xmax = p[0]; |
| } |
| if (ymin > p[1] || ymin == null) { |
| ymin = p[1]; |
| } |
| } |
|
|
| if (this.type === 'line' && this.renderer.bands.show) { |
| ymax = this._yaxis.series_u2p(this.renderer.bands._min); |
| ymin = this._yaxis.series_u2p(this.renderer.bands._max); |
| } |
|
|
| this._boundingBox = [[xmin, ymax], [xmax, ymin]]; |
| |
| |
| if (this.markerRenderer.show && !fill) { |
| if (this.renderer.smooth) { |
| gd = this.gridData; |
| } |
| for (i=0; i<gd.length; i++) { |
| if (gd[i][0] != null && gd[i][1] != null) { |
| this.markerRenderer.draw(gd[i][0], gd[i][1], ctx, opts.markerOptions); |
| } |
| } |
| } |
| } |
| |
| ctx.restore(); |
| }; |
| |
| $.jqplot.LineRenderer.prototype.drawShadow = function(ctx, gd, options) { |
| |
| }; |
| |
| |
| |
| function postInit(target, data, options) { |
| for (var i=0; i<this.series.length; i++) { |
| if (this.series[i].renderer.constructor == $.jqplot.LineRenderer) { |
| |
| if (this.series[i].highlightMouseOver) { |
| this.series[i].highlightMouseDown = false; |
| } |
| } |
| } |
| } |
| |
| |
| |
| |
| function postPlotDraw() { |
| |
| if (this.plugins.lineRenderer && this.plugins.lineRenderer.highlightCanvas) { |
| this.plugins.lineRenderer.highlightCanvas.resetCanvas(); |
| this.plugins.lineRenderer.highlightCanvas = null; |
| } |
| |
| this.plugins.lineRenderer.highlightedSeriesIndex = null; |
| this.plugins.lineRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); |
| |
| this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-lineRenderer-highlight-canvas', this._plotDimensions, this)); |
| this.plugins.lineRenderer.highlightCanvas.setContext(); |
| this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); |
| } |
| |
| function highlight (plot, sidx, pidx, points) { |
| var s = plot.series[sidx]; |
| var canvas = plot.plugins.lineRenderer.highlightCanvas; |
| canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); |
| s._highlightedPoint = pidx; |
| plot.plugins.lineRenderer.highlightedSeriesIndex = sidx; |
| var opts = {fillStyle: s.highlightColor}; |
| if (s.type === 'line' && s.renderer.bands.show) { |
| opts.fill = true; |
| opts.closePath = true; |
| } |
| s.renderer.shapeRenderer.draw(canvas._ctx, points, opts); |
| canvas = null; |
| } |
| |
| function unhighlight (plot) { |
| var canvas = plot.plugins.lineRenderer.highlightCanvas; |
| canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); |
| for (var i=0; i<plot.series.length; i++) { |
| plot.series[i]._highlightedPoint = null; |
| } |
| plot.plugins.lineRenderer.highlightedSeriesIndex = null; |
| plot.target.trigger('jqplotDataUnhighlight'); |
| canvas = null; |
| } |
| |
| |
| function handleMove(ev, gridpos, datapos, neighbor, plot) { |
| if (neighbor) { |
| var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
| var evt1 = jQuery.Event('jqplotDataMouseOver'); |
| evt1.pageX = ev.pageX; |
| evt1.pageY = ev.pageY; |
| plot.target.trigger(evt1, ins); |
| if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) { |
| var evt = jQuery.Event('jqplotDataHighlight'); |
| evt.which = ev.which; |
| evt.pageX = ev.pageX; |
| evt.pageY = ev.pageY; |
| plot.target.trigger(evt, ins); |
| highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); |
| } |
| } |
| else if (neighbor == null) { |
| unhighlight (plot); |
| } |
| } |
| |
| function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { |
| if (neighbor) { |
| var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
| if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) { |
| var evt = jQuery.Event('jqplotDataHighlight'); |
| evt.which = ev.which; |
| evt.pageX = ev.pageX; |
| evt.pageY = ev.pageY; |
| plot.target.trigger(evt, ins); |
| highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); |
| } |
| } |
| else if (neighbor == null) { |
| unhighlight (plot); |
| } |
| } |
| |
| function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { |
| var idx = plot.plugins.lineRenderer.highlightedSeriesIndex; |
| if (idx != null && plot.series[idx].highlightMouseDown) { |
| unhighlight(plot); |
| } |
| } |
| |
| function handleClick(ev, gridpos, datapos, neighbor, plot) { |
| if (neighbor) { |
| var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
| var evt = jQuery.Event('jqplotDataClick'); |
| evt.which = ev.which; |
| evt.pageX = ev.pageX; |
| evt.pageY = ev.pageY; |
| plot.target.trigger(evt, ins); |
| } |
| } |
| |
| function handleRightClick(ev, gridpos, datapos, neighbor, plot) { |
| if (neighbor) { |
| var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
| var idx = plot.plugins.lineRenderer.highlightedSeriesIndex; |
| if (idx != null && plot.series[idx].highlightMouseDown) { |
| unhighlight(plot); |
| } |
| var evt = jQuery.Event('jqplotDataRightClick'); |
| evt.which = ev.which; |
| evt.pageX = ev.pageX; |
| evt.pageY = ev.pageY; |
| plot.target.trigger(evt, ins); |
| } |
| } |
| |
| })(jQuery); |