Skip to content

Commit

Permalink
Add support to fill between datasets
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
simonbrunel committed Mar 11, 2017
1 parent 1ca0ffb commit 25d9b43
Show file tree
Hide file tree
Showing 48 changed files with 1,447 additions and 970 deletions.
60 changes: 60 additions & 0 deletions samples/filler/analyser.js
Original file line number Diff line number Diff line change
@@ -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; i<ilen; ++i) {
meta = chart.getDatasetMeta(i)._filler;
if (meta) {
dataset = datasets[i];
stats.push({
fill: dataset.fill,
target: meta.fill,
visible: meta.visible,
index: i
});
}
}

this.element.innerHTML = '<table>' + stats.map(function(stat) {
var target = stat.target;
var row =
'<td style="padding-right:8px"><b>Dataset ' + stat.index + '</b></td>' +
'<td style="width:128px">fill: ' + JSON.stringify(stat.fill) + '</td>';

if (target === false) {
target = 'none';
} else if (isFinite(target)) {
target = 'dataset ' + target;
} else {
target = 'boundary "' + target + '"';
}

if (stat.visible) {
row += '<td style="width:256px">target: ' + target + '</td>';
} else {
row += '<td style="width:128px">(hidden)</td>';
}

return '<tr>' + row + '</tr>';
}).join('') + '</table>';
}
});
}());
151 changes: 151 additions & 0 deletions samples/filler/line.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<!doctype html>
<html>
<head>
<title>filler > line | Chart.js example</title>
<link rel="stylesheet" type="text/css" href="../style.css">
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<script src="analyser.js"></script>
</head>
<body>
<div class="content">
<div class="wrapper">
<canvas id="chart-canvas"></canvas>
</div>
<div class="toolbar">
<button onclick="togglePropagate(this)">Propagate</button>
<button onclick="toggleSmooth(this)">Smooth</button>
<button onclick="randomize(this)">Randomize</button>
</div>
<code id="chart-analyser"></code>
</div>

<script>
var utils = Samples.utils;
var inputs = {
min: 20,
max: 80,
count: 8,
decimals: 2,
continuity: 1
};

function generateData() {
return utils.numbers(inputs);
}

function generateLabels(config) {
return utils.months({count: inputs.count});
}

utils.srand(42);

var presets = window.chartColors;
var data = {
labels: generateLabels(),
datasets: [{
backgroundColor: utils.transparentize(presets.red),
borderColor: presets.red,
data: generateData(),
label: 'D0'
}, {
backgroundColor: utils.transparentize(presets.orange),
borderColor: presets.orange,
data: generateData(),
label: 'D1',
fill: 0
}, {
backgroundColor: utils.transparentize(presets.yellow),
borderColor: presets.yellow,
data: generateData(),
label: 'D2',
fill: '-2'
}, {
backgroundColor: utils.transparentize(presets.green),
borderColor: presets.green,
data: generateData(),
label: 'D3',
fill: false
}, {
backgroundColor: utils.transparentize(presets.blue),
borderColor: presets.blue,
data: generateData(),
label: 'D4',
fill: '+1'
}, {
backgroundColor: utils.transparentize(presets.purple),
borderColor: presets.purple,
data: generateData(),
label: 'D5',
fill: '-1'
}, {
backgroundColor: utils.transparentize(presets.grey),
borderColor: presets.grey,
data: generateData(),
label: 'D6',
fill: '+1'
}, {
backgroundColor: utils.transparentize(presets.red),
borderColor: presets.red,
data: generateData(),
label: 'D7',
fill: 8
}, {
backgroundColor: utils.transparentize(presets.orange),
borderColor: presets.orange,
data: generateData(),
label: 'D8',
fill: 'end'
}]
};

var options = {
maintainAspectRatio: false,
spanGaps: false,
elements: {
line: {
tension: 0.000001
}
},
scales: {
yAxes: [{
stacked: true
}]
},
plugins: {
filler: {
propagate: false
},
samples_filler_analyser: {
target: 'chart-analyser'
}
}
};

var chart = new Chart('chart-canvas', {
type: 'line',
data: data,
options: options
});

function togglePropagate(btn) {
var value = btn.classList.toggle('btn-on');
chart.options.plugins.filler.propagate = value;
chart.update();
}

function toggleSmooth(btn) {
var value = btn.classList.toggle('btn-on');
chart.options.elements.line.tension = value? 0.4 : 0.000001;
chart.update();
}

function randomize() {
chart.data.datasets.forEach(function(dataset) {
dataset.data = generateData();
});
chart.update();
}
</script>
</body>
</html>
132 changes: 132 additions & 0 deletions samples/filler/radar.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<!doctype html>
<html>
<head>
<title>filler > radar | Chart.js example</title>
<link rel="stylesheet" type="text/css" href="../style.css">
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<script src="analyser.js"></script>
</head>
<body>
<div class="content">
<div class="wrapper" style="max-width: 512px; margin: auto">
<canvas id="chart-canvas"></canvas>
</div>
<div class="toolbar">
<button onclick="togglePropagate(this)">Propagate</button>
<button onclick="toggleSmooth(this)">Smooth</button>
<button onclick="randomize(this)">Randomize</button>
</div>
<code id="chart-analyser"></code>
</div>

<script>
var utils = Samples.utils;
var inputs = {
min: 8,
max: 16,
count: 8,
decimals: 2,
continuity: 1
};

function generateData() {
// radar chart doesn't support stacked values, let's do it manually
var values = utils.numbers(inputs);
inputs.from = values;
return values;
}

function generateLabels(config) {
return utils.months({count: inputs.count});
}

utils.srand(42);

var presets = window.chartColors;
var data = {
labels: generateLabels(),
datasets: [{
backgroundColor: utils.transparentize(presets.red),
borderColor: presets.red,
data: generateData(),
label: 'D0'
}, {
backgroundColor: utils.transparentize(presets.orange),
borderColor: presets.orange,
data: generateData(),
label: 'D1',
fill: 0
}, {
backgroundColor: utils.transparentize(presets.yellow),
borderColor: presets.yellow,
data: generateData(),
label: 'D2',
fill: '-2'
}, {
backgroundColor: utils.transparentize(presets.green),
borderColor: presets.green,
data: generateData(),
label: 'D3',
fill: false
}, {
backgroundColor: utils.transparentize(presets.blue),
borderColor: presets.blue,
data: generateData(),
label: 'D4',
fill: '-1'
}, {
backgroundColor: utils.transparentize(presets.purple),
borderColor: presets.purple,
data: generateData(),
label: 'D5',
fill: '-1'
}]
};

var options = {
maintainAspectRatio: true,
spanGaps: false,
elements: {
line: {
tension: 0.000001
}
},
plugins: {
filler: {
propagate: false
},
samples_filler_analyser: {
target: 'chart-analyser'
}
}
};

var chart = new Chart('chart-canvas', {
type: 'radar',
data: data,
options: options
});

function togglePropagate(btn) {
var value = btn.classList.toggle('btn-on');
chart.options.plugins.filler.propagate = value;
chart.update();
}

function toggleSmooth(btn) {
var value = btn.classList.toggle('btn-on');
chart.options.elements.line.tension = value? 0.4 : 0.000001;
chart.update();
}

function randomize() {
inputs.from = [];
chart.data.datasets.forEach(function(dataset) {
dataset.data = generateData();
});
chart.update();
}
</script>
</body>
</html>
43 changes: 43 additions & 0 deletions samples/style.css
Original file line number Diff line number Diff line change
@@ -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;
}
Loading

0 comments on commit 25d9b43

Please sign in to comment.