X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=dygraph-canvas.js;h=825a4c29c59385c7e0cb1ad238601cb262613855;hb=3f55b813316f73082795fe52f6cf26e9f1592f12;hp=f8167a706efda831a295d89eca45bac098fc69a2;hpb=537fe03a3ae53a0a9deb81d23fcca494bcc7691f;p=dygraphs.git diff --git a/dygraph-canvas.js b/dygraph-canvas.js index f8167a7..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,15 +303,19 @@ DygraphCanvasRenderer.prototype._drawSeries = function( ctx.strokeStyle = color; ctx.lineWidth = strokeWidth; - for (var i = iter.start_; i < iter.end_; i++) { - // while (iter.hasNext) { - 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) { @@ -327,18 +328,10 @@ DygraphCanvasRenderer.prototype._drawSeries = function( } else { isIsolated = false; if (drawGapPoints || !prevCanvasX) { - // nextCanvasY = iter.hasNext ? iter.peek.canvasy : null; - // var next_i = i + 1; - // while (next_i < iter.end_ && (!iter.predicate_ || !iter.predicate_(iter.array_, next_i))) { - // next_i++; - // } iter.nextIdx_ = i; var peek = iter.next(); nextCanvasY = iter.hasNext ? iter.peek.canvasy : null; - // nextCanvasY = next_i < iter.end_ ? iter.array_[next_i].canvasy : null; - // TODO: we calculate isNullOrNaN for this point, and the next, and then, - // when we iterate, test for isNullOrNaN again. Why bother? var isNextCanvasYNullOrNaN = nextCanvasY === null || nextCanvasY != nextCanvasY; isIsolated = (!prevCanvasX && isNextCanvasYNullOrNaN); @@ -359,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); } @@ -424,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. @@ -470,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"))); @@ -500,7 +502,6 @@ DygraphCanvasRenderer.prototype.drawErrorBars_ = function(points) { continue; } - // TODO(danvk): here if (stepPlot) { newYs = [ point.y_bottom, point.y_top ]; prevY = point.y; @@ -549,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")));