Skip to content

Commit

Permalink
Allow specifying spanGaps as number (max distance)
Browse files Browse the repository at this point in the history
  • Loading branch information
kurkle committed Jan 21, 2020
1 parent fb19b77 commit d089cec
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 6 deletions.
4 changes: 2 additions & 2 deletions docs/charts/line.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ The line chart allows a number of properties to be specified for each dataset. T
| [`pointRotation`](#point-styling) | `number` | Yes | Yes | `0`
| [`pointStyle`](#point-styling) | <code>string&#124;Image</code> | Yes | Yes | `'circle'`
| [`showLine`](#line-styling) | `boolean` | - | - | `undefined`
| [`spanGaps`](#line-styling) | `boolean` | - | - | `undefined`
| [`spanGaps`](#line-styling) | <code>boolean&#124;number</code> | - | - | `undefined`
| [`steppedLine`](#stepped-line) | <code>boolean&#124;string</code> | - | - | `false`
| [`xAxisID`](#general) | `string` | - | - | first x axis
| [`yAxisID`](#general) | `string` | - | - | first y axis
Expand Down Expand Up @@ -124,7 +124,7 @@ The style of the line can be controlled with the following properties:
| `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. This option is ignored if monotone cubic interpolation is used.
| `showLine` | If false, the line is not drawn for this dataset.
| `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.
| `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. Can also be a number specifying the maximum gap length to span. The unit of the value depends on the scale used.

If the value is `undefined`, `showLine` and `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.

Expand Down
3 changes: 3 additions & 0 deletions samples/samples.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@
}, {
title: 'Line (point data)',
path: 'scales/time/line-point-data.html'
}, {
title: 'Line (break on 2 day gap)',
path: 'scales/time/line-max-span.html'
}, {
title: 'Time Series',
path: 'scales/time/financial.html'
Expand Down
150 changes: 150 additions & 0 deletions samples/scales/time/line-max-span.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<!doctype html>
<html>

<head>
<title>Time Scale Point Data</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/moment.min.js"></script>
<script src="../../../dist/Chart.min.js"></script>
<script src="../../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>

<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<br>
<br>
<button id="randomizeData">Randomize Data</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
function newDate(days) {
return moment().add(days, 'd').toDate();
}

function newDateString(days) {
return moment().add(days, 'd').format();
}

var color = Chart.helpers.color;
var config = {
type: 'line',
data: {
datasets: [{
label: 'Dataset with string point data',
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
borderColor: window.chartColors.red,
fill: false,
data: [{
x: newDateString(0),
y: randomScalingFactor()
}, {
x: newDateString(2),
y: randomScalingFactor()
}, {
x: newDateString(4),
y: randomScalingFactor()
}, {
x: newDateString(6),
y: randomScalingFactor()
}],
}, {
label: 'Dataset with date object point data',
backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),
borderColor: window.chartColors.blue,
fill: false,
data: [{
x: newDate(0),
y: randomScalingFactor()
}, {
x: newDate(2),
y: randomScalingFactor()
}, {
x: newDate(5),
y: randomScalingFactor()
}, {
x: newDate(6),
y: randomScalingFactor()
}]
}]
},
options: {
spanGaps: 1000 * 60 * 60 * 24 * 2, // 2 days
responsive: true,
title: {
display: true,
text: 'Chart.js Time - spanGaps: 172800000 (2 days in ms)'
},
scales: {
x: {
type: 'time',
display: true,
scaleLabel: {
display: true,
labelString: 'Date'
},
ticks: {
major: {
fontStyle: 'bold',
fontColor: '#FF0000'
}
}
},
y: {
display: true,
scaleLabel: {
display: true,
labelString: 'value'
}
}
}
}
};

window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myLine = new Chart(ctx, config);
};

document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data.forEach(function(dataObj) {
dataObj.y = randomScalingFactor();
});
});

window.myLine.update();
});
document.getElementById('addData').addEventListener('click', function() {
if (config.data.datasets.length > 0) {
config.data.datasets[0].data.push({
x: newDateString(config.data.datasets[0].data.length + 2),
y: randomScalingFactor()
});
config.data.datasets[1].data.push({
x: newDate(config.data.datasets[1].data.length + 2),
y: randomScalingFactor()
});

window.myLine.update();
}
});

document.getElementById('removeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data.pop();
});

window.myLine.update();
});
</script>
</body>

</html>
8 changes: 7 additions & 1 deletion src/controllers/controller.line.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ export default DatasetController.extend({
const firstOpts = me._resolveDataElementOptions(start, mode);
const sharedOptions = me._getSharedOptions(mode, points[start], firstOpts);
const includeOptions = me._includeOptions(mode, sharedOptions);
const spanGaps = valueOrDefault(me._config.spanGaps, me.chart.options.spanGaps);
const maxGapLength = helpers.math.isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY;
let prevParsed;

for (let i = 0; i < points.length; ++i) {
const index = start + i;
Expand All @@ -108,14 +111,17 @@ export default DatasetController.extend({
const properties = {
x,
y,
skip: isNaN(x) || isNaN(y)
skip: isNaN(x) || isNaN(y),
stop: i > 0 && (parsed.x - prevParsed.x) > maxGapLength
};

if (includeOptions) {
properties.options = me._resolveDataElementOptions(index, mode);
}

me._updateElement(point, index, properties, mode);

prevParsed = parsed;
}

me._updateSharedOptions(sharedOptions, mode);
Expand Down
6 changes: 3 additions & 3 deletions src/helpers/helpers.segment.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,11 @@ function solidSegments(points, start, max, loop) {

for (end = start + 1; end <= max; ++end) {
const cur = points[end % count];
if (cur.skip) {
if (cur.skip || cur.stop) {
if (!prev.skip) {
loop = false;
result.push({start: start % count, end: (end - 1) % count, loop});
start = last = null;
start = last = cur.stop ? end : null;
}
} else {
last = end;
Expand Down Expand Up @@ -218,7 +218,7 @@ export function _computeSegments(line) {
const loop = !!line._loop;
const {start, end} = findStartAndEnd(points, count, loop, spanGaps);

if (spanGaps) {
if (spanGaps === true) {
return [{start, end, loop}];
}

Expand Down

0 comments on commit d089cec

Please sign in to comment.