@spteck/fluentui-react-charts 1.0.7 → 1.0.8

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.
Files changed (105) hide show
  1. package/dist/charts/BarChart/BarChart.d.ts +2 -1
  2. package/dist/charts/ComboChart/ComboChart.d.ts +2 -1
  3. package/dist/charts/Doughnut/DoughnutChart.d.ts +2 -1
  4. package/dist/charts/PieChart/PieChart.d.ts +2 -1
  5. package/dist/charts/areaChart/AreaChart.d.ts +2 -1
  6. package/dist/charts/barHorizontalChart/BarHotizontalChart.d.ts +2 -1
  7. package/dist/charts/bubbleChart/BubbleChart.d.ts +2 -1
  8. package/dist/charts/floatBarChart/FloatBarChart.d.ts +2 -1
  9. package/dist/charts/index.d.ts +14 -0
  10. package/dist/charts/lineChart/LineChart.d.ts +2 -1
  11. package/dist/charts/polarChart/PolarChart.d.ts +2 -1
  12. package/dist/charts/radarChart/RadarChart.d.ts +2 -1
  13. package/dist/charts/scatterChart/ScatterChart.d.ts +2 -1
  14. package/dist/charts/stackedLineChart/StackedLineChart.d.ts +2 -1
  15. package/dist/charts/steamChart/SteamChart.d.ts +2 -1
  16. package/dist/components/index.d.ts +0 -14
  17. package/dist/fluentui-react-charts.cjs.development.js +1086 -1072
  18. package/dist/fluentui-react-charts.cjs.development.js.map +1 -1
  19. package/dist/fluentui-react-charts.cjs.production.min.js +1 -1
  20. package/dist/fluentui-react-charts.cjs.production.min.js.map +1 -1
  21. package/dist/fluentui-react-charts.esm.js +1074 -1074
  22. package/dist/fluentui-react-charts.esm.js.map +1 -1
  23. package/dist/index.d.ts +1 -0
  24. package/package.json +3 -3
  25. package/src/assets/sample1.png +0 -0
  26. package/src/assets/sample2.png +0 -0
  27. package/src/assets/sample3.png +0 -0
  28. package/src/charts/BarChart/BarChart.tsx +0 -227
  29. package/src/charts/BarChart/README.MD +0 -335
  30. package/src/charts/BarChart/index.ts +0 -1
  31. package/src/charts/ComboChart/ComboChart.tsx +0 -209
  32. package/src/charts/ComboChart/README.MD +0 -347
  33. package/src/charts/ComboChart/index.ts +0 -1
  34. package/src/charts/Doughnut/DoughnutChart.tsx +0 -152
  35. package/src/charts/Doughnut/README.MD +0 -296
  36. package/src/charts/Doughnut/index.ts +0 -1
  37. package/src/charts/PieChart/PieChart.tsx +0 -148
  38. package/src/charts/PieChart/README.MD +0 -315
  39. package/src/charts/PieChart/index.ts +0 -1
  40. package/src/charts/areaChart/AreaChart.tsx +0 -195
  41. package/src/charts/areaChart/README.MD +0 -236
  42. package/src/charts/areaChart/index.ts +0 -1
  43. package/src/charts/barHorizontalChart/BarHotizontalChart.tsx +0 -200
  44. package/src/charts/barHorizontalChart/README.MD +0 -278
  45. package/src/charts/barHorizontalChart/index.ts +0 -2
  46. package/src/charts/bubbleChart/BubbleChart.tsx +0 -184
  47. package/src/charts/bubbleChart/README.MD +0 -275
  48. package/src/charts/bubbleChart/index.ts +0 -1
  49. package/src/charts/floatBarChart/FloatBarChart.tsx +0 -178
  50. package/src/charts/floatBarChart/README.MD +0 -354
  51. package/src/charts/floatBarChart/index.ts +0 -1
  52. package/src/charts/lineChart/LineChart.tsx +0 -200
  53. package/src/charts/lineChart/README.MD +0 -354
  54. package/src/charts/lineChart/index.ts +0 -1
  55. package/src/charts/polarChart/PolarChart.tsx +0 -161
  56. package/src/charts/polarChart/README.MD +0 -336
  57. package/src/charts/polarChart/index.ts +0 -1
  58. package/src/charts/radarChart/README.MD +0 -388
  59. package/src/charts/radarChart/RadarChart.tsx +0 -173
  60. package/src/charts/radarChart/index.ts +0 -1
  61. package/src/charts/scatterChart/README.MD +0 -335
  62. package/src/charts/scatterChart/ScatterChart.tsx +0 -155
  63. package/src/charts/scatterChart/index.ts +0 -1
  64. package/src/charts/stackedLineChart/README.MD +0 -396
  65. package/src/charts/stackedLineChart/StackedLineChart.tsx +0 -188
  66. package/src/charts/stackedLineChart/index.ts +0 -1
  67. package/src/charts/steamChart/README.MD +0 -414
  68. package/src/charts/steamChart/SteamChart.tsx +0 -236
  69. package/src/charts/steamChart/index.ts +0 -1
  70. package/src/components/RenderLabel/RenderLabel.tsx +0 -39
  71. package/src/components/RenderLabel/index.ts +0 -2
  72. package/src/components/RenderLabel/useRenderLabelStylesStyles.ts +0 -25
  73. package/src/components/RenderLegend/RenderLegend.tsx +0 -40
  74. package/src/components/RenderTooltip/RenderTooltip.tsx +0 -111
  75. package/src/components/buttonMenu/ButtonMenu.tsx +0 -186
  76. package/src/components/buttonMenu/IButtonMenuOption.ts +0 -9
  77. package/src/components/buttonMenu/IButtonMenuProps.tsx +0 -40
  78. package/src/components/dashboard/DashBoard.tsx +0 -314
  79. package/src/components/dashboard/ExampleDashboardUsage.tsx +0 -114
  80. package/src/components/dashboard/IDashboardProps.tsx +0 -11
  81. package/src/components/dashboard/NoDashboards.tsx +0 -26
  82. package/src/components/dashboard/index.ts +0 -3
  83. package/src/components/dashboard/selectZoom/SelectZoom.tsx +0 -184
  84. package/src/components/dashboard/useDashboardStyles.ts +0 -76
  85. package/src/components/index.ts +0 -17
  86. package/src/components/legendContainer/LegendContainer.tsx +0 -118
  87. package/src/components/legendeButton/LegendButton.tsx +0 -57
  88. package/src/components/renderSliceLegend/RenderSliceLegend.tsx +0 -46
  89. package/src/components/renderValueLegend/RenderValueLegend.tsx +0 -43
  90. package/src/components/stack/IStackProps.tsx +0 -94
  91. package/src/components/stack/Stack.tsx +0 -103
  92. package/src/components/svgImages/BusinessReportIcon.tsx +0 -218
  93. package/src/components/themeProvider/ThemeProvider.tsx +0 -48
  94. package/src/constants/Constants.tsx +0 -23
  95. package/src/graphGlobalStyles/useGraphGlobalStyles.ts +0 -28
  96. package/src/hooks/index.ts +0 -1
  97. package/src/hooks/useChartFactory.tsx +0 -136
  98. package/src/hooks/useChartUtils.tsx +0 -187
  99. package/src/hooks/useIndexedDBCache.ts +0 -119
  100. package/src/hooks/useResponsiveLegend.ts +0 -35
  101. package/src/index.tsx +0 -5
  102. package/src/models/ChartDatum.ts +0 -4
  103. package/src/models/ICardChartContainer.tsx +0 -11
  104. package/src/models/IChart.ts +0 -50
  105. package/src/models/index.ts +0 -3
