ng2-charts
ng2-charts copied to clipboard
Data Decimation not working
Reproduction of the problem
TS file
import { Component, ViewChild } from '@angular/core';
import { BaseChartDirective } from 'ng2-charts';
import 'chartjs-adapter-moment';
function randNumGen(max) {
return Math.floor((Math.random() * max) + 1)
}
const NUM_POINTS = 10000;
const START = 1617235200000;
const POINT_DATA = [];
for (let i = 0; i < NUM_POINTS; ++i) {
const max = Math.random() < 0.001 ? 100 : 20;
const randNumber = randNumGen(max)
POINT_DATA.push({ x: START + i * 30000, y: randNumber });
}
@Component({
selector: 'app-line-chart',
templateUrl: './line-chart.component.html',
styleUrls: ['./line-chart.component.css']
})
export class LineChartComponent {
@ViewChild(BaseChartDirective) chart?: BaseChartDirective;
data = {
datasets: [
{
borderColor: "red",
borderWidth: 1,
data: POINT_DATA,
label: "Large Dataset",
radius: 0,
},
],
};
plugins = {
decimation: {
enabled: false,
algorithm: 'min-max',
},
}
options = {
animation: false,
parsing: false,
interaction: {
mode: "nearest",
axis: "x",
intersect: false,
},
scales: {
x: {
type: "time",
ticks: {
source: "auto",
maxRotation: 0,
autoSkip: true,
},
},
},
}
public buttonOnclick() {
this.plugins.decimation.enabled = true;
this.plugins.decimation.algorithm = 'min-max';
this.chart.chart.update();
}
}
Template HTML
<div class="flex">
<div class="flex-item">
<div style="display: block">
<canvas
baseChart
width="400"
height="400"
[data]="data"
[options]="options"
[type]="'line'"
[plugins]="plugins"
></canvas>
</div>
</div>
<button (click)="buttonOnclick()">
Decimation {{ plugins.decimation.enabled }}
</button>
</div>
Versions
Package | Version |
---|---|
chart.js | 3.7.1 |
ng2-charts | 3.0.8 |
chartjs-adapter-date-fns | 2.0.0 |
chartjs-adapter-luxon | 1.1.0 |
chartjs-adapter-moment | 1.0.0 |
Angular Version: 12.1.1
@noobnoobdc137 - You mind putting this in a stackblitz or codesandbox for all of us?
Not working for me either. Ideally, a simple way to have it would be;
public lineChartOptions: ChartConfiguration['options'] = {
elements: {
line: {
tension: 0.5
}
},
scales: {
x: {},
'y-axis-0':
{
position: 'left',
reverse: this.reverseInput
},
},
plugins: {
legend: { display: true },
decimation: {
enabled: true,
algorithm: 'lttb',
samples:50
},
}
};
And pass those option to the chart
<canvas baseChart
[data]="lineChartData"
[options]="lineChartOptions"
[type]="lineChartType"></canvas>
My line chart has too many points crowding the line. It would be great to 'thin the herd' with this simple plugin.
Probably decimation needs a re-render of the chart? Can you try using this.chart.render();
or setting the decimation.enabled
to true
from the start to see if it makes any difference?
Did anybody get this to work? I am having the same problem. My data gets rendered but decimation is not applied.
Any updates on this? I'm running into a similar issue
I did get it to work, but it took some fiddling. I preprocessed my data to not need any interpolation by converting my x axis from an ISO Date to Milliseconds, that did the trick. I used luxon and the luxon chart.js adapter for the conversion and formatting.
This is the code I applied to activate decimation:
plugins: {
// ...
decimation: {
algorithm: 'lttb',
enabled: true,
samples: 100,
threshold: 40,
},
// ...
}
For display purposes I formatted the date like this:
scales: {
x: {
type: 'time',
time: {
displayFormats: {
month: 'MMM ‘yy',
},
},
},
// ...
}
Hope it helps.
Hope it helps.
Thank you.
I realized that threshold
must be specified for small values. In my case it's
{
...
decimation: {
algorithm: 'lttb',
enabled: true,
samples: 25,
threshold: 25,
}
}
and it didn't work unless explicitly stated