borderDashOffset: 0.0,
borderJoinStyle: 'miter',
capBezierPoints: true,
- fill: true // do we fill in the area between the line and its base axis
+ fill: true, // do we fill in the area between the line and its base axis
};
Chart.elements.Line = Chart.Element.extend({
var me = this;
var vm = me._view;
var spanGaps = vm.spanGaps;
- var scaleZero = vm.scaleZero;
+ var fillPoint = vm.scaleZero;
var loop = me._loop;
+ // Handle different fill modes for cartesian lines
+ if (!loop) {
+ if (vm.fill === 'top') {
+ fillPoint = vm.scaleTop;
+ } else if (vm.fill === 'bottom') {
+ fillPoint = vm.scaleBottom;
+ }
+ }
+
var ctx = me._chart.ctx;
ctx.save();
// First point moves to it's starting position no matter what
if (index === 0) {
if (loop) {
- ctx.moveTo(scaleZero.x, scaleZero.y);
+ ctx.moveTo(fillPoint.x, fillPoint.y);
} else {
- ctx.moveTo(currentVM.x, scaleZero);
+ ctx.moveTo(currentVM.x, fillPoint);
}
if (!currentVM.skip) {
// Only do this if this is the first point that is skipped
if (!spanGaps && lastDrawnIndex === (index - 1)) {
if (loop) {
- ctx.lineTo(scaleZero.x, scaleZero.y);
+ ctx.lineTo(fillPoint.x, fillPoint.y);
} else {
- ctx.lineTo(previous._view.x, scaleZero);
+ ctx.lineTo(previous._view.x, fillPoint);
}
}
} else {
} else if (loop) {
ctx.lineTo(currentVM.x, currentVM.y);
} else {
- ctx.lineTo(currentVM.x, scaleZero);
+ ctx.lineTo(currentVM.x, fillPoint);
ctx.lineTo(currentVM.x, currentVM.y);
}
} else {
}
if (!loop && lastDrawnIndex !== -1) {
- ctx.lineTo(points[lastDrawnIndex]._view.x, scaleZero);
+ ctx.lineTo(points[lastDrawnIndex]._view.x, fillPoint);
}
ctx.fillStyle = vm.backgroundColor || globalDefaults.defaultColor;
expect(mockContext.getCalls()).toEqual(expected);
});
+ it('should draw with fillMode top', 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
+ }
+ }));
+ 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: 'top',
+ scaleZero: 2, // for filling lines
+ scaleTop: -2,
+ scaleBottom: 10,
+ tension: 0.0, // no bezier curve for now
+
+ borderCapStyle: 'round',
+ borderColor: 'rgb(255, 255, 0)',
+ borderDash: [2, 2],
+ borderDashOffset: 1.5,
+ borderJoinStyle: 'bevel',
+ borderWidth: 4,
+ backgroundColor: 'rgb(0, 0, 0)'
+ }
+ });
+
+ 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: 'bezierCurveTo',
+ args: [5, 0, 15, -10, 15, -10]
+ }, {
+ name: 'bezierCurveTo',
+ args: [15, -10, 19, -5, 19, -5]
+ }, {
+ name: 'lineTo',
+ args: [19, -2]
+ }, {
+ name: 'setFillStyle',
+ args: ['rgb(0, 0, 0)']
+ }, {
+ name: 'closePath',
+ args: []
+ }, {
+ name: 'fill',
+ args: []
+ }, {
+ name: 'setLineCap',
+ args: ['round']
+ }, {
+ name: 'setLineDash',
+ args: [
+ [2, 2]
+ ]
+ }, {
+ name: 'setLineDashOffset',
+ args: [1.5]
+ }, {
+ name: 'setLineJoin',
+ args: ['bevel']
+ }, {
+ name: 'setLineWidth',
+ args: [4]
+ }, {
+ name: 'setStrokeStyle',
+ args: ['rgb(255, 255, 0)']
+ }, {
+ 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: 'bezierCurveTo',
+ args: [15, -10, 19, -5, 19, -5]
+ }, {
+ name: 'stroke',
+ args: []
+ }, {
+ name: 'restore',
+ args: []
+ }];
+ expect(mockContext.getCalls()).toEqual(expected);
+ });
+
+ it('should draw with fillMode bottom', 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
+ }
+ }));
+ 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: 'bottom',
+ scaleZero: 2, // for filling lines
+ scaleTop: -2,
+ scaleBottom: 10,
+ tension: 0.0, // no bezier curve for now
+
+ borderCapStyle: 'round',
+ borderColor: 'rgb(255, 255, 0)',
+ borderDash: [2, 2],
+ borderDashOffset: 1.5,
+ borderJoinStyle: 'bevel',
+ borderWidth: 4,
+ backgroundColor: 'rgb(0, 0, 0)'
+ }
+ });
+
+ line.draw();
+
+ var expected = [{
+ name: 'save',
+ args: []
+ }, {
+ name: 'beginPath',
+ args: []
+ }, {
+ name: 'moveTo',
+ args: [0, 10]
+ }, {
+ 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: 'lineTo',
+ args: [19, 10]
+ }, {
+ name: 'setFillStyle',
+ args: ['rgb(0, 0, 0)']
+ }, {
+ name: 'closePath',
+ args: []
+ }, {
+ name: 'fill',
+ args: []
+ }, {
+ name: 'setLineCap',
+ args: ['round']
+ }, {
+ name: 'setLineDash',
+ args: [
+ [2, 2]
+ ]
+ }, {
+ name: 'setLineDashOffset',
+ args: [1.5]
+ }, {
+ name: 'setLineJoin',
+ args: ['bevel']
+ }, {
+ name: 'setLineWidth',
+ args: [4]
+ }, {
+ name: 'setStrokeStyle',
+ args: ['rgb(255, 255, 0)']
+ }, {
+ 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: 'bezierCurveTo',
+ args: [15, -10, 19, -5, 19, -5]
+ }, {
+ name: 'stroke',
+ args: []
+ }, {
+ name: 'restore',
+ args: []
+ }];
+ expect(mockContext.getCalls()).toEqual(expected);
+ });
+
it('should skip points correctly', function() {
var mockContext = window.createMockContext();