Support spanGaps in radar charts (#6289)

* Support spanGaps in radar charts

* Minor fixes based on feedback
This commit is contained in:
Akihiko Kusanagi
2019-06-19 19:12:53 +08:00
committed by Evert Timberg
parent d81914ea29
commit e3e80c9ac6
29 changed files with 307 additions and 48 deletions

View File

@@ -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
@@ -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

View File

@@ -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;
},
@@ -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);
}

View File

@@ -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
@@ -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) {
@@ -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;
}

View File

@@ -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);

View File

@@ -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": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -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
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -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": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -19,6 +19,7 @@
},
"options": {
"responsive": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {

View File

@@ -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
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -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
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -19,6 +19,7 @@
},
"options": {
"responsive": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {

View File

@@ -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": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -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": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,45 @@
{
"config": {
"type": "radar",
"data": {
"labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
"datasets": [{
"backgroundColor": "rgba(0, 0, 255, 0.25)",
"data": [null, null, 2, 3, 4, -4, -2, 1, 0]
}, {
"backgroundColor": "rgba(0, 255, 0, 0.25)",
"data": [6, 2, null, 4, 5, null, null, 2, 1]
}, {
"backgroundColor": "rgba(255, 0, 0, 0.25)",
"data": [7, 3, 4, 5, 6, 1, 4, null, null]
}, {
"backgroundColor": "rgba(0, 0, 255, 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": "start"
}
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 256
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -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": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -27,7 +27,8 @@
},
"options": {
"responsive": false,
"legend": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {
"display": false

View File

@@ -0,0 +1,53 @@
{
"config": {
"type": "radar",
"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],
"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,
"scale": {
"display": false
},
"elements": {
"point": {
"radius": 0
},
"line": {
"borderColor": "transparent",
"tension": 0
}
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 256
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -27,6 +27,7 @@
},
"options": {
"responsive": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {

View File

@@ -27,6 +27,7 @@
},
"options": {
"responsive": false,
"spanGaps": false,
"legend": false,
"title": false,
"scale": {