]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Can now skip in all cases (start, mid, end) whether or not there is a look
authorEvert Timberg <evert.timberg@gmail.com>
Sun, 15 Nov 2015 16:16:41 +0000 (11:16 -0500)
committerEvert Timberg <evert.timberg@gmail.com>
Sun, 15 Nov 2015 16:16:41 +0000 (11:16 -0500)
src/elements/element.line.js
test/element.line.tests.js

index dc1f1d635a527fd3e0bac55e6066b88d5be9bd8d..00ae696cf1e1c321822ccea4430a07f5e8354c68 100644 (file)
@@ -29,7 +29,6 @@
                fill: true, // do we fill in the area between the line and its base axis
        };
 
-
        Chart.elements.Line = Chart.Element.extend({
                lineToNextPoint: function(previousPoint, point, nextPoint, skipHandler, previousSkipHandler) {
                        var ctx = this._chart.ctx;
@@ -59,8 +58,8 @@
                        var first = this._children[0];
                        var last = this._children[this._children.length - 1];
 
-                       function loopBackToStart() {
-                               if (!first._view.skip) {
+                       function loopBackToStart(drawLineToCenter) {
+                               if (!first._view.skip && !last._view.skip) {
                                        // Draw a bezier line from last to first
                                        ctx.bezierCurveTo(
                                                last._view.controlPointNextX,
@@ -70,7 +69,7 @@
                                                first._view.x,
                                                first._view.y
                                        );
-                               } else {
+                               } else if (drawLineToCenter) {
                                        // Go to center
                                        ctx.lineTo(_this._view.scaleZero.x, _this._view.scaleZero.y);
                                }
                                ctx.beginPath();
 
                                helpers.each(this._children, function(point, index) {
-                                       var previous = helpers.previousItem(this._children, index/*, this._loop*/);
-                                       var next = helpers.nextItem(this._children, index/*, this._loop*/);
+                                       var previous = helpers.previousItem(this._children, index);
+                                       var next = helpers.nextItem(this._children, index);
 
                                        // First point moves to it's starting position no matter what
                                        if (index === 0) {
-                                               ctx.moveTo(point._view.x, vm.scaleZero);
-                                               ctx.lineTo(point._view.x, point._view.y);
+                                               if (this._loop) {
+                                                       ctx.moveTo(vm.scaleZero.x, vm.scaleZero.y);
+                                               } else {
+                                                       ctx.moveTo(point._view.x, vm.scaleZero);
+                                               }
+
+                                               if (point._view.skip) {
+                                                       if (!this._loop) {
+                                                               ctx.moveTo(next._view.x, this._view.scaleZero);
+                                                       }
+                                               } else {
+                                                       ctx.lineTo(point._view.x, point._view.y);
+                                               }
                                        } else {
                                                this.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {
-                                                       if (this.loop) {
+                                                       if (this._loop) {
                                                                // Go to center
                                                                ctx.lineTo(this._view.scaleZero.x, this._view.scaleZero.y);
                                                        } else {
 
                                // For radial scales, loop back around to the first point
                                if (this._loop) {
-                                       loopBackToStart();
+                                       loopBackToStart(true);
                                } else {
                                        //Round off the line by going to the base of the chart, back to the start, then fill.
                                        ctx.lineTo(this._children[this._children.length - 1]._view.x, vm.scaleZero);
                                        ctx.moveTo(point._view.x, point._view.y);
                                } else {
                                        this.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {
-                                               ctx.moveTo(nextPoint._view.x, this._view.scaleZero);
+                                               ctx.moveTo(nextPoint._view.x, nextPoint._view.y);
                                        }, function(previousPoint, point, nextPoint) {
                                                // If we skipped the last point, move up to our point preventing a line from being drawn
                                                ctx.moveTo(point._view.x, point._view.y);
index a310772325ed4d6730f61f01eb417fb95c42defd..926345feb9279a3ef9ccb9259839f2c20c28af53 100644 (file)
@@ -283,6 +283,159 @@ describe('Line element tests', function() {
                expect(mockContext.getCalls()).toEqual(expected);
        });
 
+       it ('should skip points correctly', function() {
+               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
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 1,
+                       _view: {
+                               x: 5,
+                               y: 0,
+                               controlPointPreviousX: 5,
+                               controlPointPreviousY: 0,
+                               controlPointNextX: 5,
+                               controlPointNextY: 0
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 2,
+                       _view: {
+                               x: 15,
+                               y: -10,
+                               controlPointPreviousX: 15,
+                               controlPointPreviousY: -10,
+                               controlPointNextX: 15,
+                               controlPointNextY: -10,
+                               skip: true
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 3,
+                       _view: {
+                               x: 19,
+                               y: -5,
+                               controlPointPreviousX: 19,
+                               controlPointPreviousY: -5,
+                               controlPointNextX: 19,
+                               controlPointNextY: -5
+                       }
+               }));
+
+               var line = new Chart.elements.Line({
+                       _datasetindex: 2,
+                       _chart: {
+                               ctx: mockContext,
+                       },
+                       _children: points,
+                       // Need to provide some settings
+                       _view: {
+                               fill: true,
+                               scaleZero: 2, // for filling lines
+                               tension: 0.0, // no bezier curve for now
+                       }
+               });
+
+               line.draw();
+
+               var expected = [{
+                       name: 'save',
+                       args: []
+               }, {
+                       name: 'beginPath',
+                       args: []
+               }, {
+                       name: 'moveTo',
+                       args: [0, 2]
+               }, {
+                       name: 'lineTo',
+                       args: [0, 10]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [0, 10, 5, 0, 5, 0]
+               }, {
+                       name: 'lineTo',
+                       args: [5, 2]
+               }, {
+                       name: 'moveTo',
+                       args: [19, 2]
+               }, {
+                       name: 'lineTo',
+                       args: [19, -5]
+               }, {
+                       name: 'lineTo',
+                       args: [19, 2]
+               }, {
+                       name: 'lineTo',
+                       args: [0, 2]
+               }, {
+                       name: 'setFillStyle',
+                       args: ['rgba(0,0,0,0.1)']
+               }, {
+                       name: 'closePath',
+                       args: []
+               }, {
+                       name: 'fill',
+                       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: 'bezierCurveTo',
+                       args: [0, 10, 5, 0, 5, 0]
+               }, {
+                       name: 'moveTo',
+                       args: [19, -5]
+               }, {
+                       name: 'moveTo',
+                       args: [19, -5]
+               }, {
+                       name: 'stroke',
+                       args: [],
+               }, {
+                       name: 'restore',
+                       args: []
+               }];
+               expect(mockContext.getCalls()).toEqual(expected);
+       });
+
        it('should be able to draw with a loop back to the beginning point', function() {
                var mockContext = window.createMockContext();
 
@@ -346,9 +499,12 @@ describe('Line element tests', function() {
                        _loop: true, // want the line to loop back to the first point
                        // Need to provide some settings
                        _view: {
-                               fill: false, // don't want to fill
+                               fill: true, // don't want to fill
                                tension: 0.0, // no bezier curve for now
-                               scaleZero: 0,
+                               scaleZero: {
+                                       x: 3,
+                                       y: 2
+                               },
                        }
                });
 
@@ -357,6 +513,36 @@ describe('Line element tests', function() {
                expect(mockContext.getCalls()).toEqual([{
                        name: 'save',
                        args: [],
+               }, {
+                       name: 'beginPath',
+                       args: []
+               }, {
+                       name: 'moveTo',
+                       args: [3, 2]
+               }, {
+                       name: 'lineTo',
+                       args: [0, 10]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [0, 10, 5, 0, 5, 0]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [5, 0, 15, -10, 15, -10]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [15, -10, 19, -5, 19, -5]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [19, -5, 0, 10, 0, 10]
+               }, {
+                       name: 'setFillStyle',
+                       args: ['rgba(0,0,0,0.1)']
+               }, {
+                       name: 'closePath',
+                       args: []
+               }, {
+                       name: 'fill',
+                       args: []
                }, {
                        name: 'setLineCap',
                        args: ['butt']
@@ -403,4 +589,460 @@ describe('Line element tests', function() {
                        args: []
                }]);
        });
+
+       it('should be able to draw with a loop back to the beginning point when there is a skip in the middle of the dataset', function() {
+               var mockContext = window.createMockContext();
+
+               // Create our points
+               var points = [];
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 0,
+                       _view: {
+                               x: 0,
+                               y: 10,
+                               controlPointPreviousX: 0,
+                               controlPointPreviousY: 10,
+                               controlPointNextX: 0,
+                               controlPointNextY: 10
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 1,
+                       _view: {
+                               x: 5,
+                               y: 0,
+                               controlPointPreviousX: 5,
+                               controlPointPreviousY: 0,
+                               controlPointNextX: 5,
+                               controlPointNextY: 0,
+                               skip: true
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 2,
+                       _view: {
+                               x: 15,
+                               y: -10,
+                               controlPointPreviousX: 15,
+                               controlPointPreviousY: -10,
+                               controlPointNextX: 15,
+                               controlPointNextY: -10
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 3,
+                       _view: {
+                               x: 19,
+                               y: -5,
+                               controlPointPreviousX: 19,
+                               controlPointPreviousY: -5,
+                               controlPointNextX: 19,
+                               controlPointNextY: -5
+                       }
+               }));
+
+               var line = new Chart.elements.Line({
+                       _datasetindex: 2,
+                       _chart: {
+                               ctx: mockContext,
+                       },
+                       _children: points,
+                       _loop: true, // want the line to loop back to the first point
+                       // Need to provide some settings
+                       _view: {
+                               fill: true, // don't want to fill
+                               tension: 0.0, // no bezier curve for now
+                               scaleZero: {
+                                       x: 3,
+                                       y: 2
+                               },
+                       }
+               });
+
+               line.draw();
+
+               expect(mockContext.getCalls()).toEqual([{
+                       name: 'save',
+                       args: [],
+               }, {
+                       name: 'beginPath',
+                       args: []
+               }, {
+                       name: 'moveTo',
+                       args: [3, 2]
+               }, {
+                       name: 'lineTo',
+                       args: [0, 10]
+               }, {
+                       name: 'lineTo',
+                       args: [3, 2]
+               }, {
+                       name: 'lineTo',
+                       args: [15, -10]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [15, -10, 19, -5, 19, -5]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [19, -5, 0, 10, 0, 10]
+               }, {
+                       name: 'setFillStyle',
+                       args: ['rgba(0,0,0,0.1)']
+               }, {
+                       name: 'closePath',
+                       args: []
+               }, {
+                       name: 'fill',
+                       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: 'moveTo',
+                       args: [15, -10]
+               }, {
+                       name: 'moveTo',
+                       args: [15, -10]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [15, -10, 19, -5, 19, -5]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [19, -5, 0, 10, 0, 10]
+               }, {
+                       name: 'stroke',
+                       args: [],
+               }, {
+                       name: 'restore',
+                       args: []
+               }]);
+       });
+
+       it('should be able to draw with a loop back to the beginning point when the first point is skipped', function() {
+               var mockContext = window.createMockContext();
+
+               // Create our points
+               var points = [];
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 0,
+                       _view: {
+                               x: 0,
+                               y: 10,
+                               controlPointPreviousX: 0,
+                               controlPointPreviousY: 10,
+                               controlPointNextX: 0,
+                               controlPointNextY: 10,
+                               skip: true
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 1,
+                       _view: {
+                               x: 5,
+                               y: 0,
+                               controlPointPreviousX: 5,
+                               controlPointPreviousY: 0,
+                               controlPointNextX: 5,
+                               controlPointNextY: 0,
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 2,
+                       _view: {
+                               x: 15,
+                               y: -10,
+                               controlPointPreviousX: 15,
+                               controlPointPreviousY: -10,
+                               controlPointNextX: 15,
+                               controlPointNextY: -10
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 3,
+                       _view: {
+                               x: 19,
+                               y: -5,
+                               controlPointPreviousX: 19,
+                               controlPointPreviousY: -5,
+                               controlPointNextX: 19,
+                               controlPointNextY: -5
+                       }
+               }));
+
+               var line = new Chart.elements.Line({
+                       _datasetindex: 2,
+                       _chart: {
+                               ctx: mockContext,
+                       },
+                       _children: points,
+                       _loop: true, // want the line to loop back to the first point
+                       // Need to provide some settings
+                       _view: {
+                               fill: true, // don't want to fill
+                               tension: 0.0, // no bezier curve for now
+                               scaleZero: {
+                                       x: 3,
+                                       y: 2
+                               },
+                       }
+               });
+
+               line.draw();
+
+               expect(mockContext.getCalls()).toEqual([{
+                       name: 'save',
+                       args: [],
+               }, {
+                       name: 'beginPath',
+                       args: []
+               }, {
+                       name: 'moveTo',
+                       args: [3, 2]
+               }, {
+                       name: 'lineTo',
+                       args: [5, 0]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [5, 0, 15, -10, 15, -10]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [15, -10, 19, -5, 19, -5]
+               }, {
+                       name: 'lineTo',
+                       args: [3, 2]
+               }, {
+                       name: 'setFillStyle',
+                       args: ['rgba(0,0,0,0.1)']
+               }, {
+                       name: 'closePath',
+                       args: []
+               }, {
+                       name: 'fill',
+                       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: 'moveTo',
+                       args: [5, 0]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [5, 0, 15, -10, 15, -10]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [15, -10, 19, -5, 19, -5]
+               }, {
+                       name: 'stroke',
+                       args: [],
+               }, {
+                       name: 'restore',
+                       args: []
+               }]);
+       });
+
+       it('should be able to draw with a loop back to the beginning point when the last point is skipped', function() {
+               var mockContext = window.createMockContext();
+
+               // Create our points
+               var points = [];
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 0,
+                       _view: {
+                               x: 0,
+                               y: 10,
+                               controlPointPreviousX: 0,
+                               controlPointPreviousY: 10,
+                               controlPointNextX: 0,
+                               controlPointNextY: 10
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 1,
+                       _view: {
+                               x: 5,
+                               y: 0,
+                               controlPointPreviousX: 5,
+                               controlPointPreviousY: 0,
+                               controlPointNextX: 5,
+                               controlPointNextY: 0,
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 2,
+                       _view: {
+                               x: 15,
+                               y: -10,
+                               controlPointPreviousX: 15,
+                               controlPointPreviousY: -10,
+                               controlPointNextX: 15,
+                               controlPointNextY: -10
+                       }
+               }));
+               points.push(new Chart.elements.Point({
+                       _datasetindex: 2,
+                       _index: 3,
+                       _view: {
+                               x: 19,
+                               y: -5,
+                               controlPointPreviousX: 19,
+                               controlPointPreviousY: -5,
+                               controlPointNextX: 19,
+                               controlPointNextY: -5,
+                               skip: true
+                       }
+               }));
+
+               var line = new Chart.elements.Line({
+                       _datasetindex: 2,
+                       _chart: {
+                               ctx: mockContext,
+                       },
+                       _children: points,
+                       _loop: true, // want the line to loop back to the first point
+                       // Need to provide some settings
+                       _view: {
+                               fill: true, // don't want to fill
+                               tension: 0.0, // no bezier curve for now
+                               scaleZero: {
+                                       x: 3,
+                                       y: 2
+                               },
+                       }
+               });
+
+               line.draw();
+
+               expect(mockContext.getCalls()).toEqual([{
+                       name: 'save',
+                       args: [],
+               }, {
+                       name: 'beginPath',
+                       args: []
+               }, {
+                       name: 'moveTo',
+                       args: [3, 2]
+               }, {
+                       name: 'lineTo',
+                       args: [0, 10]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [0, 10, 5, 0, 5, 0]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [5, 0, 15, -10, 15, -10]
+               }, {
+                       name: 'lineTo',
+                       args: [3, 2]
+               }, {
+                       name: 'lineTo',
+                       args: [3, 2]
+               }, {
+                       name: 'setFillStyle',
+                       args: ['rgba(0,0,0,0.1)']
+               }, {
+                       name: 'closePath',
+                       args: []
+               }, {
+                       name: 'fill',
+                       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: 'bezierCurveTo',
+                       args: [0, 10, 5, 0, 5, 0]
+               }, {
+                       name: 'bezierCurveTo',
+                       args: [5, 0, 15, -10, 15, -10]
+               }, {
+                       name: 'moveTo',
+                       args: [19, -5]
+               }, {
+                       name: 'stroke',
+                       args: [],
+               }, {
+                       name: 'restore',
+                       args: []
+               }]);
+       });
 });