From: Eric Nikolay Katz Date: Sun, 16 Apr 2017 20:13:13 +0000 (-0400) Subject: Enhancement: adds step-after functionality, true defaults to step-before (#4065) X-Git-Tag: v2.6.0~2^2~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=205cedc0efb5f1aa168f6236bc8a8f0f16529e67;p=thirdparty%2FChart.js.git Enhancement: adds step-after functionality, true defaults to step-before (#4065) * Adds step-after functionality, true defaults to step-before * Update stepped line sample to include all variations of steppedLine configurations * Update documentation on steppedLine values * Add tests for new steppedLine values 'before' and 'after' --- diff --git a/docs/charts/line.md b/docs/charts/line.md index 6a2783e62..f838bac0d 100644 --- a/docs/charts/line.md +++ b/docs/charts/line.md @@ -70,7 +70,7 @@ All point* properties can be specified as an array. If these are set to an array | `pointHoverRadius` | `Number/Number[]` | The radius of the point when hovered. | `showLine` | `Boolean` | If false, the line is not drawn for this dataset. | `spanGaps` | `Boolean` | If true, lines will be drawn between points with no or null data. If false, points with `NaN` data will create a break in the line -| `steppedLine` | `Boolean` | If true, the line is shown as a stepped line and 'lineTension' will be ignored. +| `steppedLine` | `Boolean/String` | If the line is shown as a stepped line. [more...](#stepped-line) ### cubicInterpolationMode The following interpolation modes are supported: @@ -106,6 +106,15 @@ The style of point. Options are: If the option is an image, that image is drawn on the canvas using [drawImage](https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/drawImage). +### Stepped Line +The following values are supported for `steppedLine`: +* `false`: No Step Interpolation (default) +* `true`: Step-before Interpolation (eq. 'before') +* `'before'`: Step-before Interpolation +* `'after'`: Step-after Interpolation + +If the `steppedLine` value is set to anything other than false, `lineTension` will be ignored. + ## Configuration Options The line chart defines the following configuration options. These options are merged with the global chart configuration options, `Chart.defaults.global`, to form the options passed to the chart. diff --git a/samples/charts/line/stepped.html b/samples/charts/line/stepped.html index 8650f55da..ccce87c2d 100644 --- a/samples/charts/line/stepped.html +++ b/samples/charts/line/stepped.html @@ -5,88 +5,98 @@ Stepped Line Chart - + -
- -
+
+
diff --git a/src/core/core.canvasHelpers.js b/src/core/core.canvasHelpers.js index fad37e3c0..7d420524a 100644 --- a/src/core/core.canvasHelpers.js +++ b/src/core/core.canvasHelpers.js @@ -123,7 +123,11 @@ module.exports = function(Chart) { helpers.lineTo = function(ctx, previous, target, flip) { if (target.steppedLine) { - ctx.lineTo(target.x, previous.y); + if (target.steppedLine === 'after') { + ctx.lineTo(previous.x, target.y); + } else { + ctx.lineTo(target.x, previous.y); + } ctx.lineTo(target.x, target.y); return; } diff --git a/test/specs/element.line.tests.js b/test/specs/element.line.tests.js index c4d1722b4..f9f351d7d 100644 --- a/test/specs/element.line.tests.js +++ b/test/specs/element.line.tests.js @@ -243,7 +243,141 @@ describe('Chart.elements.Line', function() { }]); }); - it('should draw stepped lines', function() { + it('should draw stepped lines, with "before" interpolation', function() { + + // Both `true` and `'before'` should draw the same steppedLine + var beforeInterpolations = [true, 'before']; + + beforeInterpolations.forEach(function(mode) { + var mockContext = window.createMockContext(); + + // Create our points + var points = []; + points.push(new Chart.elements.Point({ + _datasetindex: 2, + _index: 0, + _view: { + x: 0, + y: 10, + controlPointNextX: 0, + controlPointNextY: 10, + steppedLine: mode + } + })); + points.push(new Chart.elements.Point({ + _datasetindex: 2, + _index: 1, + _view: { + x: 5, + y: 0, + controlPointPreviousX: 5, + controlPointPreviousY: 0, + controlPointNextX: 5, + controlPointNextY: 0, + steppedLine: mode + } + })); + points.push(new Chart.elements.Point({ + _datasetindex: 2, + _index: 2, + _view: { + x: 15, + y: -10, + controlPointPreviousX: 15, + controlPointPreviousY: -10, + controlPointNextX: 15, + controlPointNextY: -10, + steppedLine: mode + } + })); + points.push(new Chart.elements.Point({ + _datasetindex: 2, + _index: 3, + _view: { + x: 19, + y: -5, + controlPointPreviousX: 19, + controlPointPreviousY: -5, + controlPointNextX: 19, + controlPointNextY: -5, + steppedLine: mode + } + })); + + var line = new Chart.elements.Line({ + _datasetindex: 2, + _chart: { + ctx: mockContext, + }, + _children: points, + // Need to provide some settings + _view: { + fill: false, // don't want to fill + tension: 0, // no bezier curve for now + } + }); + + line.draw(); + + expect(mockContext.getCalls()).toEqual([{ + name: 'save', + args: [], + }, { + name: 'setLineCap', + args: ['butt'] + }, { + name: 'setLineDash', + args: [ + [] + ] + }, { + name: 'setLineDashOffset', + args: [0.0] + }, { + name: 'setLineJoin', + args: ['miter'] + }, { + name: 'setLineWidth', + args: [3] + }, { + name: 'setStrokeStyle', + args: ['rgba(0,0,0,0.1)'] + }, { + name: 'beginPath', + args: [] + }, { + name: 'moveTo', + args: [0, 10] + }, { + name: 'lineTo', + args: [5, 10] + }, { + name: 'lineTo', + args: [5, 0] + }, { + name: 'lineTo', + args: [15, 0] + }, { + name: 'lineTo', + args: [15, -10] + }, { + name: 'lineTo', + args: [19, -10] + }, { + name: 'lineTo', + args: [19, -5] + }, { + name: 'stroke', + args: [], + }, { + name: 'restore', + args: [] + }]); + }); + }); + + it('should draw stepped lines, with "after" interpolation', function() { + var mockContext = window.createMockContext(); // Create our points @@ -256,7 +390,7 @@ describe('Chart.elements.Line', function() { y: 10, controlPointNextX: 0, controlPointNextY: 10, - steppedLine: true + steppedLine: 'after' } })); points.push(new Chart.elements.Point({ @@ -269,7 +403,7 @@ describe('Chart.elements.Line', function() { controlPointPreviousY: 0, controlPointNextX: 5, controlPointNextY: 0, - steppedLine: true + steppedLine: 'after' } })); points.push(new Chart.elements.Point({ @@ -282,7 +416,7 @@ describe('Chart.elements.Line', function() { controlPointPreviousY: -10, controlPointNextX: 15, controlPointNextY: -10, - steppedLine: true + steppedLine: 'after' } })); points.push(new Chart.elements.Point({ @@ -295,7 +429,7 @@ describe('Chart.elements.Line', function() { controlPointPreviousY: -5, controlPointNextX: 19, controlPointNextY: -5, - steppedLine: true + steppedLine: 'after' } })); @@ -345,19 +479,19 @@ describe('Chart.elements.Line', function() { args: [0, 10] }, { name: 'lineTo', - args: [5, 10] + args: [0, 0] }, { name: 'lineTo', args: [5, 0] }, { name: 'lineTo', - args: [15, 0] + args: [5, -10] }, { name: 'lineTo', args: [15, -10] }, { name: 'lineTo', - args: [19, -10] + args: [15, -5] }, { name: 'lineTo', args: [19, -5]