X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=dygraph-canvas.js;h=825a4c29c59385c7e0cb1ad238601cb262613855;hb=f34f95d1f2fe3adcc0bbe578368740afba513d9f;hp=720ab80b0f674bfe8ae53562492350c4ee1dcaab;hpb=c06d8ec4ed15aeaf6bc2be27542972d73b9c0680;p=dygraphs.git diff --git a/dygraph-canvas.js b/dygraph-canvas.js index 720ab80..825a4c2 100644 --- a/dygraph-canvas.js +++ b/dygraph-canvas.js @@ -243,23 +243,20 @@ DygraphCanvasRenderer._predicateThatSkipsEmptyPoints = }; /** - * * @private */ DygraphCanvasRenderer.prototype._drawStyledLine = function( - ctx, i, setName, color, strokeWidth, strokePattern, drawPoints, + ctx, setIdx, setName, color, strokeWidth, strokePattern, drawPoints, drawPointCallback, pointSize) { // TODO(konigsberg): Compute attributes outside this method call. var stepPlot = this.attr_("stepPlot"); - var firstIndexInSet = this.layout.setPointsOffsets[i]; - var setLength = this.layout.setPointsLengths[i]; - var points = this.layout.points; if (!Dygraph.isArrayLike(strokePattern)) { strokePattern = null; } var drawGapPoints = this.dygraph_.attr_('drawGapEdgePoints', setName); - var iter = Dygraph.createIterator(points, firstIndexInSet, setLength, + var points = this.layout.points[setIdx]; + var iter = Dygraph.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate( this.attr_("connectSeparatedPoints"))); @@ -306,14 +303,19 @@ DygraphCanvasRenderer.prototype._drawSeries = function( ctx.strokeStyle = color; ctx.lineWidth = strokeWidth; - for (var i = iter.start_; i < iter.end_; i++) { - point = iter.array_[i]; - if (iter.predicate_) { - while (i < iter.end_ && !iter.predicate_(iter.array_, i)) { + // NOTE: we break the iterator's encapsulation here for about a 25% speedup. + var arr = iter.array_; + var limit = iter.end_; + var predicate = iter.predicate_; + + for (var i = iter.start_; i < limit; i++) { + point = arr[i]; + if (predicate) { + while (i < limit && !predicate(arr, i)) { i++; } - if (i == iter.end_) break; - point = iter.array_[i]; + if (i == limit) break; + point = arr[i]; } if (point.canvasy === null || point.canvasy != point.canvasy) { @@ -350,6 +352,8 @@ DygraphCanvasRenderer.prototype._drawSeries = function( ctx.lineTo(point.canvasx, prevCanvasY); prevCanvasX = point.canvasx; } + + // TODO(danvk): this moveTo is rarely necessary ctx.moveTo(prevCanvasX, prevCanvasY); ctx.lineTo(point.canvasx, point.canvasy); } @@ -415,11 +419,20 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() { // TODO(bhs): this loop is a hot-spot for high-point-count charts. These // transformations can be pushed into the canvas via linear transformation // matrices. - var points = this.layout.points; - for (i = points.length; i--;) { - var point = points[i]; - point.canvasx = this.area.w * point.x + this.area.x; - point.canvasy = this.area.h * point.y + this.area.y; + // NOTE(danvk): this is trickier than it sounds at first. The transformation + // needs to be done before the .moveTo() and .lineTo() calls, but must be + // undone before the .stroke() call to ensure that the stroke width is + // unaffected. An alternative is to reduce the stroke width in the + // transformed coordinate space, but you can't specify different values for + // each dimension (as you can with .scale()). The speedup here is ~12%. + var sets = this.layout.points; + for (i = sets.length; i--;) { + var points = sets[i]; + for (var j = points.length; j--;) { + var point = points[j]; + point.canvasx = this.area.w * point.x + this.area.x; + point.canvasy = this.area.h * point.y + this.area.y; + } } // Draw any "fills", i.e. error bars or the filled area under a series. @@ -461,15 +474,13 @@ DygraphCanvasRenderer.prototype.drawErrorBars_ = function(points) { var newYs; - for (var i = 0; i < setCount; i++) { - var setName = setNames[i]; + for (var setIdx = 0; setIdx < setCount; setIdx++) { + var setName = setNames[setIdx]; var axis = this.dygraph_.axisPropertiesForSeries(setName); var color = this.colors[setName]; - var firstIndexInSet = this.layout.setPointsOffsets[i]; - var setLength = this.layout.setPointsLengths[i]; - - var iter = Dygraph.createIterator(points, firstIndexInSet, setLength, + var points = this.layout.points[setIdx]; + var iter = Dygraph.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate( this.attr_("connectSeparatedPoints"))); @@ -491,7 +502,6 @@ DygraphCanvasRenderer.prototype.drawErrorBars_ = function(points) { continue; } - // TODO(danvk): here if (stepPlot) { newYs = [ point.y_bottom, point.y_top ]; prevY = point.y; @@ -540,18 +550,17 @@ DygraphCanvasRenderer.prototype.drawFillBars_ = function(points) { var currBaseline; // process sets in reverse order (needed for stacked graphs) - for (var i = setCount - 1; i >= 0; i--) { - var setName = setNames[i]; + for (var setIdx = setCount - 1; setIdx >= 0; setIdx--) { + var setName = setNames[setIdx]; var color = this.colors[setName]; var axis = this.dygraph_.axisPropertiesForSeries(setName); var axisY = 1.0 + axis.minyval * axis.yscale; if (axisY < 0.0) axisY = 0.0; else if (axisY > 1.0) axisY = 1.0; axisY = this.area.h * axisY + this.area.y; - var firstIndexInSet = this.layout.setPointsOffsets[i]; - var setLength = this.layout.setPointsLengths[i]; - var iter = Dygraph.createIterator(points, firstIndexInSet, setLength, + var points = this.layout.points[setIdx]; + var iter = Dygraph.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate( this.attr_("connectSeparatedPoints")));