['moveTo', 3, 0]], extractMoveToAndLineToCalls(htx));
});
+
+// For a more visual version of this test, see
+// https://gist.github.com/danvk/e98dbb24253c9b153696
+// The drawing commands in the following two tests are taken from there.
+it('should handle gaps on the left', function() {
+ var htx = new Proxy(fakeCanvasContext);
+ var fastProxy = DygraphCanvasRenderer._fastCanvasProxy(htx);
+
+ fastProxy.moveTo(0, 320);
+ fastProxy.lineTo(0, 320);
+ fastProxy.lineTo(53.21, 187);
+ fastProxy.lineTo(53.23, 29);
+ fastProxy.lineTo(53.41, 320);
+ fastProxy.lineTo(54.15, 320);
+ fastProxy.lineTo(475, 320);
+ fastProxy.lineTo(475, 320);
+ fastProxy.fill();
+
+ assert.deepEqual([
+ ['moveTo', 0, 320],
+ ['lineTo', 0, 320],
+ ['lineTo', 53.21, 187],
+ ['lineTo', 53.23, 29],
+ ['lineTo', 53.41, 320],
+ ['lineTo', 54.15, 320],
+ ['lineTo', 475, 320],
+ ['lineTo', 475, 320]
+ ], extractMoveToAndLineToCalls(htx));
+});
+
+it('should handle gaps on the right', function() {
+ var htx = new Proxy(fakeCanvasContext);
+ var fastProxy = DygraphCanvasRenderer._fastCanvasProxy(htx);
+ fastProxy.moveTo(240.2, 320);
+ fastProxy.lineTo(240.2, 320);
+ fastProxy.lineTo(240.2, 174);
+ fastProxy.lineTo(240.7, 145);
+ fastProxy.lineTo(240.8, 320);
+ fastProxy.lineTo(241.3, 29);
+ fastProxy.lineTo(241.4, 320);
+ fastProxy.lineTo(715.9, 320);
+ fastProxy.lineTo(715.9, 320);
+ fastProxy.fill();
+
+ assert.deepEqual([
+ ['moveTo', 240.2, 320],
+ ['lineTo', 240.2, 320],
+ ['lineTo', 240.2, 174],
+ ['lineTo', 240.7, 145],
+ ['lineTo', 240.8, 320],
+ ['lineTo', 241.3, 29],
+ ['lineTo', 241.4, 320],
+ ['lineTo', 715.9, 320],
+ ['lineTo', 715.9, 320]
+ ], extractMoveToAndLineToCalls(htx));
+});
+
});
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;
context.moveTo(action[1], action[2]);
}
}
+ if (pendingActions.length) {
+ lastFlushedX = pendingActions[pendingActions.length - 1][1];
+ }
actionCount += pendingActions.length;
pendingActions = [];
};
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]);
// 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);
}