From 2b921529d3f0687bab60aaaff8fee498ea2fbf00 Mon Sep 17 00:00:00 2001 From: Simon Brunel Date: Sat, 11 Mar 2017 11:28:38 +0100 Subject: [PATCH] Add support to fill between datasets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 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 2 new examples (line and radar) 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/filler/analyser.js | 60 ++ samples/filler/line.html | 151 +++ samples/filler/radar.html | 132 +++ samples/style.css | 43 + samples/utils.js | 93 +- 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 ++++++ 48 files changed, 1447 insertions(+), 970 deletions(-) create mode 100644 samples/filler/analyser.js create mode 100644 samples/filler/line.html create mode 100644 samples/filler/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/filler/analyser.js b/samples/filler/analyser.js new file mode 100644 index 00000000000..8bfd3105f44 --- /dev/null +++ b/samples/filler/analyser.js @@ -0,0 +1,60 @@ +/* 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; iDataset ' + stat.index + '' + + 'fill: ' + 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: ' + target + ''; + } else { + row += '(hidden)'; + } + + return '' + row + ''; + }).join('') + ''; + } + }); +}()); diff --git a/samples/filler/line.html b/samples/filler/line.html new file mode 100644 index 00000000000..6d9543591e0 --- /dev/null +++ b/samples/filler/line.html @@ -0,0 +1,151 @@ + + + + filler > line | Chart.js example + + + + + + +
+
+ +
+
+ + + +
+ +
+ + + + diff --git a/samples/filler/radar.html b/samples/filler/radar.html new file mode 100644 index 00000000000..dd394353f77 --- /dev/null +++ b/samples/filler/radar.html @@ -0,0 +1,132 @@ + + + + filler > radar | Chart.js example + + + + + + +
+
+ +
+
+ + + +
+ +
+ + + + diff --git a/samples/style.css b/samples/style.css new file mode 100644 index 00000000000..e23005e7f04 --- /dev/null +++ b/samples/style.css @@ -0,0 +1,43 @@ +body, html { + font-family: sans-serif; + padding: 0; + margin: 0; +} + +code { + color: #333; + display: block; + margin: 8px 0; + padding: 8px; + white-space: pre-wrap; +} + +.content { + max-width: 800px; + margin: auto; + padding: 16px; +} + +.wrapper { + min-height: 400px; + padding: 16px 0; + position: relative; +} + +.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; +} diff --git a/samples/utils.js b/samples/utils.js index 34965ce66ca..42693dcb6c0 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,94 @@ 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; iR|FtK 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 literal 0 HcmV?d00001 diff --git a/test/fixtures/plugin.filler/fill-line-dataset-spline-span.json b/test/fixtures/plugin.filler/fill-line-dataset-spline-span.json new file mode 100644 index 00000000000..6f89e62c4bf --- /dev/null +++ b/test/fixtures/plugin.filler/fill-line-dataset-spline-span.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": true, + "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-span.png b/test/fixtures/plugin.filler/fill-line-dataset-spline-span.png new file mode 100644 index 0000000000000000000000000000000000000000..7fb4e403e4c30435e61755ad3121c701e52689cb GIT binary patch literal 25819 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 literal 0 HcmV?d00001 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 00000000000..55054f1f5b6 --- /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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 literal 0 HcmV?d00001 diff --git a/test/fixtures/plugin.filler/fill-line-dataset.json b/test/fixtures/plugin.filler/fill-line-dataset.json new file mode 100644 index 00000000000..d82bd7440b4 --- /dev/null +++ b/test/fixtures/plugin.filler/fill-line-dataset.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": { + "borderColor": "transparent", + "tension": 0 + } + } + } + }, + "options": { + "canvas": { + "height": 256, + "width": 512 + } + } +} diff --git a/test/fixtures/plugin.filler/fill-line-dataset.png b/test/fixtures/plugin.filler/fill-line-dataset.png new file mode 100644 index 0000000000000000000000000000000000000000..d8a7e09d3b7881bf1f7fe8620fa904f594182397 GIT binary patch literal 22331 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 UE~qqvAPL%JVQqeAy+_3V0jXP*J^%m! literal 0 HcmV?d00001 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 c22d8a6517c..8640adcf89c 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 172007943a7..fafe29791af 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 2341b403cd8..f1fe61facc5 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 4b9c1f696dc..8f621c96bb4 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 52d94cd377c..c4d1722b4ad 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 63f383ed6cd..3c21d784aac 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 00000000000..117f680360e --- /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) + ]); + }); + }); +});