Skip to content

Commit

Permalink
feat: datasetIdKey prop (#848)
Browse files Browse the repository at this point in the history
datasetIdKey prop added to track datasets changes
  • Loading branch information
dangreen authored Nov 8, 2021
1 parent 6a9b2a7 commit f895766
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .size-limit
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[
{
"path": "dist/index.cjs",
"limit": "1.6 KB",
"limit": "1.7 KB",
"webpack": false,
"running": false
},
Expand Down
5 changes: 3 additions & 2 deletions src/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ function ChartComponent<
height = 150,
width = 300,
redraw = false,
datasetIdKey,
type,
data,
options,
Expand All @@ -40,7 +41,7 @@ function ChartComponent<

chartRef.current = new ChartJS(canvasRef.current, {
type,
data: cloneData(data),
data: cloneData(data, datasetIdKey),
options,
plugins,
});
Expand Down Expand Up @@ -71,7 +72,7 @@ function ChartComponent<

useEffect(() => {
if (!redraw && chartRef.current && data.datasets) {
setDatasets(chartRef.current.config.data, data.datasets);
setDatasets(chartRef.current.config.data, data.datasets, datasetIdKey);
}
}, [redraw, data.datasets]);

Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface ChartProps<
options?: ChartOptions<TType>;
plugins?: Plugin<TType>[];
redraw?: boolean;
datasetIdKey?: string;
/**
* @todo Replace with `children` prop.
*/
Expand Down
24 changes: 18 additions & 6 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import type {
Chart,
} from 'chart.js';

const defaultDatasetIdKey = 'label';

export function reforwardRef<T>(ref: ForwardedRef<T>, value: T) {
if (typeof ref === 'function') {
ref(value);
Expand Down Expand Up @@ -41,17 +43,27 @@ export function setDatasets<
TLabel = unknown
>(
currentData: ChartData<TType, TData, TLabel>,
nextDatasets: ChartDataset<TType, TData>[]
nextDatasets: ChartDataset<TType, TData>[],
datasetIdKey = defaultDatasetIdKey
) {
const addedDatasets: ChartDataset<TType, TData>[] = [];

currentData.datasets = nextDatasets.map(nextDataset => {
// given the new set, find it's current match
const currentDataset = currentData.datasets.find(
dataset =>
dataset.label === nextDataset.label && dataset.type === nextDataset.type
dataset => dataset[datasetIdKey] === nextDataset[datasetIdKey]
);

// There is no original to update, so simply add new one
if (!currentDataset || !nextDataset.data) return { ...nextDataset };
if (
!currentDataset ||
!nextDataset.data ||
addedDatasets.includes(currentDataset)
) {
return { ...nextDataset };
}

addedDatasets.push(currentDataset);

Object.assign(currentDataset, nextDataset);

Expand All @@ -63,14 +75,14 @@ export function cloneData<
TType extends ChartType = ChartType,
TData = DefaultDataPoint<TType>,
TLabel = unknown
>(data: ChartData<TType, TData, TLabel>) {
>(data: ChartData<TType, TData, TLabel>, datasetIdKey = defaultDatasetIdKey) {
const nextData: ChartData<TType, TData, TLabel> = {
labels: [],
datasets: [],
};

setLabels(nextData, data.labels);
setDatasets(nextData, data.datasets);
setDatasets(nextData, data.datasets, datasetIdKey);

return nextData;
}
Expand Down
62 changes: 62 additions & 0 deletions test/chart.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,66 @@ describe('<Chart />', () => {

expect(chart.canvas.getAttribute('aria-label')).toBe(ariaLabel);
});

it('should rerender datasets with same labels', () => {
const getData = () => ({
labels: [1, 2, 3],
datasets: [
{
label: '',
data: [5, 6, 7],
},
{
label: '',
data: [3, 2, 1],
},
],
});

const { rerender } = render(
<Chart ref={ref} type='line' data={getData()} />
);

const [prevDataset1, prevDataset2] = chart.config.data.datasets;

rerender(<Chart ref={ref} type='line' data={getData()} />);

const [nextDataset1, nextDataset2] = chart.config.data.datasets;

expect(prevDataset1).toBe(nextDataset1);
expect(prevDataset2).not.toBe(nextDataset2);
});

it('should rerender datasets with id', () => {
const getData = () => ({
labels: [1, 2, 3],
datasets: [
{
id: 1,
label: '',
data: [5, 6, 7],
},
{
id: 2,
label: '',
data: [3, 2, 1],
},
],
});

const { rerender } = render(
<Chart ref={ref} datasetIdKey='id' type='line' data={getData()} />
);

const [prevDataset1, prevDataset2] = chart.config.data.datasets;

rerender(
<Chart ref={ref} datasetIdKey='id' type='line' data={getData()} />
);

const [nextDataset1, nextDataset2] = chart.config.data.datasets;

expect(prevDataset1).toBe(nextDataset1);
expect(prevDataset2).toBe(nextDataset2);
});
});

0 comments on commit f895766

Please sign in to comment.