From 4b421a50bfa17f73ac7aa8db7d077e674dbc148d Mon Sep 17 00:00:00 2001 From: Simon Brunel Date: Sat, 18 Mar 2017 11:08:57 +0100 Subject: [PATCH] Add support to fill between datasets (#4008) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The `fill` option now accepts the index of the target dataset (number) or a string starting by "+" or "-" followed by a number representing the dataset index relative to the current one (e.g. `fill: "-2"` on dataset at index 3 will fill to dataset at index 1). It's also possible to "propagate" the filling to the target of an hidden dataset (`options.plugins.filler.propagate`). Fill boundaries `zero`, `top` and `bottom` have been deprecated and replaced by `origin`, `start` and `end`. Implementation has been moved out of the line element into a new plugin (`src/plugins/plugin.filler.js`) and does not rely anymore on the deprecated model `scaleTop`, `scaleBottom` and `scaleZero` values. Drawing Bézier splines has been refactored in the canvas helpers (note that `Chart.helpers.canvas` is now an alias of `Chart.canvasHelpers`). Add 3 new examples and extend utils with a pseudo-random number generator that can be initialized with `srand`. That makes possible to design examples starting always with the same initial data. --- samples/area/analyser.js | 66 ++ samples/area/line-boundaries.html | 120 +++ samples/area/line-datasets.html | 157 ++++ samples/area/radar.html | 136 +++ samples/style.css | 64 ++ samples/utils.js | 110 ++- src/chart.js | 7 + src/controllers/controller.line.js | 4 - src/controllers/controller.radar.js | 6 +- src/core/core.canvasHelpers.js | 22 + src/elements/element.line.js | 109 +-- src/plugins/plugin.filler.js | 309 +++++++ .../fill-line-boundary-end-span.json} | 2 +- .../fill-line-boundary-end-span.png} | Bin .../fill-line-boundary-end.json} | 2 +- .../fill-line-boundary-end.png} | Bin .../fill-line-boundary-origin-span.json} | 2 +- .../fill-line-boundary-origin-span.png} | Bin ...ill-line-boundary-origin-spline-span.json} | 2 +- ...fill-line-boundary-origin-spline-span.png} | Bin .../fill-line-boundary-origin-spline.json} | 2 +- .../fill-line-boundary-origin-spline.png} | Bin ...ll-line-boundary-origin-stepped-span.json} | 2 +- ...ill-line-boundary-origin-stepped-span.png} | Bin .../fill-line-boundary-origin-stepped.json} | 2 +- .../fill-line-boundary-origin-stepped.png} | Bin .../fill-line-boundary-origin.json} | 2 +- .../fill-line-boundary-origin.png} | Bin .../fill-line-boundary-start-span.json} | 2 +- .../fill-line-boundary-start-span.png} | Bin .../fill-line-boundary-start.json} | 2 +- .../fill-line-boundary-start.png} | Bin .../plugin.filler/fill-line-dataset-span.json | 62 ++ .../plugin.filler/fill-line-dataset-span.png | Bin 0 -> 24102 bytes .../fill-line-dataset-spline-span.json | 62 ++ .../fill-line-dataset-spline-span.png | Bin 0 -> 25819 bytes .../fill-line-dataset-spline.json | 62 ++ .../fill-line-dataset-spline.png | Bin 0 -> 23223 bytes .../plugin.filler/fill-line-dataset.json | 62 ++ .../plugin.filler/fill-line-dataset.png | Bin 0 -> 22331 bytes .../fill-radar-boundary-origin-spline.json} | 2 +- .../fill-radar-boundary-origin-spline.png} | Bin .../fill-radar-boundary-origin.json} | 2 +- .../fill-radar-boundary-origin.png} | Bin test/specs/controller.line.tests.js | 42 - test/specs/controller.radar.tests.js | 12 - test/specs/element.line.tests.js | 869 ++---------------- test/specs/global.deprecations.tests.js | 21 + test/specs/plugin.filler.tests.js | 265 ++++++ 49 files changed, 1621 insertions(+), 970 deletions(-) create mode 100644 samples/area/analyser.js create mode 100644 samples/area/line-boundaries.html create mode 100644 samples/area/line-datasets.html create mode 100644 samples/area/radar.html create mode 100644 samples/style.css create mode 100644 src/plugins/plugin.filler.js rename test/fixtures/{element.line/fill-line-top-span.json => plugin.filler/fill-line-boundary-end-span.json} (97%) rename test/fixtures/{element.line/fill-line-top-span.png => plugin.filler/fill-line-boundary-end-span.png} (100%) rename test/fixtures/{element.line/fill-line-top.json => plugin.filler/fill-line-boundary-end.json} (97%) rename test/fixtures/{element.line/fill-line-top.png => plugin.filler/fill-line-boundary-end.png} (100%) rename test/fixtures/{element.line/fill-line-zero-span.json => plugin.filler/fill-line-boundary-origin-span.json} (97%) rename test/fixtures/{element.line/fill-line-zero-span.png => plugin.filler/fill-line-boundary-origin-span.png} (100%) rename test/fixtures/{element.line/fill-line-spline-span.json => plugin.filler/fill-line-boundary-origin-spline-span.json} (97%) rename test/fixtures/{element.line/fill-line-spline-span.png => plugin.filler/fill-line-boundary-origin-spline-span.png} (100%) rename test/fixtures/{element.line/fill-line-spline.json => plugin.filler/fill-line-boundary-origin-spline.json} (97%) rename test/fixtures/{element.line/fill-line-spline.png => plugin.filler/fill-line-boundary-origin-spline.png} (100%) rename test/fixtures/{element.line/fill-line-stepped-span.json => plugin.filler/fill-line-boundary-origin-stepped-span.json} (97%) rename test/fixtures/{element.line/fill-line-stepped-span.png => plugin.filler/fill-line-boundary-origin-stepped-span.png} (100%) rename test/fixtures/{element.line/fill-line-stepped.json => plugin.filler/fill-line-boundary-origin-stepped.json} (97%) rename test/fixtures/{element.line/fill-line-stepped.png => plugin.filler/fill-line-boundary-origin-stepped.png} (100%) rename test/fixtures/{element.line/fill-line-zero.json => plugin.filler/fill-line-boundary-origin.json} (97%) rename test/fixtures/{element.line/fill-line-zero.png => plugin.filler/fill-line-boundary-origin.png} (100%) rename test/fixtures/{element.line/fill-line-bottom-span.json => plugin.filler/fill-line-boundary-start-span.json} (97%) rename test/fixtures/{element.line/fill-line-bottom-span.png => plugin.filler/fill-line-boundary-start-span.png} (100%) rename test/fixtures/{element.line/fill-line-bottom.json => plugin.filler/fill-line-boundary-start.json} (97%) rename test/fixtures/{element.line/fill-line-bottom.png => plugin.filler/fill-line-boundary-start.png} (100%) create mode 100644 test/fixtures/plugin.filler/fill-line-dataset-span.json create mode 100644 test/fixtures/plugin.filler/fill-line-dataset-span.png create mode 100644 test/fixtures/plugin.filler/fill-line-dataset-spline-span.json create mode 100644 test/fixtures/plugin.filler/fill-line-dataset-spline-span.png create mode 100644 test/fixtures/plugin.filler/fill-line-dataset-spline.json create mode 100644 test/fixtures/plugin.filler/fill-line-dataset-spline.png create mode 100644 test/fixtures/plugin.filler/fill-line-dataset.json create mode 100644 test/fixtures/plugin.filler/fill-line-dataset.png rename test/fixtures/{element.line/fill-radar-spline.json => plugin.filler/fill-radar-boundary-origin-spline.json} (97%) rename test/fixtures/{element.line/fill-radar-spline.png => plugin.filler/fill-radar-boundary-origin-spline.png} (100%) rename test/fixtures/{element.line/fill-radar-zero.json => plugin.filler/fill-radar-boundary-origin.json} (97%) rename test/fixtures/{element.line/fill-radar-zero.png => plugin.filler/fill-radar-boundary-origin.png} (100%) create mode 100644 test/specs/plugin.filler.tests.js diff --git a/samples/area/analyser.js b/samples/area/analyser.js new file mode 100644 index 000000000..f9d001af5 --- /dev/null +++ b/samples/area/analyser.js @@ -0,0 +1,66 @@ +/* global Chart */ + +'use strict'; + +(function() { + Chart.plugins.register({ + id: 'samples_filler_analyser', + + beforeInit: function(chart, options) { + this.element = document.getElementById(options.target); + }, + + afterUpdate: function(chart) { + var datasets = chart.data.datasets; + var element = this.element; + var stats = []; + var meta, i, ilen, dataset; + + if (!element) { + return; + } + + for (i=0, ilen=datasets.length; i' + + 'Dataset' + + 'Fill' + + 'Target (visibility)' + + '' + + stats.map(function(stat) { + var target = stat.target; + var row = + '' + stat.index + '' + + '' + JSON.stringify(stat.fill) + ''; + + if (target === false) { + target = 'none'; + } else if (isFinite(target)) { + target = 'dataset ' + target; + } else { + target = 'boundary "' + target + '"'; + } + + if (stat.visible) { + row += '' + target + ''; + } else { + row += '(hidden)'; + } + + return '' + row + ''; + }).join('') + ''; + } + }); +}()); diff --git a/samples/area/line-boundaries.html b/samples/area/line-boundaries.html new file mode 100644 index 000000000..ca0aab3a7 --- /dev/null +++ b/samples/area/line-boundaries.html @@ -0,0 +1,120 @@ + + + + + + + area > boundaries | Chart.js sample + + + + + + +
+
+
+
+
+ +
+ + +
+
+ + + + diff --git a/samples/area/line-datasets.html b/samples/area/line-datasets.html new file mode 100644 index 000000000..37719df26 --- /dev/null +++ b/samples/area/line-datasets.html @@ -0,0 +1,157 @@ + + + + + + + area > datasets | Chart.js sample + + + + + + +
+
+ +
+
+ + + +
+
+
+ + + + diff --git a/samples/area/radar.html b/samples/area/radar.html new file mode 100644 index 000000000..23f2bdd36 --- /dev/null +++ b/samples/area/radar.html @@ -0,0 +1,136 @@ + + + + + + + area > radar | Chart.js sample + + + + + + +
+
+ +
+
+ + + +
+
+
+ + + + diff --git a/samples/style.css b/samples/style.css new file mode 100644 index 000000000..5b5865064 --- /dev/null +++ b/samples/style.css @@ -0,0 +1,64 @@ +body, html { + font-family: sans-serif; + padding: 0; + margin: 0; +} + +.content { + max-width: 800px; + margin: auto; + padding: 16px; +} + +.wrapper { + min-height: 400px; + padding: 16px 0; + position: relative; +} + +.wrapper.col-2 { + display: inline-block; + min-height: 256px; + width: 49%; +} + +@media (max-width: 400px) { + .wrapper.col-2 { + width: 100% + } +} + +.wrapper canvas { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; +} + +.toolbar { + display: flex; +} + +.toolbar > * { + margin: 0 8px 0 0; +} + +.btn-on { + border-style: inset; +} + +.analyser table { + color: #333; + font-size: 0.9rem; + margin: 8px 0; + width: 100% +} + +.analyser th { + background-color: #f0f0f0; + padding: 2px; +} + +.analyser td { + padding: 2px; + text-align: center; +} diff --git a/samples/utils.js b/samples/utils.js index 34965ce66..dc5bd12ae 100644 --- a/samples/utils.js +++ b/samples/utils.js @@ -1,3 +1,7 @@ +/* global Chart */ + +'use strict'; + window.chartColors = { red: 'rgb(255, 99, 132)', orange: 'rgb(255, 159, 64)', @@ -5,9 +9,111 @@ window.chartColors = { green: 'rgb(75, 192, 192)', blue: 'rgb(54, 162, 235)', purple: 'rgb(153, 102, 255)', - grey: 'rgb(231,233,237)' + grey: 'rgb(201, 203, 207)' }; window.randomScalingFactor = function() { return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100); -} \ No newline at end of file +}; + +(function(global) { + var Months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' + ]; + + var Samples = global.Samples || (global.Samples = {}); + Samples.utils = { + // Adapted from http://indiegamr.com/generate-repeatable-random-numbers-in-js/ + srand: function(seed) { + this._seed = seed; + }, + + rand: function(min, max) { + var seed = this._seed; + min = min === undefined? 0 : min; + max = max === undefined? 1 : max; + this._seed = (seed * 9301 + 49297) % 233280; + return min + (this._seed / 233280) * (max - min); + }, + + numbers: function(config) { + var cfg = config || {}; + var min = cfg.min || 0; + var max = cfg.max || 1; + var from = cfg.from || []; + var count = cfg.count || 8; + var decimals = cfg.decimals || 8; + var continuity = cfg.continuity || 1; + var dfactor = Math.pow(10, decimals) || 0; + var data = []; + var i, value; + + for (i=0; i= count) { + return false; + } + + return target; + } + + switch (fill) { + // compatibility + case 'bottom': + return 'start'; + case 'top': + return 'end'; + case 'zero': + return 'origin'; + // supported boundaries + case 'origin': + case 'start': + case 'end': + return fill; + // invalid fill values + default: + return false; + } + } + + function computeBoundary(source) { + var model = source.el._model || {}; + var scale = source.el._scale || {}; + var fill = source.fill; + var target = null; + var horizontal; + + if (isFinite(fill)) { + return null; + } + + // Backward compatibility: until v3, we still need to support boundary values set on + // the model (scaleTop, scaleBottom and scaleZero) because some external plugins and + // controllers might still use it (e.g. the Smith chart). + + if (fill === 'start') { + target = model.scaleBottom === undefined? scale.bottom : model.scaleBottom; + } else if (fill === 'end') { + target = model.scaleTop === undefined? scale.top : model.scaleTop; + } else if (model.scaleZero !== undefined) { + target = model.scaleZero; + } else if (scale.getBasePosition) { + target = scale.getBasePosition(); + } else if (scale.getBasePixel) { + target = scale.getBasePixel(); + } + + if (target !== undefined && target !== null) { + if (target.x !== undefined && target.y !== undefined) { + return target; + } + + if (typeof target === 'number' && isFinite(target)) { + horizontal = scale.isHorizontal(); + return { + x: horizontal? target : null, + y: horizontal? null : target + }; + } + } + + return null; + } + + function resolveTarget(sources, index, propagate) { + var source = sources[index]; + var fill = source.fill; + var visited = [index]; + var target; + + if (!propagate) { + return fill; + } + + while (fill !== false && visited.indexOf(fill) === -1) { + if (!isFinite(fill)) { + return fill; + } + + target = sources[fill]; + if (!target) { + return false; + } + + if (target.visible) { + return fill; + } + + visited.push(fill); + fill = target.fill; + } + + return false; + } + + function createMapper(source) { + var fill = source.fill; + var type = 'dataset'; + + if (fill === false) { + return null; + } + + if (!isFinite(fill)) { + type = 'boundary'; + } + + return mappers[type](source); + } + + function isDrawable(point) { + return point && !point.skip; + } + + function drawArea(ctx, curve0, curve1, len0, len1) { + var i; + + if (!len0 || !len1) { + return; + } + + // building first area curve (normal) + ctx.moveTo(curve0[0].x, curve0[0].y); + for (i=1; i0; --i) { + helpers.canvas.lineTo(ctx, curve1[i], curve1[i-1], true); + } + } + + function doFill(ctx, points, mapper, view, color, loop) { + var count = points.length; + var span = view.spanGaps; + var curve0 = []; + var curve1 = []; + var len0 = 0; + var len1 = 0; + var i, ilen, index, p0, p1, d0, d1; + + ctx.beginPath(); + + for (i = 0, ilen = (count + !!loop); i < ilen; ++i) { + index = i%count; + p0 = points[index]._view; + p1 = mapper(p0, index, view); + d0 = isDrawable(p0); + d1 = isDrawable(p1); + + if (d0 && d1) { + len0 = curve0.push(p0); + len1 = curve1.push(p1); + } else if (len0 && len1) { + if (!span) { + drawArea(ctx, curve0, curve1, len0, len1); + len0 = len1 = 0; + curve0 = []; + curve1 = []; + } else { + if (d0) { + curve0.push(p0); + } + if (d1) { + curve1.push(p1); + } + } + } + } + + drawArea(ctx, curve0, curve1, len0, len1); + + ctx.closePath(); + ctx.fillStyle = color; + ctx.fill(); + } + + return { + id: 'filler', + + afterDatasetsUpdate: function(chart, options) { + var count = (chart.data.datasets || []).length; + var propagate = options.propagate; + var sources = []; + var meta, i, el, source; + + for (i = 0; i < count; ++i) { + meta = chart.getDatasetMeta(i); + el = meta.dataset; + source = null; + + if (el && el._model && el instanceof Chart.elements.Line) { + source = { + visible: chart.isDatasetVisible(i), + fill: decodeFill(el, i, count), + chart: chart, + el: el + }; + } + + meta.$filler = source; + sources.push(source); + } + + for (i=0; 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 literal 0 Hc-jL100001 diff --git a/test/fixtures/plugin.filler/fill-line-dataset-spline.json b/test/fixtures/plugin.filler/fill-line-dataset-spline.json new file mode 100644 index 000000000..55054f1f5 --- /dev/null +++ b/test/fixtures/plugin.filler/fill-line-dataset-spline.json @@ -0,0 +1,62 @@ +{ + "config": { + "type": "line", + "data": { + "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"], + "datasets": [{ + "backgroundColor": "rgba(255, 0, 0, 0.25)", + "data": [null, null, 0, -1, 0, 1, 0, -1, 0], + "fill": 1 + }, { + "backgroundColor": "rgba(0, 255, 0, 0.25)", + "data": [1, 0, null, 1, 0, null, -1, 0, 1], + "fill": "+1" + }, { + "backgroundColor": "rgba(0, 0, 255, 0.25)", + "data": [0, 2, 0, -2, 0, 2, 0, null, null], + "fill": 3 + }, { + "backgroundColor": "rgba(255, 0, 255, 0.25)", + "data": [2, 0, -2, 0, 2, 0, -2, 0, 2], + "fill": "-2" + }, { + "backgroundColor": "rgba(255, 255, 0, 0.25)", + "data": [3, 1, -1, -3, -1, 1, 3, 1, -1], + "fill": "-1" + }] + }, + "options": { + "responsive": false, + "spanGaps": false, + "legend": false, + "title": false, + "scales": { + "xAxes": [{ + "ticks": { + "display": false + } + }], + "yAxes": [{ + "ticks": { + "display": false + } + }] + }, + "elements": { + "point": { + "radius": 0 + }, + "line": { + "cubicInterpolationMode": "monotone", + "borderColor": "transparent" + } + } + } + }, + "options": { + "canvas": { + "height": 256, + "width": 512 + } + } +} diff --git a/test/fixtures/plugin.filler/fill-line-dataset-spline.png b/test/fixtures/plugin.filler/fill-line-dataset-spline.png new file mode 100644 index 0000000000000000000000000000000000000000..41d52bc77db885b5333bd79545deabc8a0356c85 GIT binary patch literal 23223 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 Ib5F+q0I6G)J^%m! literal 0 Hc-jL100001 diff --git a/test/fixtures/element.line/fill-radar-spline.json b/test/fixtures/plugin.filler/fill-radar-boundary-origin-spline.json similarity index 97% rename from test/fixtures/element.line/fill-radar-spline.json rename to test/fixtures/plugin.filler/fill-radar-boundary-origin-spline.json index c22d8a651..8640adcf8 100644 --- a/test/fixtures/element.line/fill-radar-spline.json +++ b/test/fixtures/plugin.filler/fill-radar-boundary-origin-spline.json @@ -36,7 +36,7 @@ "line": { "borderColor": "transparent", "tension": 0.5, - "fill": "zero" + "fill": "origin" } } } diff --git a/test/fixtures/element.line/fill-radar-spline.png b/test/fixtures/plugin.filler/fill-radar-boundary-origin-spline.png similarity index 100% rename from test/fixtures/element.line/fill-radar-spline.png rename to test/fixtures/plugin.filler/fill-radar-boundary-origin-spline.png diff --git a/test/fixtures/element.line/fill-radar-zero.json b/test/fixtures/plugin.filler/fill-radar-boundary-origin.json similarity index 97% rename from test/fixtures/element.line/fill-radar-zero.json rename to test/fixtures/plugin.filler/fill-radar-boundary-origin.json index 172007943..fafe29791 100644 --- a/test/fixtures/element.line/fill-radar-zero.json +++ b/test/fixtures/plugin.filler/fill-radar-boundary-origin.json @@ -35,7 +35,7 @@ }, "line": { "borderColor": "transparent", - "fill": "zero" + "fill": "origin" } } } diff --git a/test/fixtures/element.line/fill-radar-zero.png b/test/fixtures/plugin.filler/fill-radar-boundary-origin.png similarity index 100% rename from test/fixtures/element.line/fill-radar-zero.png rename to test/fixtures/plugin.filler/fill-radar-boundary-origin.png diff --git a/test/specs/controller.line.tests.js b/test/specs/controller.line.tests.js index 2341b403c..f1fe61fac 100644 --- a/test/specs/controller.line.tests.js +++ b/test/specs/controller.line.tests.js @@ -509,48 +509,6 @@ describe('Line controller tests', function() { }); - it('should find the correct scale zero when the data is all positive', function() { - var chart = window.acquireChart({ - type: 'line', - data: { - datasets: [{ - data: [10, 15, 20, 20], - label: 'dataset1', - }], - labels: ['label1', 'label2', 'label3', 'label4'] - }, - }); - - var meta = chart.getDatasetMeta(0); - - expect(meta.dataset._model).toEqual(jasmine.objectContaining({ - scaleTop: 32, - scaleBottom: 484, - scaleZero: 484, - })); - }); - - it('should find the correct scale zero when the data is all negative', function() { - var chart = window.acquireChart({ - type: 'line', - data: { - datasets: [{ - data: [-10, -15, -20, -20], - label: 'dataset1', - }], - labels: ['label1', 'label2', 'label3', 'label4'] - }, - }); - - var meta = chart.getDatasetMeta(0); - - expect(meta.dataset._model).toEqual(jasmine.objectContaining({ - scaleTop: 32, - scaleBottom: 484, - scaleZero: 32, - })); - }); - it('should fall back to the line styles for points', function() { var chart = window.acquireChart({ type: 'line', diff --git a/test/specs/controller.radar.tests.js b/test/specs/controller.radar.tests.js index 4b9c1f696..8f621c96b 100644 --- a/test/specs/controller.radar.tests.js +++ b/test/specs/controller.radar.tests.js @@ -111,10 +111,6 @@ describe('Radar controller tests', function() { meta.controller.reset(); // reset first // Line element - expect(meta.dataset._model.scaleTop).toBeCloseToPixel(32); - expect(meta.dataset._model.scaleBottom).toBeCloseToPixel(512); - expect(meta.dataset._model.scaleZero.x).toBeCloseToPixel(256); - expect(meta.dataset._model.scaleZero.y).toBeCloseToPixel(272); expect(meta.dataset._model).toEqual(jasmine.objectContaining({ backgroundColor: 'rgb(255, 0, 0)', borderCapStyle: 'round', @@ -198,10 +194,6 @@ describe('Radar controller tests', function() { meta.controller.update(); - expect(meta.dataset._model.scaleTop).toBeCloseToPixel(32); - expect(meta.dataset._model.scaleBottom).toBeCloseToPixel(512); - expect(meta.dataset._model.scaleZero.x).toBeCloseToPixel(256); - expect(meta.dataset._model.scaleZero.y).toBeCloseToPixel(272); expect(meta.dataset._model).toEqual(jasmine.objectContaining({ backgroundColor: 'rgb(98, 98, 98)', borderCapStyle: 'butt', @@ -262,10 +254,6 @@ describe('Radar controller tests', function() { meta.controller.update(); - expect(meta.dataset._model.scaleTop).toBeCloseToPixel(32); - expect(meta.dataset._model.scaleBottom).toBeCloseToPixel(512); - expect(meta.dataset._model.scaleZero.x).toBeCloseToPixel(256); - expect(meta.dataset._model.scaleZero.y).toBeCloseToPixel(272); expect(meta.dataset._model).toEqual(jasmine.objectContaining({ backgroundColor: 'rgb(55, 55, 54)', borderCapStyle: 'square', diff --git a/test/specs/element.line.tests.js b/test/specs/element.line.tests.js index 52d94cd37..c4d1722b4 100644 --- a/test/specs/element.line.tests.js +++ b/test/specs/element.line.tests.js @@ -1,7 +1,5 @@ // Tests for the line element describe('Chart.elements.Line', function() { - describe('auto', jasmine.specsFromFixtures('element.line')); - it('should be constructed', function() { var line = new Chart.elements.Line({ _datasetindex: 2, @@ -74,8 +72,7 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: false, // don't want to fill - tension: 0.0, // no bezier curve for now - scaleZero: 0 + tension: 0, // no bezier curve for now } }); @@ -111,14 +108,14 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [0, 10] }, { - name: 'bezierCurveTo', - args: [0, 10, 5, 0, 5, 0] + name: 'lineTo', + args: [5, 0] }, { - name: 'bezierCurveTo', - args: [5, 0, 15, -10, 15, -10] + name: 'lineTo', + args: [15, -10] }, { - name: 'bezierCurveTo', - args: [15, -10, 19, -5, 19, -5] + name: 'lineTo', + args: [19, -5] }, { name: 'stroke', args: [], @@ -193,8 +190,7 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: false, // don't want to fill - tension: 0.0, // no bezier curve for now - scaleZero: 0 + tension: 0, // no bezier curve for now } }); @@ -312,8 +308,7 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: false, // don't want to fill - tension: 0.0, // no bezier curve for now - scaleZero: 0 + tension: 0, // no bezier curve for now } }); @@ -436,8 +431,7 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: true, - scaleZero: 2, // for filling lines - tension: 0.0, // no bezier curve for now + tension: 0, // no bezier curve for now borderCapStyle: 'round', borderColor: 'rgb(255, 255, 0)', @@ -454,36 +448,6 @@ describe('Chart.elements.Line', function() { 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'] @@ -510,327 +474,15 @@ describe('Chart.elements.Line', function() { }, { 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 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] + args: [5, 0] }, { 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] + args: [15, -10] }, { 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] + args: [19, -5] }, { name: 'stroke', args: [] @@ -903,48 +555,14 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: true, - scaleZero: 2, // for filling lines - tension: 0.0, // no bezier curve for now + tension: 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: 'lineTo', - args: [19, 2] - }, { - name: 'lineTo', - args: [19, -5] - }, { - name: 'lineTo', - args: [19, 2] - }, { - name: 'setFillStyle', - args: ['rgba(0,0,0,0.1)'] - }, { - name: 'closePath', - args: [] - }, { - name: 'fill', + }); + + line.draw(); + + var expected = [{ + name: 'save', args: [] }, { name: 'setLineCap', @@ -973,8 +591,8 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [0, 10] }, { - name: 'bezierCurveTo', - args: [0, 10, 5, 0, 5, 0] + name: 'lineTo', + args: [5, 0] }, { name: 'moveTo', args: [19, -5] @@ -1050,8 +668,7 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: true, - scaleZero: 2, // for filling lines - tension: 0.0, // no bezier curve for now + tension: 0, // no bezier curve for now spanGaps: true } }); @@ -1061,33 +678,6 @@ describe('Chart.elements.Line', function() { 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, 19, -5, 19, -5] - }, { - name: 'lineTo', - args: [19, 2] - }, { - name: 'setFillStyle', - args: ['rgba(0,0,0,0.1)'] - }, { - name: 'closePath', - args: [] - }, { - name: 'fill', - args: [] }, { name: 'setLineCap', args: ['butt'] @@ -1115,11 +705,11 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [0, 10] }, { - name: 'bezierCurveTo', - args: [0, 10, 5, 0, 5, 0] + name: 'lineTo', + args: [5, 0] }, { - name: 'bezierCurveTo', - args: [5, 0, 19, -5, 19, -5] + name: 'lineTo', + args: [19, -5] }, { name: 'stroke', args: [] @@ -1195,8 +785,7 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: true, - scaleZero: 2, // for filling lines - tension: 0.0, // no bezier curve for now + tension: 0, // no bezier curve for now spanGaps: true } }); @@ -1206,21 +795,6 @@ describe('Chart.elements.Line', function() { var expected = [{ name: 'save', args: [] - }, { - name: 'beginPath', - args: [] - }, { - name: 'moveTo', - args: [0, 2] - }, { - name: 'setFillStyle', - args: ['rgba(0,0,0,0.1)'] - }, { - name: 'closePath', - args: [] - }, { - name: 'fill', - args: [] }, { name: 'setLineCap', args: ['butt'] @@ -1316,8 +890,7 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: true, - scaleZero: 2, // for filling lines - tension: 0.0, // no bezier curve for now + tension: 0, // no bezier curve for now } }); @@ -1326,36 +899,6 @@ describe('Chart.elements.Line', function() { var expected = [{ name: 'save', args: [] - }, { - name: 'beginPath', - args: [] - }, { - name: 'moveTo', - args: [0, 2] - }, { - name: 'lineTo', - args: [5, 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: [19, 2] - }, { - name: 'setFillStyle', - args: ['rgba(0,0,0,0.1)'] - }, { - name: 'closePath', - args: [] - }, { - name: 'fill', - args: [] }, { name: 'setLineCap', args: ['butt'] @@ -1383,11 +926,11 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [5, 0] }, { - name: 'bezierCurveTo', - args: [5, 0, 15, -10, 15, -10] + name: 'lineTo', + args: [15, -10] }, { - name: 'bezierCurveTo', - args: [15, -10, 19, -5, 19, -5] + name: 'lineTo', + args: [19, -5] }, { name: 'stroke', args: [] @@ -1460,8 +1003,7 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: true, - scaleZero: 2, // for filling lines - tension: 0.0, // no bezier curve for now + tension: 0, // no bezier curve for now spanGaps: true } }); @@ -1471,36 +1013,6 @@ describe('Chart.elements.Line', function() { var expected = [{ name: 'save', args: [] - }, { - name: 'beginPath', - args: [] - }, { - name: 'moveTo', - args: [0, 2] - }, { - name: 'lineTo', - args: [5, 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: [19, 2] - }, { - name: 'setFillStyle', - args: ['rgba(0,0,0,0.1)'] - }, { - name: 'closePath', - args: [] - }, { - name: 'fill', - args: [] }, { name: 'setLineCap', args: ['butt'] @@ -1528,11 +1040,11 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [5, 0] }, { - name: 'bezierCurveTo', - args: [5, 0, 15, -10, 15, -10] + name: 'lineTo', + args: [15, -10] }, { - name: 'bezierCurveTo', - args: [15, -10, 19, -5, 19, -5] + name: 'lineTo', + args: [19, -5] }, { name: 'stroke', args: [] @@ -1605,8 +1117,7 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: true, - scaleZero: 2, // for filling lines - tension: 0.0, // no bezier curve for now + tension: 0, // no bezier curve for now } }); @@ -1615,36 +1126,6 @@ describe('Chart.elements.Line', function() { 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: 'lineTo', - args: [15, 2] - }, { - name: 'lineTo', - args: [15, 2] - }, { - name: 'setFillStyle', - args: ['rgba(0,0,0,0.1)'] - }, { - name: 'closePath', - args: [] - }, { - name: 'fill', - args: [] }, { name: 'setLineCap', args: ['butt'] @@ -1672,11 +1153,11 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [0, 10] }, { - name: 'bezierCurveTo', - args: [0, 10, 5, 0, 5, 0] + name: 'lineTo', + args: [5, 0] }, { - name: 'bezierCurveTo', - args: [5, 0, 15, -10, 15, -10] + name: 'lineTo', + args: [15, -10] }, { name: 'stroke', args: [] @@ -1749,8 +1230,7 @@ describe('Chart.elements.Line', function() { // Need to provide some settings _view: { fill: true, - scaleZero: 2, // for filling lines - tension: 0.0, // no bezier curve for now + tension: 0, // no bezier curve for now spanGaps: true } }); @@ -1760,33 +1240,6 @@ describe('Chart.elements.Line', function() { 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: 'lineTo', - args: [15, 2] - }, { - name: 'setFillStyle', - args: ['rgba(0,0,0,0.1)'] - }, { - name: 'closePath', - args: [] - }, { - name: 'fill', - args: [] }, { name: 'setLineCap', args: ['butt'] @@ -1814,11 +1267,11 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [0, 10] }, { - name: 'bezierCurveTo', - args: [0, 10, 5, 0, 5, 0] + name: 'lineTo', + args: [5, 0] }, { - name: 'bezierCurveTo', - args: [5, 0, 15, -10, 15, -10] + name: 'lineTo', + args: [15, -10] }, { name: 'stroke', args: [] @@ -1893,11 +1346,7 @@ describe('Chart.elements.Line', function() { // 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 - }, + tension: 0, // no bezier curve for now } }); @@ -1906,36 +1355,6 @@ describe('Chart.elements.Line', 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'] @@ -1963,17 +1382,17 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [0, 10] }, { - name: 'bezierCurveTo', - args: [0, 10, 5, 0, 5, 0] + name: 'lineTo', + args: [5, 0] }, { - name: 'bezierCurveTo', - args: [5, 0, 15, -10, 15, -10] + name: 'lineTo', + args: [15, -10] }, { - name: 'bezierCurveTo', - args: [15, -10, 19, -5, 19, -5] + name: 'lineTo', + args: [19, -5] }, { - name: 'bezierCurveTo', - args: [19, -5, 0, 10, 0, 10] + name: 'lineTo', + args: [0, 10] }, { name: 'stroke', args: [], @@ -2048,11 +1467,7 @@ describe('Chart.elements.Line', function() { // 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 - }, + tension: 0, // no bezier curve for now } }); @@ -2061,36 +1476,6 @@ describe('Chart.elements.Line', function() { 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'] @@ -2121,11 +1506,11 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [15, -10] }, { - name: 'bezierCurveTo', - args: [15, -10, 19, -5, 19, -5] + name: 'lineTo', + args: [19, -5] }, { - name: 'bezierCurveTo', - args: [19, -5, 0, 10, 0, 10] + name: 'lineTo', + args: [0, 10] }, { name: 'stroke', args: [], @@ -2200,11 +1585,7 @@ describe('Chart.elements.Line', function() { // 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 - }, + tension: 0, // no bezier curve for now spanGaps: true } }); @@ -2214,33 +1595,6 @@ describe('Chart.elements.Line', 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, 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'] @@ -2268,14 +1622,14 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [0, 10] }, { - name: 'bezierCurveTo', - args: [0, 10, 15, -10, 15, -10] + name: 'lineTo', + args: [15, -10] }, { - name: 'bezierCurveTo', - args: [15, -10, 19, -5, 19, -5] + name: 'lineTo', + args: [19, -5] }, { - name: 'bezierCurveTo', - args: [19, -5, 0, 10, 0, 10] + name: 'lineTo', + args: [0, 10] }, { name: 'stroke', args: [], @@ -2350,11 +1704,7 @@ describe('Chart.elements.Line', function() { // 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 - }, + tension: 0, // no bezier curve for now } }); @@ -2363,33 +1713,6 @@ describe('Chart.elements.Line', function() { 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'] @@ -2417,11 +1740,11 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [5, 0] }, { - name: 'bezierCurveTo', - args: [5, 0, 15, -10, 15, -10] + name: 'lineTo', + args: [15, -10] }, { - name: 'bezierCurveTo', - args: [15, -10, 19, -5, 19, -5] + name: 'lineTo', + args: [19, -5] }, { name: 'stroke', args: [], @@ -2496,11 +1819,7 @@ describe('Chart.elements.Line', function() { // 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 - }, + tension: 0, // no bezier curve for now } }); @@ -2509,36 +1828,6 @@ describe('Chart.elements.Line', 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: 'lineTo', - args: [3, 2] - }, { - name: 'lineTo', - args: [0, 10] - }, { - name: 'setFillStyle', - args: ['rgba(0,0,0,0.1)'] - }, { - name: 'closePath', - args: [] - }, { - name: 'fill', - args: [] }, { name: 'setLineCap', args: ['butt'] @@ -2566,11 +1855,11 @@ describe('Chart.elements.Line', function() { name: 'moveTo', args: [0, 10] }, { - name: 'bezierCurveTo', - args: [0, 10, 5, 0, 5, 0] + name: 'lineTo', + args: [5, 0] }, { - name: 'bezierCurveTo', - args: [5, 0, 15, -10, 15, -10] + name: 'lineTo', + args: [15, -10] }, { name: 'moveTo', args: [0, 10] diff --git a/test/specs/global.deprecations.tests.js b/test/specs/global.deprecations.tests.js index 63f383ed6..3c21d784a 100644 --- a/test/specs/global.deprecations.tests.js +++ b/test/specs/global.deprecations.tests.js @@ -86,6 +86,27 @@ describe('Deprecations', function() { }, 200); }); }); + + describe('Chart.elements.Line: fill option', function() { + it('should decode "zero", "top" and "bottom" as "origin", "start" and "end"', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: 'zero'}, + {fill: 'bottom'}, + {fill: 'top'}, + ] + } + }); + + ['origin', 'start', 'end'].forEach(function(expected, index) { + var meta = chart.getDatasetMeta(index); + expect(meta.$filler).toBeDefined(); + expect(meta.$filler.fill).toBe(expected); + }); + }); + }); }); describe('Version 2.5.0', function() { diff --git a/test/specs/plugin.filler.tests.js b/test/specs/plugin.filler.tests.js new file mode 100644 index 000000000..117f68036 --- /dev/null +++ b/test/specs/plugin.filler.tests.js @@ -0,0 +1,265 @@ +describe('Plugin.filler', function() { + function decodedFillValues(chart) { + return chart.data.datasets.map(function(dataset, index) { + var meta = chart.getDatasetMeta(index) || {}; + expect(meta.$filler).toBeDefined(); + return meta.$filler.fill; + }); + } + + describe('auto', jasmine.specsFromFixtures('plugin.filler')); + + describe('dataset.fill', function() { + it('should support boundaries', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: 'origin'}, + {fill: 'start'}, + {fill: 'end'}, + ] + } + }); + + expect(decodedFillValues(chart)).toEqual(['origin', 'start', 'end']); + }); + + it('should support absolute dataset index', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: 1}, + {fill: 3}, + {fill: 0}, + {fill: 2}, + ] + } + }); + + expect(decodedFillValues(chart)).toEqual([1, 3, 0, 2]); + }); + + it('should support relative dataset index', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: '+3'}, + {fill: '-1'}, + {fill: '+1'}, + {fill: '-2'}, + ] + } + }); + + expect(decodedFillValues(chart)).toEqual([ + 3, // 0 + 3 + 0, // 1 - 1 + 3, // 2 + 1 + 1, // 3 - 2 + ]); + }); + + it('should handle default fill when true (origin)', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: true}, + {fill: false}, + ] + } + }); + + expect(decodedFillValues(chart)).toEqual(['origin', false]); + }); + + it('should ignore self dataset index', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: 0}, + {fill: '-0'}, + {fill: '+0'}, + {fill: 3}, + ] + } + }); + + expect(decodedFillValues(chart)).toEqual([ + false, // 0 === 0 + false, // 1 === 1 - 0 + false, // 2 === 2 + 0 + false, // 3 === 3 + ]); + }); + + it('should ignore out of bounds dataset index', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: -2}, + {fill: 4}, + {fill: '-3'}, + {fill: '+1'}, + ] + } + }); + + expect(decodedFillValues(chart)).toEqual([ + false, // 0 - 2 < 0 + false, // 1 + 4 > 3 + false, // 2 - 3 < 0 + false, // 3 + 1 > 3 + ]); + }); + + it('should ignore invalid values', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: 'foo'}, + {fill: '+foo'}, + {fill: '-foo'}, + {fill: '+1.1'}, + {fill: '-2.2'}, + {fill: 3.3}, + {fill: -4.4}, + {fill: NaN}, + {fill: Infinity}, + {fill: ''}, + {fill: null}, + {fill: []}, + {fill: {}}, + {fill: function() {}} + ] + } + }); + + expect(decodedFillValues(chart)).toEqual([ + false, // NaN (string) + false, // NaN (string) + false, // NaN (string) + false, // float (string) + false, // float (string) + false, // float (number) + false, // float (number) + false, // NaN + false, // !isFinite + false, // empty string + false, // null + false, // array + false, // object + false, // function + ]); + }); + }); + + describe('options.plugins.filler.propagate', function() { + it('should compute propagated fill targets if true', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: 'start', hidden: true}, + {fill: '-1', hidden: true}, + {fill: 1, hidden: true}, + {fill: '-2', hidden: true}, + {fill: '+1'}, + {fill: '+2'}, + {fill: '-1'}, + {fill: 'end', hidden: true}, + ] + }, + options: { + plugins: { + filler: { + propagate: true + } + } + } + }); + + + expect(decodedFillValues(chart)).toEqual([ + 'start', // 'start' + 'start', // 1 - 1 -> 0 (hidden) -> 'start' + 'start', // 1 (hidden) -> 0 (hidden) -> 'start' + 'start', // 3 - 2 -> 1 (hidden) -> 0 (hidden) -> 'start' + 5, // 4 + 1 + 'end', // 5 + 2 -> 7 (hidden) -> 'end' + 5, // 6 - 1 -> 5 + 'end', // 'end' + ]); + }); + + it('should preserve initial fill targets if false', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: 'start', hidden: true}, + {fill: '-1', hidden: true}, + {fill: 1, hidden: true}, + {fill: '-2', hidden: true}, + {fill: '+1'}, + {fill: '+2'}, + {fill: '-1'}, + {fill: 'end', hidden: true}, + ] + }, + options: { + plugins: { + filler: { + propagate: false + } + } + } + }); + + expect(decodedFillValues(chart)).toEqual([ + 'start', // 'origin' + 0, // 1 - 1 + 1, // 1 + 1, // 3 - 2 + 5, // 4 + 1 + 7, // 5 + 2 + 5, // 6 - 1 + 'end', // 'end' + ]); + }); + + it('should prevent recursive propagation', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [ + {fill: '+2', hidden: true}, + {fill: '-1', hidden: true}, + {fill: '-1', hidden: true}, + {fill: '-2'} + ] + }, + options: { + plugins: { + filler: { + propagate: true + } + } + } + }); + + expect(decodedFillValues(chart)).toEqual([ + false, // 0 + 2 -> 2 (hidden) -> 1 (hidden) -> 0 (loop) + false, // 1 - 1 -> 0 (hidden) -> 2 (hidden) -> 1 (loop) + false, // 2 - 1 -> 1 (hidden) -> 0 (hidden) -> 2 (loop) + false, // 3 - 2 -> 1 (hidden) -> 0 (hidden) -> 2 (hidden) -> 1 (loop) + ]); + }); + }); +}); -- 2.47.3