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]