Skip to content

Commit

Permalink
Support spanGaps in radar charts (chartjs#6289)
Browse files Browse the repository at this point in the history
* Support spanGaps in radar charts

* Minor fixes based on feedback
  • Loading branch information
nagix authored and etimberg committed Jun 19, 2019
1 parent eb3050f commit 0316f3a
Show file tree
Hide file tree
Showing 29 changed files with 307 additions and 48 deletions.
4 changes: 3 additions & 1 deletion docs/charts/radar.md
Expand Up @@ -87,6 +87,7 @@ The radar chart allows a number of properties to be specified for each dataset.
| [`pointRadius`](#point-styling) | `number` | Yes | Yes | `3`
| [`pointRotation`](#point-styling) | `number` | Yes | Yes | `0`
| [`pointStyle`](#point-styling) | <code>string&#124;Image</code> | Yes | Yes | `'circle'`
| [`spanGaps`](#line-styling) | `boolean` | - | - | `undefined`

### General

Expand Down Expand Up @@ -125,8 +126,9 @@ The style of the line can be controlled with the following properties:
| `borderWidth` | The line width (in pixels).
| `fill` | How to fill the area under the line. See [area charts](area.md).
| `lineTension` | Bezier curve tension of the line. Set to 0 to draw straightlines.
| `spanGaps` | If true, lines will be drawn between points with no or null data. If false, points with `NaN` data will create a break in the line.

All these values, if `undefined`, fallback to the associated [`elements.line.*`](../configuration/elements.md#line-configuration) options.
If the value is `undefined`, `spanGaps` fallback to the associated [chart configuration options](#configuration-options). The rest of the values fallback to the associated [`elements.line.*`](../configuration/elements.md#line-configuration) options.

### Interactions

Expand Down
12 changes: 11 additions & 1 deletion src/controllers/controller.radar.js
Expand Up @@ -143,9 +143,12 @@ module.exports = DatasetController.extend({
*/
_resolveDatasetElementOptions: function() {
var me = this;
var config = me._config;
var options = me.chart.options;
var values = DatasetController.prototype._resolveDatasetElementOptions.apply(me, arguments);

values.tension = valueOrDefault(me._config.lineTension, me.chart.options.elements.line.tension);
values.spanGaps = valueOrDefault(config.spanGaps, options.spanGaps);
values.tension = valueOrDefault(config.lineTension, options.elements.line.tension);

return values;
},
Expand All @@ -157,6 +160,13 @@ module.exports = DatasetController.extend({
var points = meta.data || [];
var i, ilen, model, controlPoints;

// Only consider points that are drawn in case the spanGaps option is used
if (meta.dataset._model.spanGaps) {
points = points.filter(function(pt) {
return !pt._model.skip;
});
}

function capControlPoint(pt, min, max) {
return Math.max(Math.min(pt, max), min);
}
Expand Down
22 changes: 10 additions & 12 deletions src/elements/element.line.js
Expand Up @@ -38,17 +38,16 @@ module.exports = Element.extend({
var globalOptionLineElements = globalDefaults.elements.line;
var lastDrawnIndex = -1;
var closePath = me._loop;
var index, current, previous, currentVM;
var index, previous, currentVM;

if (me._loop && points.length) {
if (!spanGaps) {
for (index = points.length - 1; index >= 0; --index) {
// If the line has an open path, shift the point array
if (points[index]._view.skip) {
points = points.slice(index).concat(points.slice(0, index));
closePath = false;
break;
}
for (index = 0; index < points.length; ++index) {
previous = helpers.previousItem(points, index);
// If the line has an open path, shift the point array
if (!points[index]._view.skip && previous._view.skip) {
points = points.slice(index).concat(points.slice(0, index));
closePath = spanGaps;
break;
}
}
// If the line has a close path, add the first point again
Expand Down Expand Up @@ -77,9 +76,8 @@ module.exports = Element.extend({
lastDrawnIndex = -1;

for (index = 0; index < points.length; ++index) {
current = points[index];
previous = helpers.previousItem(points, index);
currentVM = current._view;
currentVM = points[index]._view;

// First point moves to it's starting position no matter what
if (index === 0) {
Expand All @@ -96,7 +94,7 @@ module.exports = Element.extend({
ctx.moveTo(currentVM.x, currentVM.y);
} else {
// Line to next point
helpers.canvas.lineTo(ctx, previous._view, current._view);
helpers.canvas.lineTo(ctx, previous._view, currentVM);
}
lastDrawnIndex = index;
}
Expand Down
9 changes: 7 additions & 2 deletions src/plugins/plugin.filler.js
Expand Up @@ -271,17 +271,22 @@ function doFill(ctx, points, mapper, view, color, loop) {
var curve1 = [];
var len0 = 0;
var len1 = 0;
var i, ilen, index, p0, p1, d0, d1;
var i, ilen, index, p0, p1, d0, d1, loopOffset;

ctx.beginPath();

for (i = 0, ilen = (count + !!loop); i < ilen; ++i) {
for (i = 0, ilen = count; i < ilen; ++i) {
index = i % count;
p0 = points[index]._view;
p1 = mapper(p0, index, view);
d0 = isDrawable(p0);
d1 = isDrawable(p1);

if (loop && loopOffset === undefined && d0) {
loopOffset = i + 1;
ilen = count + loopOffset;
}

if (d0 && d1) {
len0 = curve0.push(p0);
len1 = curve1.push(p1);
Expand Down
Expand Up @@ -5,20 +5,21 @@
"labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
"datasets": [{
"backgroundColor": "rgba(0, 0, 192, 0.25)",
"data": [null, null, 2, 4, 2, 1, -1, 1, 2]
"data": [null, null, 2, 3, 4, -4, -2, 1, 0]
}, {
"backgroundColor": "rgba(0, 192, 0, 0.25)",
"data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
"data": [5.5, 2, null, 4, 5, null, null, 2, 1]
}, {
"backgroundColor": "rgba(192, 0, 0, 0.25)",
"data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
"data": [7, 3, 4, 5, 6, 1, 4, null, null]
}, {
"backgroundColor": "rgba(128, 0, 128, 0.25)",
"data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
"backgroundColor": "rgba(0, 0, 192, 0.25)",
"data": [8, 7, 6.5, -6, -4, -6, 4, 5, 8]
}]
},
"options": {
"responsive": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions test/fixtures/plugin.filler/fill-radar-boundary-end-span.json
@@ -0,0 +1,45 @@
{
"config": {
"type": "radar",
"data": {
"labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
"datasets": [{
"backgroundColor": "rgba(0, 0, 192, 0.25)",
"data": [null, null, 2, 3, 4, -4, -2, 1, 0]
}, {
"backgroundColor": "rgba(0, 192, 0, 0.25)",
"data": [5.5, 2, null, 4, 5, null, null, 2, 1]
}, {
"backgroundColor": "rgba(192, 0, 0, 0.25)",
"data": [7, 3, 4, 5, 6, 1, 4, null, null]
}, {
"backgroundColor": "rgba(0, 0, 192, 0.25)",
"data": [8, 7, 6.5, -6, -4, -6, 4, 5, 8]
}]
},
"options": {
"responsive": false,
"spanGaps": true,
"legend": false,
"title": false,
"scale": {
"display": false
},
"elements": {
"point": {
"radius": 0
},
"line": {
"borderColor": "transparent",
"fill": "end"
}
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 256
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 6 additions & 5 deletions test/fixtures/plugin.filler/fill-radar-boundary-end.json
Expand Up @@ -5,20 +5,21 @@
"labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
"datasets": [{
"backgroundColor": "rgba(0, 0, 192, 0.25)",
"data": [null, null, 2, 4, 2, 1, -1, 1, 2]
"data": [null, null, 2, 3, 4, -4, -2, 1, 0]
}, {
"backgroundColor": "rgba(0, 192, 0, 0.25)",
"data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
"data": [5.5, 2, null, 4, 5, null, null, 2, 1]
}, {
"backgroundColor": "rgba(192, 0, 0, 0.25)",
"data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
"data": [7, 3, 4, 5, 6, 1, 4, null, null]
}, {
"backgroundColor": "rgba(128, 0, 128, 0.25)",
"data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
"backgroundColor": "rgba(0, 0, 192, 0.25)",
"data": [8, 7, 6.5, -6, -4, -6, 4, 5, 8]
}]
},
"options": {
"responsive": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {
Expand Down
Binary file modified test/fixtures/plugin.filler/fill-radar-boundary-end.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -19,6 +19,7 @@
},
"options": {
"responsive": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {
Expand Down
45 changes: 45 additions & 0 deletions test/fixtures/plugin.filler/fill-radar-boundary-origin-span.json
@@ -0,0 +1,45 @@
{
"config": {
"type": "radar",
"data": {
"labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
"datasets": [{
"backgroundColor": "rgba(0, 0, 192, 0.25)",
"data": [null, null, 2, 3, 4, -4, -2, 1, 0]
}, {
"backgroundColor": "rgba(0, 192, 0, 0.25)",
"data": [6, 2, null, 4, 5, null, null, 2, 1]
}, {
"backgroundColor": "rgba(192, 0, 0, 0.25)",
"data": [7, 3, 4, 5, 6, 1, 4, null, null]
}, {
"backgroundColor": "rgba(0, 64, 192, 0.25)",
"data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
}]
},
"options": {
"responsive": false,
"spanGaps": true,
"legend": false,
"title": false,
"scale": {
"display": false
},
"elements": {
"point": {
"radius": 0
},
"line": {
"borderColor": "transparent",
"fill": "origin"
}
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 256
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,46 @@
{
"config": {
"type": "radar",
"data": {
"labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
"datasets": [{
"backgroundColor": "rgba(0, 0, 192, 0.25)",
"data": [null, null, 2, 4, 2, 1, -1, 1, 2]
}, {
"backgroundColor": "rgba(0, 192, 0, 0.25)",
"data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
}, {
"backgroundColor": "rgba(192, 0, 0, 0.25)",
"data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
}, {
"backgroundColor": "rgba(128, 0, 128, 0.25)",
"data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
}]
},
"options": {
"responsive": false,
"spanGaps": true,
"legend": false,
"title": false,
"scale": {
"display": false
},
"elements": {
"point": {
"radius": 0
},
"line": {
"borderColor": "transparent",
"tension": 0.5,
"fill": "origin"
}
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 256
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -19,6 +19,7 @@
},
"options": {
"responsive": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {
Expand Down
11 changes: 6 additions & 5 deletions test/fixtures/plugin.filler/fill-radar-boundary-origin.json
Expand Up @@ -5,20 +5,21 @@
"labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
"datasets": [{
"backgroundColor": "rgba(0, 0, 192, 0.25)",
"data": [null, null, 2, 4, 2, 1, -1, 1, 2]
"data": [null, null, 2, 3, 4, -4, -2, 1, 0]
}, {
"backgroundColor": "rgba(0, 192, 0, 0.25)",
"data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
"data": [6, 2, null, 4, 5, null, null, 2, 1]
}, {
"backgroundColor": "rgba(192, 0, 0, 0.25)",
"data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
"data": [7, 3, 4, 5, 6, 1, 4, null, null]
}, {
"backgroundColor": "rgba(128, 0, 128, 0.25)",
"data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
"backgroundColor": "rgba(0, 64, 192, 0.25)",
"data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
}]
},
"options": {
"responsive": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {
Expand Down
Binary file modified test/fixtures/plugin.filler/fill-radar-boundary-origin.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -4,21 +4,22 @@
"data": {
"labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
"datasets": [{
"backgroundColor": "rgba(0, 0, 192, 0.25)",
"data": [null, null, 2, 4, 2, 1, -1, 1, 2]
"backgroundColor": "rgba(0, 0, 255, 0.25)",
"data": [null, null, 2, 3, 4, -4, -2, 1, 0]
}, {
"backgroundColor": "rgba(0, 192, 0, 0.25)",
"data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
"backgroundColor": "rgba(0, 255, 0, 0.25)",
"data": [6, 2, null, 4, 5, null, null, 2, 1]
}, {
"backgroundColor": "rgba(192, 0, 0, 0.25)",
"data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
"backgroundColor": "rgba(255, 0, 0, 0.25)",
"data": [7, 3, 4, 5, 6, 1, 4, null, null]
}, {
"backgroundColor": "rgba(128, 0, 128, 0.25)",
"data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
"backgroundColor": "rgba(0, 0, 255, 0.25)",
"data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
}]
},
"options": {
"responsive": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {
Expand Down
Binary file modified test/fixtures/plugin.filler/fill-radar-boundary-start-circular.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 0316f3a

Please sign in to comment.