]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Enhancement: adds step-after functionality, true defaults to step-before (#4065)
authorEric Nikolay Katz <admin@ericnkatz.com>
Sun, 16 Apr 2017 20:13:13 +0000 (16:13 -0400)
committerEvert Timberg <evert.timberg+github@gmail.com>
Sun, 16 Apr 2017 20:13:13 +0000 (16:13 -0400)
* 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'

docs/charts/line.md
samples/charts/line/stepped.html
src/core/core.canvasHelpers.js
test/specs/element.line.tests.js

index 6a2783e622307fe989d708b9969c18da9d815883..f838bac0dd2e37d7d65f623a1a4082ec693219b6 100644 (file)
@@ -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.
index 8650f55da15190ccb2470007c04911a5915f03f6..ccce87c2dcf1431111de5a4695b28ee29e696978 100644 (file)
@@ -5,88 +5,98 @@
     <title>Stepped Line Chart</title>
     <script src="../../../dist/Chart.bundle.js"></script>
     <script src="../../utils.js"></script>
-    <style>
-    canvas{
-        -moz-user-select: none;
-        -webkit-user-select: none;
-        -ms-user-select: none;
-    }
-    </style>
+       <style>
+       canvas {
+               -moz-user-select: none;
+               -webkit-user-select: none;
+               -ms-user-select: none;
+       }
+       .chart-container {
+               width: 500px;
+               margin-left: 40px;
+               margin-right: 40px;
+               margin-bottom: 40px;
+       }
+       .container {
+               display: flex;
+               flex-direction: row;
+               flex-wrap: wrap;
+               justify-content: center;
+       }
+       </style>
 </head>
 
 <body>
-    <div style="width:75%;">
-        <canvas id="canvas"></canvas>
-    </div>
+       <div class="container">
+       </div>
     <script>
-        var config = {
-            type: 'line',
-            data: {
-                labels: ["January", "February", "March", "April", "May", "June", "July"],
-                datasets: [{
-                    label: "My First dataset",
-                    borderColor: window.chartColors.red,
-                    backgroundColor: window.chartColors.red,
-                    data: [
-                        randomScalingFactor(),
-                        randomScalingFactor(),
-                        randomScalingFactor(),
-                        randomScalingFactor(),
-                        randomScalingFactor(),
-                        randomScalingFactor(),
-                        randomScalingFactor()
-                    ],
-                    fill: false,
-                    steppedLine: true,
-                }, {
-                    label: "My Second dataset",
-                    steppedLine: true,
-                    borderColor: window.chartColors.blue,
-                    backgroundColor: window.chartColors.blue,
-                    data: [
-                        randomScalingFactor(),
-                        randomScalingFactor(),
-                        randomScalingFactor(),
-                        randomScalingFactor(),
-                        randomScalingFactor(),
-                        randomScalingFactor(),
-                        randomScalingFactor()
-                    ],
-                    fill: false,
-                }]
-            },
-            options: {
-                responsive: true,
-                title:{
-                    display:true,
-                    text:'Chart.js Line Chart'
-                },
-                tooltips: {
-                    mode: 'index',
-                },
-                scales: {
-                    xAxes: [{
-                        display: true,
-                        scaleLabel: {
-                            display: true,
-                            labelString: 'Month'
-                        }
-                    }],
-                    yAxes: [{
-                        display: true,
-                        scaleLabel: {
-                            display: true,
-                            labelString: 'Value'
-                        },
-                    }]
-                }
-            }
-        };
+       function createConfig(details, data) {
+               return {
+                       type: 'line',
+                       data: {
+                               labels: ['Day 1', 'Day 2', 'Day 3', 'Day 4', 'Day 5', 'Day 6'],
+                               datasets: [{
+                                       label: 'steppedLine: ' + ((typeof(details.steppedLine) === 'boolean') ? details.steppedLine : `'${details.steppedLine}'`),
+                                       steppedLine: details.steppedLine,
+                                       data: data,
+                                       borderColor: details.color,
+                                       fill: false,
+                               }]
+                       },
+                       options: {
+                               responsive: true,
+                               title: {
+                                       display: true,
+                                       text: details.label,
+                               }
+                       }
+               };
+       }
 
-        window.onload = function() {
-            var ctx = document.getElementById("canvas").getContext("2d");
-            window.myLine = new Chart(ctx, config);
-        };
+
+       window.onload = function() {
+               var container = document.querySelector('.container');
+
+               var data = [
+                       randomScalingFactor(),
+                       randomScalingFactor(),
+                       randomScalingFactor(),
+                       randomScalingFactor(),
+                       randomScalingFactor(),
+                       randomScalingFactor()
+               ];
+
+               var steppedLineSettings = [{
+                       steppedLine: false,
+                       label: 'No Step Interpolation',
+                       color: window.chartColors.red
+               }, {
+                       steppedLine: true,
+                       label: 'Step Before Interpolation',
+                       color: window.chartColors.green
+               }, {
+                       steppedLine: 'before',
+                       label: 'Step Before Interpolation',
+                       color: window.chartColors.green
+               }, {
+                       steppedLine: 'after',
+                       label: 'Step After Interpolation',
+                       color: window.chartColors.purple
+               }];
+
+               steppedLineSettings.forEach(function(details) {
+                       var div = document.createElement('div');
+                       div.classList.add('chart-container');
+
+                       var canvas = document.createElement('canvas');
+                       div.appendChild(canvas);
+                       container.appendChild(div);
+
+                       var ctx = canvas.getContext('2d');
+                       var config = createConfig(details, data);
+                       new Chart(ctx, config);
+               });
+       };
     </script>
 </body>
 
index fad37e3c0f0ddac4abf7d2a44c304c5c4c177918..7d420524a8d8fc87b7c356ce221ca93b7821522b 100644 (file)
@@ -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;
                }
index c4d1722b4ad84a6447611741bb9192b05f09f1bd..f9f351d7db6139ed9368e339e03b185ccc66549c 100644 (file)
@@ -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]