Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying spanGaps as number (max distance) #6993

Merged
merged 1 commit into from
Jan 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/moment@2.24.0/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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could add skip and stop to properties only if true. I'm wondering if it would improve performance to make the object smaller

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

};

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