@spteck/fluentui-react-charts 1.0.7 → 1.0.9

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 +5 -5
  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,296 +0,0 @@
1
- # DoughnutChart Component
2
-
3
- A customizable doughnut chart component built with Chart.js and Fluent UI React. This component displays data as a circular chart with a hollow center, making it perfect for showing proportions, percentages, and part-to-whole relationships with an elegant visual presentation.
4
-
5
- ## Features
6
-
7
- - **Circular Data Visualization**: Display proportional data in an intuitive circular format
8
- - **Value Aggregation**: Automatically aggregates values across multiple series for the same labels
9
- - **Interactive Legend**: Toggle segments visibility with click interactions and value display
10
- - **Fluent UI Integration**: Seamless integration with Fluent UI themes and design system
11
- - **Data Labels**: Optional display of values directly on chart segments
12
- - **Responsive Design**: Automatically adapts to container dimensions
13
- - **TypeScript Support**: Full TypeScript support with generic types
14
- - **Custom Tooltips**: Rich tooltips showing detailed segment information
15
- - **Hollow Center**: Classic doughnut design with customizable center space
16
-
17
- ## Installation
18
-
19
- ```bash
20
- npm install chart.js react-chartjs-2 chartjs-plugin-datalabels @fluentui/react-components
21
- ```
22
-
23
- ## Basic Usage
24
-
25
- ```tsx
26
- import React from 'react';
27
- import { DoughnutChart } from './components/Doughnut/DoughnutChart';
28
- import { webLightTheme } from '@fluentui/react-components';
29
-
30
- interface SalesData {
31
- category: string;
32
- amount: number;
33
- }
34
-
35
- const salesData: SalesData[] = [
36
- { category: 'Electronics', amount: 125000 },
37
- { category: 'Clothing', amount: 85000 },
38
- { category: 'Books', amount: 45000 },
39
- { category: 'Home & Garden', amount: 95000 },
40
- { category: 'Sports', amount: 65000 },
41
- ];
42
-
43
- function App() {
44
- return (
45
- <div style={{ width: '600px', height: '400px' }}>
46
- <DoughnutChart
47
- data={[
48
- { label: 'Sales by Category', data: salesData }
49
- ]}
50
- getLabel={(datum) => datum.category}
51
- getValue={(datum) => datum.amount}
52
- title="Sales Distribution by Category"
53
- theme={webLightTheme}
54
- />
55
- </div>
56
- );
57
- }
58
- ```
59
-
60
- ## Props
61
-
62
- ### DoughnutChartProps<T>
63
-
64
- | Prop | Type | Required | Default | Description |
65
- |------|------|----------|---------|-------------|
66
- | `data` | `{ label: string; data: T[] }[]` | Yes | - | Array of data series with labels and data points |
67
- | `getLabel` | `(datum: T) => string` | Yes | - | Function to extract the segment label from each data point |
68
- | `getValue` | `(datum: T) => number` | Yes | - | Function to extract the segment value from each data point |
69
- | `title` | `string` | No | - | Chart title displayed at the top |
70
- | `showDataLabels` | `boolean` | No | `true` | Whether to show data values on chart segments |
71
- | `theme` | `Theme` | No | `webLightTheme` | Fluent UI theme object for styling |
72
-
73
- ## Advanced Usage
74
-
75
- ### Budget Allocation
76
-
77
- ```tsx
78
- interface BudgetItem {
79
- department: string;
80
- allocation: number;
81
- priority: 'high' | 'medium' | 'low';
82
- }
83
-
84
- const budgetData: BudgetItem[] = [
85
- { department: 'Engineering', allocation: 450000, priority: 'high' },
86
- { department: 'Marketing', allocation: 280000, priority: 'high' },
87
- { department: 'Sales', allocation: 320000, priority: 'high' },
88
- { department: 'Operations', allocation: 180000, priority: 'medium' },
89
- { department: 'HR', allocation: 120000, priority: 'medium' },
90
- { department: 'Legal', allocation: 80000, priority: 'low' },
91
- ];
92
-
93
- <DoughnutChart
94
- data={[{ label: 'Budget Allocation', data: budgetData }]}
95
- getLabel={(datum) => datum.department}
96
- getValue={(datum) => datum.allocation}
97
- title="Annual Budget Allocation by Department"
98
- showDataLabels={true}
99
- theme={webLightTheme}
100
- />
101
- ```
102
-
103
- ### Multiple Series Aggregation
104
-
105
- ```tsx
106
- interface RegionalSales {
107
- product: string;
108
- region: string;
109
- sales: number;
110
- }
111
-
112
- const salesData: RegionalSales[] = [
113
- { product: 'Product A', region: 'North', sales: 15000 },
114
- { product: 'Product A', region: 'South', sales: 12000 },
115
- { product: 'Product B', region: 'North', sales: 18000 },
116
- { product: 'Product B', region: 'South', sales: 14000 },
117
- { product: 'Product C', region: 'North', sales: 10000 },
118
- { product: 'Product C', region: 'South', sales: 8000 },
119
- ];
120
-
121
- // This will automatically aggregate sales by product across all regions
122
- <DoughnutChart
123
- data={[
124
- { label: 'North Region', data: salesData.filter(d => d.region === 'North') },
125
- { label: 'South Region', data: salesData.filter(d => d.region === 'South') }
126
- ]}
127
- getLabel={(datum) => datum.product}
128
- getValue={(datum) => datum.sales}
129
- title="Total Sales by Product (All Regions Combined)"
130
- theme={webLightTheme}
131
- />
132
- ```
133
-
134
- ### Survey Results
135
-
136
- ```tsx
137
- interface SurveyResponse {
138
- answer: string;
139
- count: number;
140
- percentage: number;
141
- }
142
-
143
- const surveyData: SurveyResponse[] = [
144
- { answer: 'Very Satisfied', count: 156, percentage: 39 },
145
- { answer: 'Satisfied', count: 124, percentage: 31 },
146
- { answer: 'Neutral', count: 68, percentage: 17 },
147
- { answer: 'Dissatisfied', count: 32, percentage: 8 },
148
- { answer: 'Very Dissatisfied', count: 20, percentage: 5 },
149
- ];
150
-
151
- <DoughnutChart
152
- data={[{ label: 'Customer Satisfaction', data: surveyData }]}
153
- getLabel={(datum) => datum.answer}
154
- getValue={(datum) => datum.count}
155
- title="Customer Satisfaction Survey Results"
156
- showDataLabels={true}
157
- theme={webLightTheme}
158
- />
159
- ```
160
-
161
- ### Market Share Analysis
162
-
163
- ```tsx
164
- interface MarketShare {
165
- company: string;
166
- marketShare: number;
167
- revenue: number;
168
- }
169
-
170
- const marketData: MarketShare[] = [
171
- { company: 'Company A', marketShare: 28.5, revenue: 2850000 },
172
- { company: 'Company B', marketShare: 22.1, revenue: 2210000 },
173
- { company: 'Company C', marketShare: 18.7, revenue: 1870000 },
174
- { company: 'Company D', marketShare: 15.3, revenue: 1530000 },
175
- { company: 'Others', marketShare: 15.4, revenue: 1540000 },
176
- ];
177
-
178
- <DoughnutChart
179
- data={[{ label: 'Market Share', data: marketData }]}
180
- getLabel={(datum) => datum.company}
181
- getValue={(datum) => datum.marketShare}
182
- title="Industry Market Share Distribution"
183
- showDataLabels={true}
184
- theme={webLightTheme}
185
- />
186
- ```
187
-
188
- ## Data Structure
189
-
190
- The component expects data in the following format:
191
-
192
- ```tsx
193
- interface ChartSeries<T> {
194
- label: string; // Series name (for multiple data sources)
195
- data: T[]; // Array of data points
196
- }
197
- ```
198
-
199
- Each data point `T` should contain:
200
-
201
- - A label value (segment name) - string
202
- - A numeric value (segment size) - number
203
-
204
- ## Data Aggregation
205
-
206
- The component automatically aggregates values when multiple data points have the same label:
207
-
208
- ```tsx
209
- // Input data
210
- const data = [
211
- { category: 'Electronics', value: 100 },
212
- { category: 'Electronics', value: 50 }, // Will be aggregated
213
- { category: 'Clothing', value: 75 },
214
- ];
215
-
216
- // Result: Electronics = 150, Clothing = 75
217
- ```
218
-
219
- ## Interactive Features
220
-
221
- ### Legend with Values
222
-
223
- - Displays both label and actual value for each segment
224
- - Click legend items to show/hide segments
225
- - Visual feedback on hover states
226
- - Maintains proportional relationships when segments are hidden
227
-
228
- ### Segment Interactions
229
-
230
- - Hover effects on chart segments
231
- - Rich tooltips showing detailed information
232
- - Smooth animations and transitions
233
-
234
- ### Responsive Layout
235
-
236
- - Chart automatically resizes to container dimensions
237
- - Legend positioning adapts to available space
238
- - Maintains readability across different screen sizes
239
-
240
- ## Styling and Theme Integration
241
-
242
- The component uses Fluent UI theme tokens:
243
-
244
- ```tsx
245
- // Segment colors
246
- backgroundColor: Derived from theme palette with lightening
247
- borderWidth: 1
248
-
249
- // Typography
250
- fontFamily: theme.fontFamilyBase
251
- fontSize: theme.fontSizeBase200
252
- fontWeight: theme.fontWeightSemibold
253
- color: theme.colorNeutralForeground1
254
-
255
- // Data labels
256
- color: theme.colorNeutralForeground1
257
- font: theme font properties
258
- ```
259
-
260
- ## Performance Optimizations
261
-
262
- The component includes several React optimizations:
263
-
264
- ````tsx
265
- // Memoized value aggregation
266
- const valueMap = useMemo(() => {
267
- const map = new Map<string, number>();
268
- data.forEach(series => {
269
- series.data.forEach(d => {
270
- const label = getLabel(d);
271
- const value = getValue(d);
272
- map.set(label, (map.get(label) || 0) + value);
273
- });
274
- });
275
- return map;
276
- }, [data, getLabel, getValue]);
277
-
278
- // Memoized color calculations
279
- const { allLabels, colors } = useMemo(() => {
280
- const allLabels = Array.from(valueMap.keys());
281
- const palette = getFluentPalette(theme);
282
- const colors = allLabels.map((_, i) =>
283
- lightenColor(palette[i % palette.length], 0.3)
284
- );
285
- return { allLabels, colors };
286
- }, [valueMap, getFluentPalette, theme, lightenColor]);
287
-
288
- // Memoized chart data
289
- const chartData = useMemo(() => ({
290
- labels: filteredLabels,
291
- datasets: [{
292
- data: values,
293
- backgroundColor: visibleColors,
294
- borderWidth: 1,
295
- }],
296
- }), [filteredLabels, values, visibleColors]);
@@ -1 +0,0 @@
1
- export * from './DoughnutChart';
@@ -1,148 +0,0 @@
1
- import {
2
- ArcElement,
3
- Chart as ChartJS,
4
- ChartOptions,
5
- Legend,
6
- Title,
7
- Tooltip,
8
- } from 'chart.js';
9
- import React, { useMemo, useState } from 'react';
10
- import { Theme, webLightTheme } from '@fluentui/react-components';
11
-
12
- import ChartDataLabels from 'chartjs-plugin-datalabels';
13
- import { Pie } from 'react-chartjs-2';
14
- import RenderValueLegend from '../../components/renderValueLegend/RenderValueLegend';
15
- import { createFluentTooltip } from '../../hooks/useChartUtils';
16
- import { useChartUtils } from '../../hooks/useChartUtils';
17
- import { useGraphGlobalStyles } from '../../graphGlobalStyles/useGraphGlobalStyles';
18
-
19
- ChartJS.register(ChartDataLabels);
20
- ChartJS.register(ArcElement, Tooltip, Legend, Title);
21
-
22
- export interface PieChartProps<T> {
23
- data: {
24
- label: string;
25
- data: T[];
26
- }[];
27
- getLabel: (datum: T) => string;
28
- getValue: (datum: T) => number;
29
- title?: string;
30
- showDataLabels?: boolean;
31
- theme?: Theme;
32
- }
33
-
34
- export default function PieChart<T extends object>({
35
- data,
36
- getLabel,
37
- getValue,
38
- title,
39
- showDataLabels = false,
40
- theme = webLightTheme,
41
- }: PieChartProps<T>) {
42
- const { getFluentPalette, lightenColor } = useChartUtils(theme);
43
- const [hiddenLabels, setHiddenLabels] = useState<string[]>([]);
44
- const styles = useGraphGlobalStyles();
45
- const toggleLabel = (label: string): void => {
46
- setHiddenLabels(prev =>
47
- prev.includes(label) ? prev.filter(l => l !== label) : [...prev, label]
48
- );
49
- };
50
-
51
- const valueMap = useMemo(() => {
52
- const map = new Map<string, number>();
53
- data.forEach(series => {
54
- series.data.forEach(d => {
55
- const label = getLabel(d);
56
- const value = getValue(d);
57
- map.set(label, (map.get(label) || 0) + value);
58
- });
59
- });
60
- return map;
61
- }, [data, getLabel, getValue]);
62
-
63
- const { allLabels, colors, filteredLabels, values, visibleColors } = useMemo(() => {
64
- const allLabels = Array.from(valueMap.keys());
65
- const palette = getFluentPalette(theme);
66
- const colors = allLabels.map((_, i) =>
67
- lightenColor(palette[i % palette.length], 0.3)
68
- );
69
-
70
- const filteredLabels = allLabels.filter(
71
- label => !hiddenLabels.includes(label)
72
- );
73
- const values = filteredLabels.map(label => valueMap.get(label) || 0);
74
- const visibleColors = filteredLabels.map(label => {
75
- const idx = allLabels.indexOf(label);
76
- return colors[idx];
77
- });
78
-
79
- return { allLabels, colors, filteredLabels, values, visibleColors };
80
- }, [valueMap, getFluentPalette, lightenColor, theme, hiddenLabels]);
81
-
82
- const { chartData, legendEntries } = useMemo(() => {
83
- const chartData = {
84
- labels: filteredLabels,
85
- datasets: [
86
- {
87
- data: values,
88
- backgroundColor: visibleColors,
89
- borderWidth: 1,
90
- },
91
- ],
92
- };
93
-
94
- const legendEntries = allLabels.map((label, i) => ({
95
- label,
96
- value: valueMap.get(label) || 0,
97
- color: colors[i],
98
- }));
99
-
100
- return { chartData, legendEntries };
101
- }, [filteredLabels, values, visibleColors, allLabels, valueMap, colors]);
102
-
103
- const options = useMemo<ChartOptions<'pie'>>(() => ({
104
- responsive: true,
105
- maintainAspectRatio: false,
106
- plugins: {
107
- tooltip: createFluentTooltip<'pie'>(theme),
108
- legend: { display: false },
109
- title: {
110
- display: !!title,
111
- text: title,
112
- font: {
113
- size: 14,
114
- family: theme.fontFamilyBase,
115
- weight: theme.fontWeightSemibold,
116
- },
117
- color: theme.colorNeutralForeground1,
118
- padding: {
119
- top: 20,
120
- bottom: 20,
121
- },
122
- },
123
- datalabels: {
124
- display: showDataLabels,
125
- color: theme.colorNeutralForeground1,
126
- font: {
127
- family: theme.fontFamilyBase,
128
- size: parseInt(theme.fontSizeBase200.replace('px', '')) || 14,
129
- },
130
- },
131
- },
132
- }), [theme, title, showDataLabels]);
133
-
134
- return (
135
- <div className={styles.chartWithLegend}>
136
- <div className={styles.chartArea}>
137
- <Pie data={chartData} options={options} />
138
- </div>
139
- <div className={styles.legendArea}>
140
- <RenderValueLegend
141
- entries={legendEntries}
142
- visibleLabels={filteredLabels}
143
- toggleLabel={toggleLabel}
144
- />
145
- </div>
146
- </div>
147
- );
148
- }