X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=src%2Fdygraph-canvas.js;h=7377239857f40561c26931f771dcd8a0efbf47ec;hb=aec24511f59ace8681d28cb5d11d04f9f57357b4;hp=a688c43975958639e973715cdcbc5727b18712c9;hpb=3123ca57f71d145bb5bcc4a2f754d3dff3225346;p=dygraphs.git diff --git a/src/dygraph-canvas.js b/src/dygraph-canvas.js index a688c43..7377239 100644 --- a/src/dygraph-canvas.js +++ b/src/dygraph-canvas.js @@ -24,10 +24,12 @@ * @constructor */ -var DygraphCanvasRenderer = (function() { /*global Dygraph:false */ "use strict"; +import * as utils from './dygraph-utils'; +import Dygraph from './dygraph'; + /** * @constructor @@ -57,7 +59,7 @@ var DygraphCanvasRenderer = function(dygraph, element, elementContext, layout) { this.width = dygraph.width_; // --- check whether everything is ok before we return - if (!Dygraph.isCanvasSupported(this.element)) { + if (!utils.isCanvasSupported(this.element)) { throw "Canvas is not supported."; } @@ -66,19 +68,15 @@ var DygraphCanvasRenderer = function(dygraph, element, elementContext, layout) { // Set up a clipping area for the canvas (and the interaction canvas). // This ensures that we don't overdraw. - // on Android 3 and 4, setting a clipping area on a canvas prevents it from - // displaying anything. - if (!Dygraph.isAndroid()) { - var ctx = this.dygraph_.canvas_ctx_; - ctx.beginPath(); - ctx.rect(this.area.x, this.area.y, this.area.w, this.area.h); - ctx.clip(); + var ctx = this.dygraph_.canvas_ctx_; + ctx.beginPath(); + ctx.rect(this.area.x, this.area.y, this.area.w, this.area.h); + ctx.clip(); - ctx = this.dygraph_.hidden_ctx_; - ctx.beginPath(); - ctx.rect(this.area.x, this.area.y, this.area.w, this.area.h); - ctx.clip(); - } + ctx = this.dygraph_.hidden_ctx_; + ctx.beginPath(); + ctx.rect(this.area.x, this.area.y, this.area.w, this.area.h); + ctx.clip(); }; /** @@ -135,7 +133,7 @@ DygraphCanvasRenderer._drawStyledLine = function(e, // TODO(konigsberg): Compute attributes outside this method call. var stepPlot = g.getBooleanOption("stepPlot", e.setName); - if (!Dygraph.isArrayLike(strokePattern)) { + if (!utils.isArrayLike(strokePattern)) { strokePattern = null; } @@ -143,7 +141,7 @@ DygraphCanvasRenderer._drawStyledLine = function(e, var points = e.points; var setName = e.setName; - var iter = Dygraph.createIterator(points, 0, points.length, + var iter = utils.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate( g.getBooleanOption("connectSeparatedPoints", setName))); @@ -152,7 +150,7 @@ DygraphCanvasRenderer._drawStyledLine = function(e, var ctx = e.drawingContext; ctx.save(); if (stroking) { - ctx.installPattern(strokePattern); + if (ctx.setLineDash) ctx.setLineDash(strokePattern); } var pointsOnLine = DygraphCanvasRenderer._drawSeries( @@ -161,7 +159,7 @@ DygraphCanvasRenderer._drawStyledLine = function(e, e, pointsOnLine, drawPointCallback, color, pointSize); if (stroking) { - ctx.uninstallPattern(); + if (ctx.setLineDash) ctx.setLineDash([]); } ctx.restore(); @@ -218,18 +216,18 @@ DygraphCanvasRenderer._drawSeries = function(e, prevCanvasX = prevCanvasY = null; } else { isIsolated = false; - if (drawGapPoints || !prevCanvasX) { + if (drawGapPoints || prevCanvasX === null) { iter.nextIdx_ = i; iter.next(); nextCanvasY = iter.hasNext ? iter.peek.canvasy : null; var isNextCanvasYNullOrNaN = nextCanvasY === null || nextCanvasY != nextCanvasY; - isIsolated = (!prevCanvasX && isNextCanvasYNullOrNaN); + isIsolated = (prevCanvasX === null && isNextCanvasYNullOrNaN); if (drawGapPoints) { // Also consider a point to be "isolated" if it's adjacent to a // null point, excluding the graph edges. - if ((!first && !prevCanvasX) || + if ((!first && prevCanvasX === null) || (iter.hasNext && isNextCanvasYNullOrNaN)) { isIsolated = true; } @@ -334,7 +332,7 @@ DygraphCanvasRenderer.prototype._renderLineChart = function(opt_seriesName, opt_ // Determine which series have specialized plotters. var plotter_attr = this.dygraph_.getOption("plotter"); var plotters = plotter_attr; - if (!Dygraph.isArrayLike(plotters)) { + if (!utils.isArrayLike(plotters)) { plotters = [plotters]; } @@ -425,7 +423,7 @@ DygraphCanvasRenderer._linePlotter = function(e) { // this code a bit nasty. var borderWidth = g.getNumericOption("strokeBorderWidth", setName); var drawPointCallback = g.getOption("drawPointCallback", setName) || - Dygraph.Circles.DEFAULT; + utils.Circles.DEFAULT; var strokePattern = g.getOption("strokePattern", setName); var drawPoints = g.getBooleanOption("drawPoints", setName); var pointSize = g.getNumericOption("pointSize", setName); @@ -475,7 +473,7 @@ DygraphCanvasRenderer._errorPlotter = function(e) { var stepPlot = g.getBooleanOption("stepPlot", setName); var points = e.points; - var iter = Dygraph.createIterator(points, 0, points.length, + var iter = utils.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate( g.getBooleanOption("connectSeparatedPoints", setName))); @@ -486,7 +484,7 @@ DygraphCanvasRenderer._errorPlotter = function(e) { var prevY = NaN; var prevYs = [-1, -1]; // should be same color as the lines but only 15% opaque. - var rgb = Dygraph.toRGB_(color); + var rgb = utils.toRGB_(color); var err_color = 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')'; ctx.fillStyle = err_color; @@ -542,12 +540,13 @@ DygraphCanvasRenderer._errorPlotter = function(e) { * Proxy for CanvasRenderingContext2D which drops moveTo/lineTo calls which are * superfluous. It accumulates all movements which haven't changed the x-value * and only applies the two with the most extreme y-values. - * + * * Calls to lineTo/moveTo must have non-decreasing x-values. */ DygraphCanvasRenderer._fastCanvasProxy = function(context) { var pendingActions = []; // array of [type, x, y] tuples var lastRoundedX = null; + var lastFlushedX = null; var LINE_TO = 1, MOVE_TO = 2; @@ -626,6 +625,9 @@ DygraphCanvasRenderer._fastCanvasProxy = function(context) { context.moveTo(action[1], action[2]); } } + if (pendingActions.length) { + lastFlushedX = pendingActions[pendingActions.length - 1][1]; + } actionCount += pendingActions.length; pendingActions = []; }; @@ -633,7 +635,12 @@ DygraphCanvasRenderer._fastCanvasProxy = function(context) { var addAction = function(action, x, y) { var rx = Math.round(x); if (lastRoundedX === null || rx != lastRoundedX) { - flushActions(); + // if there are large gaps on the x-axis, it's essential to keep the + // first and last point as well. + var hasGapOnLeft = (lastRoundedX - lastFlushedX > 1), + hasGapOnRight = (rx - lastRoundedX > 1), + hasGap = hasGapOnLeft || hasGapOnRight; + flushActions(hasGap); lastRoundedX = rx; } pendingActions.push([action, x, y]); @@ -698,7 +705,6 @@ DygraphCanvasRenderer._fillPlotter = function(e) { var sets = e.allSeriesPoints; var setCount = sets.length; - var fillAlpha = g.getNumericOption('fillAlpha'); var stackedGraph = g.getBooleanOption("stackedGraph"); var colors = g.getColors(); @@ -730,6 +736,7 @@ DygraphCanvasRenderer._fillPlotter = function(e) { var setName = setNames[setIdx]; if (!g.getBooleanOption('fillGraph', setName)) continue; + var fillAlpha = g.getNumericOption('fillAlpha', setName); var stepPlot = g.getBooleanOption('stepPlot', setName); var color = colors[setIdx]; var axis = g.axisPropertiesForSeries(setName); @@ -739,7 +746,7 @@ DygraphCanvasRenderer._fillPlotter = function(e) { axisY = area.h * axisY + area.y; var points = sets[setIdx]; - var iter = Dygraph.createIterator(points, 0, points.length, + var iter = utils.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate( g.getBooleanOption("connectSeparatedPoints", setName))); @@ -748,7 +755,7 @@ DygraphCanvasRenderer._fillPlotter = function(e) { var prevYs = [-1, -1]; var newYs; // should be same color as the lines but only 15% opaque. - var rgb = Dygraph.toRGB_(color); + var rgb = utils.toRGB_(color); var err_color = 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')'; ctx.fillStyle = err_color; @@ -757,7 +764,7 @@ DygraphCanvasRenderer._fillPlotter = function(e) { // If the point density is high enough, dropping segments on their way to // the canvas justifies the overhead of doing so. - if (points.length > 2 * g.width_) { + if (points.length > 2 * g.width_ || Dygraph.FORCE_FAST_PROXY) { ctx = DygraphCanvasRenderer._fastCanvasProxy(ctx); } @@ -773,7 +780,7 @@ DygraphCanvasRenderer._fillPlotter = function(e) { var point; while (iter.hasNext) { point = iter.next(); - if (!Dygraph.isOK(point.y) && !stepPlot) { + if (!utils.isOK(point.y) && !stepPlot) { traceBackPath(ctx, prevX, prevYs[1], pathBack); pathBack = []; prevX = NaN; @@ -857,6 +864,4 @@ DygraphCanvasRenderer._fillPlotter = function(e) { } }; -return DygraphCanvasRenderer; - -})(); +export default DygraphCanvasRenderer;