@spteck/fluentui-react-charts 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fluentui-react-charts.cjs.development.js +2478 -2198
- package/dist/fluentui-react-charts.cjs.development.js.map +1 -1
- package/dist/fluentui-react-charts.cjs.production.min.js +1 -1
- package/dist/fluentui-react-charts.cjs.production.min.js.map +1 -1
- package/dist/fluentui-react-charts.esm.js +2479 -2200
- package/dist/fluentui-react-charts.esm.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/useChartFactory.d.ts +6 -0
- package/dist/hooks/{useGraphUtils.d.ts → useChartUtils.d.ts} +2 -5
- package/dist/hooks/useIndexedDBCache.d.ts +33 -0
- package/dist/index.d.ts +1 -0
- package/package.json +2 -1
- package/src/charts/BarChart/BarChart.tsx +2 -2
- package/src/charts/ComboChart/ComboChart.tsx +2 -2
- package/src/charts/Doughnut/DoughnutChart.tsx +2 -2
- package/src/charts/PieChart/PieChart.tsx +3 -3
- package/src/charts/areaChart/AreaChart.tsx +2 -2
- package/src/charts/barHorizontalChart/BarHotizontalChart.tsx +2 -2
- package/src/charts/bubbleChart/BubbleChart.tsx +2 -2
- package/src/charts/floatBarChart/FloatBarChart.tsx +2 -2
- package/src/charts/lineChart/LineChart.tsx +2 -2
- package/src/charts/polarChart/PolarChart.tsx +2 -2
- package/src/charts/radarChart/RadarChart.tsx +2 -2
- package/src/charts/scatterChart/ScatterChart.tsx +2 -2
- package/src/charts/stackedLineChart/StackedLineChart.tsx +2 -2
- package/src/charts/steamChart/SteamChart.tsx +2 -2
- package/src/components/dashboard/DashBoard.tsx +117 -21
- package/src/components/dashboard/ExampleDashboardUsage.tsx +1 -1
- package/src/components/dashboard/IDashboardProps.tsx +0 -2
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useChartFactory.tsx +136 -0
- package/src/hooks/{useGraphUtils.tsx → useChartUtils.tsx} +3 -130
- package/src/hooks/useIndexedDBCache.ts +122 -0
- package/src/hooks/useResponsiveLegend.ts +2 -2
- package/src/index.tsx +1 -0
- package/src/models/ICardChartContainer.tsx +0 -2
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Theme, webLightTheme } from "@fluentui/react-components";
|
|
2
|
+
|
|
3
|
+
import AreaChart from '../charts/areaChart/AreaChart';
|
|
4
|
+
import BarChart from '../charts/BarChart/BarChart';
|
|
5
|
+
import BarHorizontalChart from '../charts/barHorizontalChart/BarHotizontalChart';
|
|
6
|
+
import BubbleChart from '../charts/bubbleChart/BubbleChart';
|
|
7
|
+
import ComboChart from '../charts/ComboChart/ComboChart';
|
|
8
|
+
import DoughnutChart from '../charts/Doughnut/DoughnutChart';
|
|
9
|
+
import FloatingBarChart from '../charts/floatBarChart/FloatBarChart';
|
|
10
|
+
import { IChart } from "../models";
|
|
11
|
+
import LineChart from '../charts/lineChart/LineChart';
|
|
12
|
+
import PieChart from '../charts/PieChart/PieChart';
|
|
13
|
+
import PolarChart from '../charts/polarChart/PolarChart';
|
|
14
|
+
import RadarChart from '../charts/radarChart/RadarChart';
|
|
15
|
+
import React from 'react';
|
|
16
|
+
import ScatterChart from '../charts/scatterChart/ScatterChart';
|
|
17
|
+
import StackedLineChart from '../charts/stackedLineChart/StackedLineChart';
|
|
18
|
+
import SteamChart from '../charts/steamChart/SteamChart';
|
|
19
|
+
|
|
20
|
+
const chartProps = (chart: IChart) => ({
|
|
21
|
+
data: chart.data,
|
|
22
|
+
title: chart.title,
|
|
23
|
+
getPrimary: (d: any) => d.name,
|
|
24
|
+
getSecondary: (d: any) => d.value,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const getChartComponent = (chart: IChart, theme: Theme) => {
|
|
28
|
+
const { type } = chart;
|
|
29
|
+
const fuiTheme = theme ?? webLightTheme;
|
|
30
|
+
switch (type) {
|
|
31
|
+
case 'bar':
|
|
32
|
+
return <BarChart {...chartProps(chart)} stacked={false} theme={fuiTheme} />;
|
|
33
|
+
case 'line':
|
|
34
|
+
return <LineChart {...chartProps(chart)} theme={fuiTheme} />;
|
|
35
|
+
case 'area':
|
|
36
|
+
return <AreaChart {...chartProps(chart)} stacked={false} theme={fuiTheme} />;
|
|
37
|
+
|
|
38
|
+
case 'bar-horizontal':
|
|
39
|
+
return <BarHorizontalChart {...chartProps(chart)} stacked={true} theme={fuiTheme} />;
|
|
40
|
+
case 'bubble':
|
|
41
|
+
return (
|
|
42
|
+
<BubbleChart {...chartProps(chart)} getRadius={d => d.radius ?? 1} theme={fuiTheme} />
|
|
43
|
+
);
|
|
44
|
+
case 'multiple-axes':
|
|
45
|
+
return (
|
|
46
|
+
<ComboChart
|
|
47
|
+
{...chartProps(chart)}
|
|
48
|
+
theme={fuiTheme}
|
|
49
|
+
|
|
50
|
+
data={chart.data.map((series: any) => ({
|
|
51
|
+
label: series.label,
|
|
52
|
+
type: series.type ?? 'bar',
|
|
53
|
+
data: series.data,
|
|
54
|
+
yAxisID: series.secondaryAxisId,
|
|
55
|
+
|
|
56
|
+
}))}
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
case 'steam':
|
|
60
|
+
return <SteamChart {...chartProps(chart)} theme={fuiTheme} />;
|
|
61
|
+
case 'floating-bar':
|
|
62
|
+
return (
|
|
63
|
+
<FloatingBarChart
|
|
64
|
+
getRange={d => [d.min ?? 0, d.max ?? 0]}
|
|
65
|
+
{...chartProps(chart)}
|
|
66
|
+
theme={fuiTheme}
|
|
67
|
+
/>
|
|
68
|
+
);
|
|
69
|
+
case 'stacked-line':
|
|
70
|
+
return <StackedLineChart {...chartProps(chart)} theme={fuiTheme} />;
|
|
71
|
+
case 'doughnut':
|
|
72
|
+
return (
|
|
73
|
+
<DoughnutChart
|
|
74
|
+
getLabel={datum => datum.name}
|
|
75
|
+
getValue={datum => datum.value ?? 0}
|
|
76
|
+
{...chartProps(chart)}
|
|
77
|
+
theme={fuiTheme}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
case 'pie':
|
|
81
|
+
return (
|
|
82
|
+
<PieChart
|
|
83
|
+
getLabel={datum => datum.name}
|
|
84
|
+
getValue={datum => datum.value ?? 0}
|
|
85
|
+
showDataLabels={true}
|
|
86
|
+
{...chartProps(chart)}
|
|
87
|
+
theme={fuiTheme}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
case 'scatter':
|
|
91
|
+
return (
|
|
92
|
+
<ScatterChart
|
|
93
|
+
getX={d => {
|
|
94
|
+
if (typeof d.x === 'number') return d.x;
|
|
95
|
+
if (typeof d.x === 'string') return Number(d.x) || 0;
|
|
96
|
+
if (d.x instanceof Date) return d.x.getTime();
|
|
97
|
+
return 0;
|
|
98
|
+
}}
|
|
99
|
+
getY={d => (typeof d.y === 'number' ? d.y : 0)}
|
|
100
|
+
{...chartProps(chart)}
|
|
101
|
+
theme={fuiTheme}
|
|
102
|
+
showDataLabels={false}
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
case 'polar':
|
|
106
|
+
return (
|
|
107
|
+
<PolarChart
|
|
108
|
+
data={chart.data}
|
|
109
|
+
getLabel={d => d.name}
|
|
110
|
+
getValue={d => d.value ?? 0}
|
|
111
|
+
title={chart.title}
|
|
112
|
+
showDataLabels={true}
|
|
113
|
+
theme={fuiTheme}
|
|
114
|
+
/>
|
|
115
|
+
);
|
|
116
|
+
case 'radar':
|
|
117
|
+
return (
|
|
118
|
+
<RadarChart
|
|
119
|
+
data={chart.data}
|
|
120
|
+
getLabel={d => d.name}
|
|
121
|
+
getValue={d => d.value ?? 0}
|
|
122
|
+
title={chart.title}
|
|
123
|
+
theme={fuiTheme}
|
|
124
|
+
/>
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
default:
|
|
128
|
+
throw new Error(`Unsupported chart type: ${type}`);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const useChartFactory = () => {
|
|
133
|
+
return React.useMemo(() => ({
|
|
134
|
+
getChartComponent
|
|
135
|
+
}), []);
|
|
136
|
+
};
|
|
@@ -5,24 +5,8 @@ import {
|
|
|
5
5
|
TooltipModel,
|
|
6
6
|
TooltipOptions,
|
|
7
7
|
} from 'chart.js';
|
|
8
|
-
import { Theme, webLightTheme } from '@fluentui/react-components';
|
|
9
8
|
|
|
10
|
-
import
|
|
11
|
-
import BarChart from '../charts/BarChart/BarChart';
|
|
12
|
-
import BarHorizontalChart from '../charts/barHorizontalChart/BarHotizontalChart';
|
|
13
|
-
import BubbleChart from '../charts/bubbleChart/BubbleChart';
|
|
14
|
-
import ComboChart from '../charts/ComboChart/ComboChart';
|
|
15
|
-
import DoughnutChart from '../charts/Doughnut/DoughnutChart';
|
|
16
|
-
import FloatingBarChart from '../charts/floatBarChart/FloatBarChart';
|
|
17
|
-
import { IChart } from '../models/IChart';
|
|
18
|
-
import LineChart from '../charts/lineChart/LineChart';
|
|
19
|
-
import PieChart from '../charts/PieChart/PieChart';
|
|
20
|
-
import PolarChart from '../charts/polarChart/PolarChart';
|
|
21
|
-
import RadarChart from '../charts/radarChart/RadarChart';
|
|
22
|
-
import React from 'react';
|
|
23
|
-
import ScatterChart from '../charts/scatterChart/ScatterChart';
|
|
24
|
-
import StackedLineChart from '../charts/stackedLineChart/StackedLineChart';
|
|
25
|
-
import SteamChart from '../charts/steamChart/SteamChart';
|
|
9
|
+
import { Theme } from '@fluentui/react-components';
|
|
26
10
|
import { useMemo } from 'react';
|
|
27
11
|
|
|
28
12
|
/**
|
|
@@ -62,117 +46,7 @@ export const getFluentPalette = (_theme: Theme): string[] => [
|
|
|
62
46
|
'#79706e',
|
|
63
47
|
];
|
|
64
48
|
|
|
65
|
-
const chartProps = (chart: IChart) => ({
|
|
66
|
-
data: chart.data,
|
|
67
|
-
title: chart.title,
|
|
68
|
-
getPrimary: (d: any) => d.name,
|
|
69
|
-
getSecondary: (d: any) => d.value,
|
|
70
|
-
});
|
|
71
49
|
|
|
72
|
-
const getChartComponent = (chart: IChart, theme: Theme) => {
|
|
73
|
-
const { type } = chart;
|
|
74
|
-
const fuiTheme = theme ?? webLightTheme;
|
|
75
|
-
switch (type) {
|
|
76
|
-
case 'bar':
|
|
77
|
-
return <BarChart {...chartProps(chart)} stacked={false} theme={fuiTheme} />;
|
|
78
|
-
case 'line':
|
|
79
|
-
return <LineChart {...chartProps(chart)} theme={fuiTheme} />;
|
|
80
|
-
case 'area':
|
|
81
|
-
return <AreaChart {...chartProps(chart)} stacked={false} theme={fuiTheme} />;
|
|
82
|
-
|
|
83
|
-
case 'bar-horizontal':
|
|
84
|
-
return <BarHorizontalChart {...chartProps(chart)} stacked={true} theme={fuiTheme} />;
|
|
85
|
-
case 'bubble':
|
|
86
|
-
return (
|
|
87
|
-
<BubbleChart {...chartProps(chart)} getRadius={d => d.radius ?? 1} theme={fuiTheme} />
|
|
88
|
-
);
|
|
89
|
-
case 'multiple-axes':
|
|
90
|
-
return (
|
|
91
|
-
<ComboChart
|
|
92
|
-
{...chartProps(chart)}
|
|
93
|
-
theme={fuiTheme}
|
|
94
|
-
|
|
95
|
-
data={chart.data.map((series: any) => ({
|
|
96
|
-
label: series.label,
|
|
97
|
-
type: series.type ?? 'bar',
|
|
98
|
-
data: series.data,
|
|
99
|
-
yAxisID: series.secondaryAxisId,
|
|
100
|
-
|
|
101
|
-
}))}
|
|
102
|
-
/>
|
|
103
|
-
);
|
|
104
|
-
case 'steam':
|
|
105
|
-
return <SteamChart {...chartProps(chart)} theme={fuiTheme} />;
|
|
106
|
-
case 'floating-bar':
|
|
107
|
-
return (
|
|
108
|
-
<FloatingBarChart
|
|
109
|
-
getRange={d => [d.min ?? 0, d.max ?? 0]}
|
|
110
|
-
{...chartProps(chart)}
|
|
111
|
-
theme={fuiTheme}
|
|
112
|
-
/>
|
|
113
|
-
);
|
|
114
|
-
case 'stacked-line':
|
|
115
|
-
return <StackedLineChart {...chartProps(chart)} theme={fuiTheme} />;
|
|
116
|
-
case 'doughnut':
|
|
117
|
-
return (
|
|
118
|
-
<DoughnutChart
|
|
119
|
-
getLabel={datum => datum.name}
|
|
120
|
-
getValue={datum => datum.value ?? 0}
|
|
121
|
-
{...chartProps(chart)}
|
|
122
|
-
theme={fuiTheme}
|
|
123
|
-
/>
|
|
124
|
-
);
|
|
125
|
-
case 'pie':
|
|
126
|
-
return (
|
|
127
|
-
<PieChart
|
|
128
|
-
getLabel={datum => datum.name}
|
|
129
|
-
getValue={datum => datum.value ?? 0}
|
|
130
|
-
showDataLabels={true}
|
|
131
|
-
{...chartProps(chart)}
|
|
132
|
-
theme={fuiTheme}
|
|
133
|
-
/>
|
|
134
|
-
);
|
|
135
|
-
case 'scatter':
|
|
136
|
-
return (
|
|
137
|
-
<ScatterChart
|
|
138
|
-
getX={d => {
|
|
139
|
-
if (typeof d.x === 'number') return d.x;
|
|
140
|
-
if (typeof d.x === 'string') return Number(d.x) || 0;
|
|
141
|
-
if (d.x instanceof Date) return d.x.getTime();
|
|
142
|
-
return 0;
|
|
143
|
-
}}
|
|
144
|
-
getY={d => (typeof d.y === 'number' ? d.y : 0)}
|
|
145
|
-
{...chartProps(chart)}
|
|
146
|
-
theme={fuiTheme}
|
|
147
|
-
showDataLabels={false}
|
|
148
|
-
/>
|
|
149
|
-
);
|
|
150
|
-
case 'polar':
|
|
151
|
-
return (
|
|
152
|
-
<PolarChart
|
|
153
|
-
data={chart.data}
|
|
154
|
-
getLabel={d => d.name}
|
|
155
|
-
getValue={d => d.value ?? 0}
|
|
156
|
-
title={chart.title}
|
|
157
|
-
showDataLabels={true}
|
|
158
|
-
theme={fuiTheme}
|
|
159
|
-
/>
|
|
160
|
-
);
|
|
161
|
-
case 'radar':
|
|
162
|
-
return (
|
|
163
|
-
<RadarChart
|
|
164
|
-
data={chart.data}
|
|
165
|
-
getLabel={d => d.name}
|
|
166
|
-
getValue={d => d.value ?? 0}
|
|
167
|
-
title={chart.title}
|
|
168
|
-
theme={fuiTheme}
|
|
169
|
-
/>
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
default:
|
|
173
|
-
throw new Error(`Unsupported chart type: ${type}`);
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
50
|
|
|
177
51
|
/**
|
|
178
52
|
* Smart Fluent tooltip generator with chart-type awareness.
|
|
@@ -297,14 +171,13 @@ function debounce<T extends (...args: any[]) => void>(fn: T, delay: number): T {
|
|
|
297
171
|
}
|
|
298
172
|
|
|
299
173
|
/**
|
|
300
|
-
*
|
|
174
|
+
* useChartUtils — shared theming and chart helpers.
|
|
301
175
|
*/
|
|
302
|
-
export function
|
|
176
|
+
export function useChartUtils(theme?: Theme) {
|
|
303
177
|
return useMemo(
|
|
304
178
|
() => ({
|
|
305
179
|
lightenColor,
|
|
306
180
|
getFluentPalette,
|
|
307
|
-
getChartComponent,
|
|
308
181
|
createFluentTooltip,
|
|
309
182
|
createAxisLabelFormatter,
|
|
310
183
|
debounce
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-floating-promises */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
4
|
+
import {
|
|
5
|
+
DBSchema,
|
|
6
|
+
openDB,
|
|
7
|
+
} from 'idb';
|
|
8
|
+
|
|
9
|
+
import { useEffect } from 'react';
|
|
10
|
+
|
|
11
|
+
export interface CacheData<T> {
|
|
12
|
+
data: T;
|
|
13
|
+
timestamp: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface CacheDB<T> extends DBSchema {
|
|
17
|
+
cache: {
|
|
18
|
+
key: string;
|
|
19
|
+
value: CacheData<T>;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface UseIndexedDBCacheReturn<T> {
|
|
24
|
+
getData: (key: string) => Promise<T | undefined>;
|
|
25
|
+
setData: (key: string, data: T) => Promise<void>;
|
|
26
|
+
deleteData: (key: string) => Promise<void>;
|
|
27
|
+
clearAllCache: () => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const CACHE: string = "application-cache";
|
|
31
|
+
|
|
32
|
+
const openDatabase = async <T>() => {
|
|
33
|
+
return openDB<CacheDB<T>>('app-cache-db', 1, {
|
|
34
|
+
upgrade(db) {
|
|
35
|
+
db.createObjectStore(CACHE as never);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const getCachedData = async <T>(key: string): Promise<T | undefined> => {
|
|
41
|
+
const db = await openDatabase<T>();
|
|
42
|
+
const cached = await db.get((CACHE as never), key);
|
|
43
|
+
return cached ? cached.data : undefined;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const setCachedData = async <T>(key: string, data: T): Promise<void> => {
|
|
47
|
+
const db = await openDatabase<T>();
|
|
48
|
+
await db.put(CACHE as never, { data, timestamp: Date.now() }, key);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const deleteCachedData = async (key: string): Promise<void> => {
|
|
52
|
+
const db = await openDatabase<any>();
|
|
53
|
+
await db.delete(CACHE as never, key);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const clearCache = async (): Promise<void> => {
|
|
57
|
+
const db = await openDatabase<any>();
|
|
58
|
+
await db.clear(CACHE as never);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const clearExpiredCache = async (maxAge: number): Promise<void> => {
|
|
62
|
+
const db = await openDatabase<any>();
|
|
63
|
+
const allKeys = await db.getAllKeys(CACHE as never);
|
|
64
|
+
const now = Date.now();
|
|
65
|
+
|
|
66
|
+
for (const key of allKeys) {
|
|
67
|
+
const cached = await db.get(CACHE as never, key as string);
|
|
68
|
+
if (cached && now - cached.timestamp > maxAge) {
|
|
69
|
+
await db.delete(CACHE as never, key);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const DEFAULT_MAX_AGE = 24 * 60 * 60 * 1000; // 1 day in milliseconds
|
|
74
|
+
/**
|
|
75
|
+
* Custom hook to manage IndexedDB cache with a specified maximum age.
|
|
76
|
+
*
|
|
77
|
+
* @template T - The type of data to be cached.
|
|
78
|
+
* @param {number} [maxAge=DEFAULT_MAX_AGE] - The maximum age (in milliseconds) for cached data before it is considered expired.
|
|
79
|
+
* @returns {UseIndexedDBCacheReturn<T>} An object containing methods to interact with the cache.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const { getData, setData, deleteData, clearAllCache } = useIndexedDBCache<MyDataType>(3600000);
|
|
83
|
+
*
|
|
84
|
+
* @function
|
|
85
|
+
* @name useIndexedDBCache
|
|
86
|
+
* @memberof hooks
|
|
87
|
+
* @inner
|
|
88
|
+
*
|
|
89
|
+
* @typedef {Object} UseIndexedDBCacheReturn<T>
|
|
90
|
+
* @property {function(string): Promise<T | undefined>} getData - Retrieves cached data by key.
|
|
91
|
+
* @property {function(string, T): Promise<void>} setData - Caches data with a specified key.
|
|
92
|
+
* @property {function(string): Promise<void>} deleteData - Deletes cached data by key.
|
|
93
|
+
* @property {function(): Promise<void>} clearAllCache - Clears all cached data.
|
|
94
|
+
*/
|
|
95
|
+
export const useIndexedDBCache = <T>(maxAge: number = DEFAULT_MAX_AGE): UseIndexedDBCacheReturn<T> => {
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
// Clear expired cache on component mount
|
|
98
|
+
(async () => {
|
|
99
|
+
await clearExpiredCache(maxAge);
|
|
100
|
+
})();
|
|
101
|
+
}, [maxAge]);
|
|
102
|
+
|
|
103
|
+
const getData = async (key: string): Promise<T | undefined> => {
|
|
104
|
+
return await getCachedData<T>(key);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const setData = async (key: string, data: T): Promise<void> => {
|
|
108
|
+
await setCachedData<T>(key, data);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const deleteData = async (key: string): Promise<void> => {
|
|
112
|
+
await deleteCachedData(key);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const clearAllCache = async (): Promise<void> => {
|
|
116
|
+
await clearCache();
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
return { getData, setData, deleteData, clearAllCache };
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export default useIndexedDBCache;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { ResizeObserver } from '@juggle/resize-observer';
|
|
4
|
-
import {
|
|
4
|
+
import { useChartUtils } from './useChartUtils';
|
|
5
5
|
|
|
6
6
|
const BUTTON_WIDTH = 100;
|
|
7
7
|
const GAP = 10;
|
|
@@ -9,7 +9,7 @@ const GAP = 10;
|
|
|
9
9
|
export function useResponsiveLegend<T extends { label: string }>(items: T[]) {
|
|
10
10
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
11
11
|
const [maxVisible, setMaxVisible] = useState(items.length);
|
|
12
|
-
const { debounce } =
|
|
12
|
+
const { debounce } = useChartUtils();
|
|
13
13
|
useEffect(() => {
|
|
14
14
|
const measure = () => {
|
|
15
15
|
const containerWidth = containerRef.current?.offsetWidth ?? 0;
|
package/src/index.tsx
CHANGED