How can I implement the custom property data structure for a dataset as mentioned below without hacking the index.esm.d.ts file?
I want to implement a custom dataset data structure similar to here in a line chart. I am doing this in Angular and using ng2-charts.
Pertinent library versions:
"@angular/core": "^14.2.0"
"@types/chart.js": "^2.9.37"
"chart.js": "^3.9.1"
"ng2-charts": "^4.0.1"
"typescript": "~4.7.2"
"tslib": "^2.3.0",
Here is a simplified version of the dataset data structure I want to implement:
data: [
{id: '1', nested: {value: 500, extra: 'one'}},
{id: '2', nested: {value: 1500, extra: 'two'}},
],
Unfortunately, I get the following typescript error when implementing this:
error TS2322: Type '{ id: string; nested: { value: number; extra: string; }; }' is not assignable to type 'number | ScatterDataPoint | BubbleDataPoint | null'.
If I modify the index.esm.d.ts file with a CustomDataPoint:
export interface CustomDataPoint {
id: string,
nested: {
value: number,
extra: string
}
}
export interface ChartTypeRegistry {
...
line: {
chartOptions: LineControllerChartOptions;
datasetOptions: LineControllerDatasetOptions & FillerControllerDatasetOptions;
defaultDataPoint: CustomDataPoint | ScatterDataPoint | number | null; //### modified
// defaultDataPoint: ScatterDataPoint | number | null; //### original
metaExtensions: {};
parsedDataType: CartesianParsedData;
scales: keyof CartesianScaleTypeRegistry;
};
...
}
I no longer get the typescript error. Yay! (;P)
How can I implement the custom property data structure for a dataset as mentioned above without hacking the index.esm.d.ts file?
Here is a minimal code set to reproduce this...
line-chart.component.ts:
import { Component, OnInit } from '@angular/core';
import {ChartConfiguration, ChartType} from "chart.js";
@Component({
selector: 'app-chart-one',
templateUrl: './chart-one.component.html',
styleUrls: ['./chart-one.component.css']
})
export class ChartOneComponent implements OnInit {
public chartData: ChartConfiguration['data'] = {
datasets: []
};
public chartOptions: ChartConfiguration['options'];
public chartType: ChartType = 'line';
constructor() {}
ngOnInit(): void {
this.chartData.datasets = [
{
data: [
{id: '1', nested: {value: 500, extra: 'one'}}, //TS Error here
{id: '2', nested: {value: 1500, extra: 'two'}}, //TS Error here
],
label: 'set 1',
borderColor: '#3cba9f',
fill: false,
}
]
this.chartOptions = {
responsive: true,
parsing: {
xAxisKey: 'id',
yAxisKey: 'nested.value'
},
};
}
}
line-chart.component.html:
<div style="display: block">
<canvas baseChart
[data]="chartData"
[options]="chartOptions"
[type]="chartType">
</canvas>
</div>
CodePudding user response:
As described in the docs here you can pass your own custom datatype:
import {ChartData} from 'chart.js';
const datasets: ChartData<'bar', {key: string, value: number} []> = {
datasets: [{
data: [{key: 'Sales', value: 20}, {key: 'Revenue', value: 10}],
parsing: {
xAxisKey: 'key',
yAxisKey: 'value'
}
}],
};