@@ -1,218 +0,0 @@
1
- import React from "react";
2
- import { tokens } from "@fluentui/react-components";
3
-
4
- interface BusinessReportIconProps {
5
- width?: number;
6
- height?: number;
7
- className?: string;
8
- style?: React.CSSProperties;
9
- }
10
-
11
- export const BusinessReportIcon: React.FC<BusinessReportIconProps> = ({
12
- width = 200,
13
- height = 200,
14
- className,
15
- style,
16
- }) => {
17
- return (
18
- <svg
19
- width={width}
20
- height={height}
21
- viewBox="200 400 1400 1000"
22
- className={className}
23
- style={{
24
- fill: tokens.colorNeutralForeground2,
25
- ...style,
26
- }}
27
- xmlns="http://www.w3.org/2000/svg"
28
- >
29
- <g id="BACKGROUND">
30
- <rect
31
- style={{ fill: tokens.colorNeutralBackground1 }}
32
- x="200"
33
- y="400"
34
- width="1400"
35
- height="1000"
36
- />
37
- </g>
38
-
39
- {/* Main chart/dashboard area */}
40
- <g>
41
- <g>
42
- <rect
43
- x="486.006"
44
- y="568.026"
45
- style={{ fill: tokens.colorNeutralBackground1 }}
46
- width="1038.994"
47
- height="768.164"
48
- />
49
- <path
50
- style={{ fill: tokens.colorNeutralStroke1 }}
51
- d="M1527.5,1338.69H483.506V565.526H1527.5V1338.69z M488.506,1333.69H1522.5V570.526H488.506V1333.69z"
52
- />
53
- </g>
54
- <g>
55
- {/* Chart bars */}
56
- <rect
57
- x="558.003"
58
- y="1086.698"
59
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
60
- width="85"
61
- height="164.492"
62
- />
63
- <rect
64
- x="693.003"
65
- y="1004.672"
66
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
67
- width="85"
68
- height="246.519"
69
- />
70
- <rect
71
- x="828.003"
72
- y="835.487"
73
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
74
- width="85"
75
- height="415.703"
76
- />
77
- <rect
78
- x="963.003"
79
- y="955.6"
80
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
81
- width="85"
82
- height="295.591"
83
- />
84
- <rect
85
- x="1098.003"
86
- y="825.238"
87
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
88
- width="85"
89
- height="425.952"
90
- />
91
- <rect
92
- x="1233.003"
93
- y="847.489"
94
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
95
- width="85"
96
- height="403.701"
97
- />
98
- <rect
99
- x="1368.003"
100
- y="699.989"
101
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
102
- width="85"
103
- height="551.201"
104
- />
105
- {/* Chart line */}
106
- <polygon
107
- style={{ fill: tokens.colorBrandBackground }}
108
- points="583.634,1185.919 581.366,1181.462 723.336,1109.231 869.748,909.808 1003.791,1050.114 1141.593,912.312 1275.235,928.549 1409.365,774.548 1413.135,777.833 1277.265,933.832 1143.407,917.569 1003.709,1057.267 870.251,917.573 726.664,1113.149"
109
- />
110
- </g>
111
- {/* Chart grid lines */}
112
- <rect
113
- x="796.336"
114
- y="662.857"
115
- style={{ fill: tokens.colorBrandBackground }}
116
- width="418.333"
117
- height="5"
118
- />
119
- <rect
120
- x="937.543"
121
- y="717.857"
122
- style={{ fill: tokens.colorBrandBackground }}
123
- width="135.92"
124
- height="5"
125
- />
126
- </g>
127
-
128
- {/* Small chart on left */}
129
- <g>
130
- <g>
131
- <rect
132
- x="264.978"
133
- y="441.049"
134
- style={{ fill: tokens.colorNeutralBackground1 }}
135
- width="482.581"
136
- height="379.067"
137
- />
138
- <path
139
- style={{ fill: tokens.colorNeutralStroke1 }}
140
- d="M750.06,822.616H262.478V438.549H750.06V822.616z M267.478,817.616H745.06V443.549H267.478V817.616z"
141
- />
142
- </g>
143
- <g>
144
- {/* Small chart elements */}
145
- <g>
146
- <rect
147
- x="330.537"
148
- y="503.15"
149
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
150
- width="108.842"
151
- height="61.633"
152
- />
153
- <g>
154
- <rect
155
- x="485.277"
156
- y="509.093"
157
- style={{ fill: tokens.colorBrandBackground }}
158
- width="198.014"
159
- height="2.623"
160
- />
161
- <rect
162
- x="485.277"
163
- y="532.656"
164
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
165
- width="198.014"
166
- height="2.623"
167
- />
168
- <rect
169
- x="485.277"
170
- y="556.218"
171
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
172
- width="198.014"
173
- height="2.623"
174
- />
175
- </g>
176
- </g>
177
- {/* Bar chart elements */}
178
- <g>
179
- <g>
180
- <rect
181
- x="381.691"
182
- y="687.747"
183
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
184
- width="22.73"
185
- height="70.417"
186
- />
187
- <rect
188
- x="404.421"
189
- y="653.482"
190
- style={{ fill: tokens.colorBrandBackground }}
191
- width="22.73"
192
- height="104.682"
193
- />
194
- </g>
195
- <g>
196
- <rect
197
- x="466.491"
198
- y="641.634"
199
- style={{ fill: tokens.colorNeutralForeground3, opacity: 0.3 }}
200
- width="22.73"
201
- height="116.089"
202
- />
203
- <rect
204
- x="489.221"
205
- y="714.758"
206
- style={{ fill: tokens.colorBrandBackground }}
207
- width="22.73"
208
- height="42.965"
209
- />
210
- </g>
211
- </g>
212
- </g>
213
- </g>
214
- </svg>
215
- );
216
- };
217
-
218
- export default BusinessReportIcon;
@@ -1,48 +0,0 @@
1
- import React, { ReactNode, createContext, useContext, useState } from 'react';
2
- import { Theme, webDarkTheme, webLightTheme } from '@fluentui/react-components';
3
-
4
- // Define your supported themes
5
- export type SupportedTheme = 'light' | 'dark';
6
-
7
- // Create context
8
- interface ThemeContextValue {
9
- themeName: SupportedTheme;
10
- theme: Theme;
11
- toggleTheme: () => void;
12
- }
13
-
14
- const ThemeContext = createContext<ThemeContextValue | undefined>(undefined);
15
-
16
- // Create provider
17
- interface ThemeProviderProps {
18
- children: ReactNode;
19
- defaultTheme?: SupportedTheme;
20
- }
21
-
22
- export const ThemeProvider: React.FC<ThemeProviderProps> = ({
23
- children,
24
- defaultTheme = 'light',
25
- }) => {
26
- const [themeName, setThemeName] = useState<SupportedTheme>(defaultTheme);
27
-
28
- const toggleTheme = () => {
29
- setThemeName(prev => (prev === 'light' ? 'dark' : 'light'));
30
- };
31
-
32
- const theme = themeName === 'light' ? webLightTheme : webDarkTheme;
33
-
34
- return (
35
- <ThemeContext.Provider value={{ themeName, theme, toggleTheme }}>
36
- {children}
37
- </ThemeContext.Provider>
38
- );
39
- };
40
-
41
- // Hook to use the context
42
- export const useThemeContext = (): ThemeContextValue => {
43
- const context = useContext(ThemeContext);
44
- if (!context) {
45
- throw new Error('useThemeContext must be used within a ThemeProvider');
46
- }
47
- return context;
48
- };
@@ -1,23 +0,0 @@
1
- import { tokens as fluentTokens } from "@fluentui/react-components";
2
-
3
- // Assign colors per series based on label
4
- export function getFluentPalette() {
5
- return [
6
- fluentTokens?.colorPaletteBerryBackground2,
7
- fluentTokens?.colorPaletteBlueBackground2,
8
- fluentTokens?.colorPaletteGreenBackground2,
9
- fluentTokens?.colorPaletteDarkOrangeBackground2,
10
- fluentTokens?.colorPalettePinkBackground2,
11
- fluentTokens?.colorPalettePurpleBackground2,
12
- fluentTokens?.colorPaletteRedBackground2,
13
- fluentTokens?.colorPaletteTealBackground2,
14
- fluentTokens?.colorPaletteYellowBackground2,
15
- fluentTokens?.colorPaletteMarigoldBackground2,
16
- fluentTokens?.colorPaletteBrassBackground2,
17
- fluentTokens?.colorPaletteForestBackground2,
18
- fluentTokens?.colorPaletteSeafoamBackground2,
19
- fluentTokens?.colorPaletteLavenderBackground2,
20
- fluentTokens?.colorPaletteCornflowerBackground2,
21
- ];
22
- }
23
-
@@ -1,28 +0,0 @@
1
- import { css } from "@emotion/css";
2
-
3
- export const useGraphGlobalStyles = () => {
4
- return {
5
- chartWithLegend: css({
6
- display: 'flex',
7
- flexDirection: 'column',
8
- height: '100%',
9
- chartArea: {
10
- flexGrow: 1,
11
- minHeight: 0,
12
- },
13
- }),
14
- chartArea: css`
15
- flex-grow: 1;
16
- min-height: 0;
17
- `,
18
- legendArea: css`
19
- margin-top: 0px;
20
- padding-top: 0px;
21
-
22
- margin-Left: 10px;
23
- margin-Right: 10px;
24
-
25
- `,
26
- };
27
-
28
- }
@@ -1 +0,0 @@
1
- export * from './useChartUtils';
@@ -1,136 +0,0 @@
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
- };
@@ -1,187 +0,0 @@
1
- import {
2
- ChartType,
3
- TooltipCallbacks,
4
- TooltipItem,
5
- TooltipModel,
6
- TooltipOptions,
7
- } from 'chart.js';
8
-
9
- import { Theme } from '@fluentui/react-components';
10
- import { useMemo } from 'react';
11
-
12
- /**
13
- * Lightens a given hex color by a percentage amount (0 to 1).
14
- */
15
- export const lightenColor = (hex: string, amount: number): string => {
16
- if (!/^#?[0-9A-Fa-f]{6}$/.test(hex)) return hex;
17
- if (hex.startsWith('#')) hex = hex.slice(1);
18
-
19
- let r = parseInt(hex.slice(0, 2), 16);
20
- let g = parseInt(hex.slice(2, 4), 16);
21
- let b = parseInt(hex.slice(4, 6), 16);
22
-
23
- r = Math.min(255, Math.floor(r + (255 - r) * amount));
24
- g = Math.min(255, Math.floor(g + (255 - g) * amount));
25
- b = Math.min(255, Math.floor(b + (255 - b) * amount));
26
-
27
- const toHex = (v: number) => v.toString(16).padStart(2, '0');
28
- return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
29
- };
30
-
31
- export const getFluentPalette = (_theme: Theme): string[] => [
32
- '#4e79a7',
33
- '#f28e2c',
34
- '#e15759',
35
- '#76b7b2',
36
- '#59a14f',
37
- '#edc949',
38
- '#af7aa1',
39
- '#ff9da7',
40
- '#9c755f',
41
- '#bab0ab',
42
- '#8cd17d',
43
- '#b6992d',
44
- '#d37295',
45
- '#fabfd2',
46
- '#79706e',
47
- ];
48
-
49
-
50
-
51
- /**
52
- * Smart Fluent tooltip generator with chart-type awareness.
53
- */
54
-
55
- export function createFluentTooltip<TType extends ChartType>(
56
- theme: Theme
57
- ): Partial<TooltipOptions<TType>> {
58
- const fontFamily = theme.fontFamilyBase;
59
- const fontSize = parseInt(theme.fontSizeBase200.replace('px', '')) || 14;
60
- const tooltipBg = theme.colorNeutralBackground1;
61
- const tooltipTitleColor = theme.colorNeutralForeground1;
62
- const tooltipBodyColor = theme.colorNeutralForeground2;
63
- const borderColor = theme.colorNeutralStroke2;
64
-
65
- const callbacks: TooltipCallbacks<TType> = {
66
- title(this: TooltipModel<TType>, context: TooltipItem<TType>[]) {
67
- return context[0]?.label ?? '';
68
- },
69
-
70
- label(this: TooltipModel<TType>, item: TooltipItem<TType>) {
71
- const datasetLabel =
72
- 'label' in (item.dataset as Record<string, any>) &&
73
- typeof (item.dataset as Record<string, any>).label === 'string'
74
- ? (item.dataset as Record<string, any>).label
75
- : 'Value';
76
-
77
- const raw = item.raw;
78
-
79
- // Bubble format { x, y, r }
80
- if (
81
- typeof raw === 'object' &&
82
- raw !== null &&
83
- 'x' in raw &&
84
- 'y' in raw &&
85
- 'r' in raw
86
- ) {
87
- const { x, y, r } = raw as any;
88
- return `${datasetLabel} — x: ${x}, y: ${y}, r: ${r}`;
89
- }
90
-
91
- // Scatter format { x, y }
92
- if (typeof raw === 'object' && raw !== null && 'x' in raw && 'y' in raw) {
93
- const { x, y } = raw as any;
94
- return `${datasetLabel} — x: ${x}, y: ${y}`;
95
- }
96
-
97
- // Floating bar [min, max]
98
- if (Array.isArray(raw) && raw.length === 2) {
99
- const [min, max] = raw;
100
- return `${datasetLabel}: ${min} – ${max}`;
101
- }
102
-
103
- // Default: single number or string
104
- return `${datasetLabel}: ${raw}`;
105
- },
106
-
107
- beforeTitle: () => '',
108
- afterTitle: () => '',
109
- beforeBody: () => '',
110
- afterBody: () => '',
111
- beforeLabel: () => '',
112
- afterLabel: () => '',
113
- labelColor: () => undefined as any,
114
- labelTextColor: () => '',
115
- footer: () => '',
116
- beforeFooter: () => '',
117
- afterFooter: () => '',
118
- labelPointStyle: () => ({
119
- pointStyle: 'circle',
120
- rotation: 0,
121
- radius: 5,
122
- }),
123
- };
124
-
125
- return {
126
- enabled: true,
127
- displayColors: true,
128
- boxWidth: 10,
129
- boxHeight: 10,
130
- boxPadding: 5,
131
- backgroundColor: tooltipBg,
132
- borderColor,
133
- borderWidth: 1,
134
- cornerRadius: 4,
135
- padding: 10,
136
- titleColor: tooltipTitleColor,
137
- bodyColor: tooltipBodyColor,
138
- titleFont: { family: fontFamily, size: fontSize },
139
- bodyFont: { family: fontFamily, size: fontSize },
140
- callbacks,
141
- };
142
- }
143
-
144
-
145
- /**
146
- * Returns a Chart.js ticks callback to truncate long labels and add optional prefix/suffix.
147
- */
148
- export const createAxisLabelFormatter = ({
149
- maxLength = 12,
150
- suffix = '',
151
- prefix = '',
152
- }: {
153
- maxLength?: number;
154
- suffix?: string;
155
- prefix?: string;
156
- }) => {
157
- return function (this: any, value: string | number): string {
158
- const label = typeof value === 'number' ? this.getLabelForValue(value) : String(value);
159
- const trimmed = label.length > maxLength ? label.slice(0, maxLength) + '…' : label;
160
- return `${prefix}${trimmed}${suffix}`;
161
- };
162
- };
163
-
164
-
165
- function debounce<T extends (...args: any[]) => void>(fn: T, delay: number): T {
166
- let timer: ReturnType<typeof setTimeout> | null = null;
167
- return function(this: any, ...args: any[]) {
168
- if (timer) clearTimeout(timer);
169
- timer = setTimeout(() => fn.apply(this, args), delay);
170
- } as T;
171
- }
172
-
173
- /**
174
- * useChartUtils — shared theming and chart helpers.
175
- */
176
- export function useChartUtils(theme?: Theme) {
177
- return useMemo(
178
- () => ({
179
- lightenColor,
180
- getFluentPalette,
181
- createFluentTooltip,
182
- createAxisLabelFormatter,
183
- debounce
184
- }),
185
- [theme]
186
- );
187
- }