@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.
- package/dist/charts/BarChart/BarChart.d.ts +2 -1
- package/dist/charts/ComboChart/ComboChart.d.ts +2 -1
- package/dist/charts/Doughnut/DoughnutChart.d.ts +2 -1
- package/dist/charts/PieChart/PieChart.d.ts +2 -1
- package/dist/charts/areaChart/AreaChart.d.ts +2 -1
- package/dist/charts/barHorizontalChart/BarHotizontalChart.d.ts +2 -1
- package/dist/charts/bubbleChart/BubbleChart.d.ts +2 -1
- package/dist/charts/floatBarChart/FloatBarChart.d.ts +2 -1
- package/dist/charts/index.d.ts +14 -0
- package/dist/charts/lineChart/LineChart.d.ts +2 -1
- package/dist/charts/polarChart/PolarChart.d.ts +2 -1
- package/dist/charts/radarChart/RadarChart.d.ts +2 -1
- package/dist/charts/scatterChart/ScatterChart.d.ts +2 -1
- package/dist/charts/stackedLineChart/StackedLineChart.d.ts +2 -1
- package/dist/charts/steamChart/SteamChart.d.ts +2 -1
- package/dist/components/index.d.ts +0 -14
- package/dist/fluentui-react-charts.cjs.development.js +1086 -1072
- 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 +1074 -1074
- package/dist/fluentui-react-charts.esm.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/package.json +5 -5
- package/src/assets/sample1.png +0 -0
- package/src/assets/sample2.png +0 -0
- package/src/assets/sample3.png +0 -0
- package/src/charts/BarChart/BarChart.tsx +0 -227
- package/src/charts/BarChart/README.MD +0 -335
- package/src/charts/BarChart/index.ts +0 -1
- package/src/charts/ComboChart/ComboChart.tsx +0 -209
- package/src/charts/ComboChart/README.MD +0 -347
- package/src/charts/ComboChart/index.ts +0 -1
- package/src/charts/Doughnut/DoughnutChart.tsx +0 -152
- package/src/charts/Doughnut/README.MD +0 -296
- package/src/charts/Doughnut/index.ts +0 -1
- package/src/charts/PieChart/PieChart.tsx +0 -148
- package/src/charts/PieChart/README.MD +0 -315
- package/src/charts/PieChart/index.ts +0 -1
- package/src/charts/areaChart/AreaChart.tsx +0 -195
- package/src/charts/areaChart/README.MD +0 -236
- package/src/charts/areaChart/index.ts +0 -1
- package/src/charts/barHorizontalChart/BarHotizontalChart.tsx +0 -200
- package/src/charts/barHorizontalChart/README.MD +0 -278
- package/src/charts/barHorizontalChart/index.ts +0 -2
- package/src/charts/bubbleChart/BubbleChart.tsx +0 -184
- package/src/charts/bubbleChart/README.MD +0 -275
- package/src/charts/bubbleChart/index.ts +0 -1
- package/src/charts/floatBarChart/FloatBarChart.tsx +0 -178
- package/src/charts/floatBarChart/README.MD +0 -354
- package/src/charts/floatBarChart/index.ts +0 -1
- package/src/charts/lineChart/LineChart.tsx +0 -200
- package/src/charts/lineChart/README.MD +0 -354
- package/src/charts/lineChart/index.ts +0 -1
- package/src/charts/polarChart/PolarChart.tsx +0 -161
- package/src/charts/polarChart/README.MD +0 -336
- package/src/charts/polarChart/index.ts +0 -1
- package/src/charts/radarChart/README.MD +0 -388
- package/src/charts/radarChart/RadarChart.tsx +0 -173
- package/src/charts/radarChart/index.ts +0 -1
- package/src/charts/scatterChart/README.MD +0 -335
- package/src/charts/scatterChart/ScatterChart.tsx +0 -155
- package/src/charts/scatterChart/index.ts +0 -1
- package/src/charts/stackedLineChart/README.MD +0 -396
- package/src/charts/stackedLineChart/StackedLineChart.tsx +0 -188
- package/src/charts/stackedLineChart/index.ts +0 -1
- package/src/charts/steamChart/README.MD +0 -414
- package/src/charts/steamChart/SteamChart.tsx +0 -236
- package/src/charts/steamChart/index.ts +0 -1
- package/src/components/RenderLabel/RenderLabel.tsx +0 -39
- package/src/components/RenderLabel/index.ts +0 -2
- package/src/components/RenderLabel/useRenderLabelStylesStyles.ts +0 -25
- package/src/components/RenderLegend/RenderLegend.tsx +0 -40
- package/src/components/RenderTooltip/RenderTooltip.tsx +0 -111
- package/src/components/buttonMenu/ButtonMenu.tsx +0 -186
- package/src/components/buttonMenu/IButtonMenuOption.ts +0 -9
- package/src/components/buttonMenu/IButtonMenuProps.tsx +0 -40
- package/src/components/dashboard/DashBoard.tsx +0 -314
- package/src/components/dashboard/ExampleDashboardUsage.tsx +0 -114
- package/src/components/dashboard/IDashboardProps.tsx +0 -11
- package/src/components/dashboard/NoDashboards.tsx +0 -26
- package/src/components/dashboard/index.ts +0 -3
- package/src/components/dashboard/selectZoom/SelectZoom.tsx +0 -184
- package/src/components/dashboard/useDashboardStyles.ts +0 -76
- package/src/components/index.ts +0 -17
- package/src/components/legendContainer/LegendContainer.tsx +0 -118
- package/src/components/legendeButton/LegendButton.tsx +0 -57
- package/src/components/renderSliceLegend/RenderSliceLegend.tsx +0 -46
- package/src/components/renderValueLegend/RenderValueLegend.tsx +0 -43
- package/src/components/stack/IStackProps.tsx +0 -94
- package/src/components/stack/Stack.tsx +0 -103
- package/src/components/svgImages/BusinessReportIcon.tsx +0 -218
- package/src/components/themeProvider/ThemeProvider.tsx +0 -48
- package/src/constants/Constants.tsx +0 -23
- package/src/graphGlobalStyles/useGraphGlobalStyles.ts +0 -28
- package/src/hooks/index.ts +0 -1
- package/src/hooks/useChartFactory.tsx +0 -136
- package/src/hooks/useChartUtils.tsx +0 -187
- package/src/hooks/useIndexedDBCache.ts +0 -119
- package/src/hooks/useResponsiveLegend.ts +0 -35
- package/src/index.tsx +0 -5
- package/src/models/ChartDatum.ts +0 -4
- package/src/models/ICardChartContainer.tsx +0 -11
- package/src/models/IChart.ts +0 -50
- package/src/models/index.ts +0 -3
package/dist/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.0.
|
|
2
|
+
"version": "1.0.9",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"typings": "dist/index.d.ts",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"visualization"
|
|
11
11
|
],
|
|
12
12
|
"files": [
|
|
13
|
-
"dist"
|
|
14
|
-
|
|
13
|
+
"dist"
|
|
14
|
+
|
|
15
15
|
],
|
|
16
16
|
"engines": {
|
|
17
17
|
"node": ">=10"
|
|
@@ -54,11 +54,11 @@
|
|
|
54
54
|
"@fluentui/react-components": "^9.66.2",
|
|
55
55
|
"@iconify/react": "^6.0.0",
|
|
56
56
|
"@juggle/resize-observer": "^3.4.0",
|
|
57
|
-
"chart.js": "^4.5.
|
|
57
|
+
"chart.js": "^4.5.1",
|
|
58
58
|
"chartjs-plugin-datalabels": "^2.2.0",
|
|
59
59
|
"idb": "^8.0.3",
|
|
60
60
|
"react": "^18.3.1",
|
|
61
|
-
"react-chartjs-2": "^5.3.
|
|
61
|
+
"react-chartjs-2": "^5.3.1",
|
|
62
62
|
"react-charts": "^3.0.0-beta.57",
|
|
63
63
|
"react-dom": "^18.3.1",
|
|
64
64
|
"recharts": "^2.15.4"
|
package/src/assets/sample1.png
DELETED
|
Binary file
|
package/src/assets/sample2.png
DELETED
|
Binary file
|
package/src/assets/sample3.png
DELETED
|
Binary file
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BarElement,
|
|
3
|
-
CategoryScale,
|
|
4
|
-
Chart as ChartJS,
|
|
5
|
-
ChartOptions,
|
|
6
|
-
Legend,
|
|
7
|
-
LinearScale,
|
|
8
|
-
Title,
|
|
9
|
-
Tooltip,
|
|
10
|
-
} from 'chart.js';
|
|
11
|
-
import React, { useMemo, useState } from 'react';
|
|
12
|
-
import { createAxisLabelFormatter, useChartUtils } from '../../hooks/useChartUtils';
|
|
13
|
-
|
|
14
|
-
import { Bar } from 'react-chartjs-2';
|
|
15
|
-
import ChartDataLabels from 'chartjs-plugin-datalabels';
|
|
16
|
-
import RenderLegend from '../../components/RenderLegend/RenderLegend';
|
|
17
|
-
import { Theme } from '@fluentui/react-components';
|
|
18
|
-
import { useGraphGlobalStyles } from '../../graphGlobalStyles/useGraphGlobalStyles';
|
|
19
|
-
|
|
20
|
-
ChartJS.register(
|
|
21
|
-
CategoryScale,
|
|
22
|
-
LinearScale,
|
|
23
|
-
BarElement,
|
|
24
|
-
Tooltip,
|
|
25
|
-
Legend,
|
|
26
|
-
ChartDataLabels,
|
|
27
|
-
Title
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
export interface BarProps<T> {
|
|
31
|
-
data: { label: string; data: T[]; type?: 'bar' | 'line' }[];
|
|
32
|
-
getPrimary: (datum: T) => string | number;
|
|
33
|
-
getSecondary: (datum: T) => number;
|
|
34
|
-
stacked?: boolean;
|
|
35
|
-
title?: string;
|
|
36
|
-
showDatalabels?: boolean;
|
|
37
|
-
theme: Theme;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default function BarChart<T extends object>({
|
|
41
|
-
data,
|
|
42
|
-
getPrimary,
|
|
43
|
-
getSecondary,
|
|
44
|
-
title,
|
|
45
|
-
showDatalabels = false,
|
|
46
|
-
stacked = false,
|
|
47
|
-
theme,
|
|
48
|
-
}: BarProps<T>) {
|
|
49
|
-
const [visibleSeries, setVisibleSeries] = useState(() =>
|
|
50
|
-
data.length > 1 ? data.map(s => s.label) : [data[0]?.label]
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
const { lightenColor, getFluentPalette, createFluentTooltip } = useChartUtils(
|
|
54
|
-
theme
|
|
55
|
-
);
|
|
56
|
-
const styles = useGraphGlobalStyles();
|
|
57
|
-
const seriesColors = useMemo(() => {
|
|
58
|
-
return data.reduce((acc, series, idx) => {
|
|
59
|
-
const base = getFluentPalette(theme)[
|
|
60
|
-
idx % getFluentPalette(theme).length
|
|
61
|
-
];
|
|
62
|
-
const color = lightenColor(base, 0.3);
|
|
63
|
-
acc[series.label] = color;
|
|
64
|
-
return acc;
|
|
65
|
-
}, {} as Record<string, string>);
|
|
66
|
-
}, [data]);
|
|
67
|
-
|
|
68
|
-
const toggleSeries = (label: string) => {
|
|
69
|
-
setVisibleSeries(prev => {
|
|
70
|
-
const isVisible = prev.includes(label);
|
|
71
|
-
const next = isVisible ? prev.filter(l => l !== label) : [...prev, label];
|
|
72
|
-
return next.length === 0 && data.length > 0 ? [data[0].label] : next;
|
|
73
|
-
});
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
// Extract all unique x-axis categories (from all series)
|
|
77
|
-
const allCategories = useMemo(() => {
|
|
78
|
-
const categorySet = new Set<string | number>();
|
|
79
|
-
data.forEach(series => {
|
|
80
|
-
series.data.forEach(datum => {
|
|
81
|
-
categorySet.add(getPrimary(datum));
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
return Array.from(categorySet);
|
|
85
|
-
}, [data, getPrimary]);
|
|
86
|
-
|
|
87
|
-
// Construct Chart.js datasets
|
|
88
|
-
const chartData = useMemo(() => {
|
|
89
|
-
return {
|
|
90
|
-
labels: allCategories,
|
|
91
|
-
datasets: data
|
|
92
|
-
.filter(series => visibleSeries.includes(series.label))
|
|
93
|
-
.map(series => ({
|
|
94
|
-
label: series.label,
|
|
95
|
-
backgroundColor: seriesColors[series.label],
|
|
96
|
-
data: allCategories.map(cat => {
|
|
97
|
-
const found = series.data.find(d => getPrimary(d) === cat);
|
|
98
|
-
return found ? getSecondary(found) : 0;
|
|
99
|
-
}),
|
|
100
|
-
// Assign y-axis based on series type when stacked
|
|
101
|
-
yAxisID: stacked ? (series.type === 'line' ? 'y1' : 'y') : 'y',
|
|
102
|
-
})),
|
|
103
|
-
};
|
|
104
|
-
}, [data, visibleSeries, allCategories, seriesColors, stacked]);
|
|
105
|
-
|
|
106
|
-
const { fontFamily, fontSize, labelColor, gridColor } = useMemo(
|
|
107
|
-
() => ({
|
|
108
|
-
fontFamily: theme.fontFamilyBase,
|
|
109
|
-
fontSize: parseInt(theme.fontSizeBase200.replace('px', '')) || 14,
|
|
110
|
-
labelColor: theme.colorNeutralForeground1,
|
|
111
|
-
gridColor: theme.colorNeutralStroke2,
|
|
112
|
-
}),
|
|
113
|
-
[theme]
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
const options: ChartOptions<'bar'> = useMemo(
|
|
117
|
-
() => ({
|
|
118
|
-
responsive: true,
|
|
119
|
-
maintainAspectRatio: false,
|
|
120
|
-
|
|
121
|
-
plugins: {
|
|
122
|
-
title: {
|
|
123
|
-
display: !!title,
|
|
124
|
-
text: title,
|
|
125
|
-
font: {
|
|
126
|
-
size: 14,
|
|
127
|
-
family: theme.fontFamilyBase,
|
|
128
|
-
weight: theme.fontWeightSemibold,
|
|
129
|
-
},
|
|
130
|
-
color: theme.colorNeutralForeground1,
|
|
131
|
-
padding: {
|
|
132
|
-
top: 20,
|
|
133
|
-
bottom: 20,
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
datalabels: {
|
|
137
|
-
display: showDatalabels,
|
|
138
|
-
color: theme.colorNeutralForeground1,
|
|
139
|
-
font: {
|
|
140
|
-
family: theme.fontFamilyBase,
|
|
141
|
-
size: parseInt(theme.fontSizeBase200.replace('px', '')) || 14,
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
legend: {
|
|
145
|
-
display: false,
|
|
146
|
-
},
|
|
147
|
-
tooltip: createFluentTooltip<'bar'>(theme),
|
|
148
|
-
},
|
|
149
|
-
scales: {
|
|
150
|
-
x: {
|
|
151
|
-
stacked,
|
|
152
|
-
ticks: {
|
|
153
|
-
callback: createAxisLabelFormatter({ maxLength: 10 }),
|
|
154
|
-
color: labelColor,
|
|
155
|
-
font: {
|
|
156
|
-
family: fontFamily,
|
|
157
|
-
size: fontSize,
|
|
158
|
-
},
|
|
159
|
-
},
|
|
160
|
-
grid: {
|
|
161
|
-
color: gridColor,
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
y: {
|
|
165
|
-
type: 'linear',
|
|
166
|
-
position: 'left',
|
|
167
|
-
stacked,
|
|
168
|
-
ticks: {
|
|
169
|
-
callback: createAxisLabelFormatter({ maxLength: 10 }),
|
|
170
|
-
color: labelColor,
|
|
171
|
-
font: {
|
|
172
|
-
family: fontFamily,
|
|
173
|
-
size: fontSize,
|
|
174
|
-
},
|
|
175
|
-
},
|
|
176
|
-
grid: {
|
|
177
|
-
color: gridColor,
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
...(stacked && {
|
|
181
|
-
y1: {
|
|
182
|
-
type: 'linear',
|
|
183
|
-
position: 'right',
|
|
184
|
-
ticks: {
|
|
185
|
-
callback: createAxisLabelFormatter({ maxLength: 10 }),
|
|
186
|
-
color: labelColor,
|
|
187
|
-
font: {
|
|
188
|
-
family: fontFamily,
|
|
189
|
-
size: fontSize,
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
grid: {
|
|
193
|
-
drawOnChartArea: false,
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
}),
|
|
197
|
-
},
|
|
198
|
-
}),
|
|
199
|
-
[
|
|
200
|
-
title,
|
|
201
|
-
showDatalabels,
|
|
202
|
-
theme,
|
|
203
|
-
fontFamily,
|
|
204
|
-
fontSize,
|
|
205
|
-
labelColor,
|
|
206
|
-
gridColor,
|
|
207
|
-
stacked,
|
|
208
|
-
createFluentTooltip,
|
|
209
|
-
]
|
|
210
|
-
);
|
|
211
|
-
|
|
212
|
-
return (
|
|
213
|
-
<div className={styles.chartWithLegend}>
|
|
214
|
-
<div className={styles.chartArea}>
|
|
215
|
-
<Bar data={chartData} options={options} />
|
|
216
|
-
</div>
|
|
217
|
-
<div className={styles.legendArea}>
|
|
218
|
-
<RenderLegend
|
|
219
|
-
data={data}
|
|
220
|
-
visibleSeries={visibleSeries}
|
|
221
|
-
seriesColors={seriesColors}
|
|
222
|
-
toggleSeries={toggleSeries}
|
|
223
|
-
/>
|
|
224
|
-
</div>
|
|
225
|
-
</div>
|
|
226
|
-
);
|
|
227
|
-
}
|
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
# BarChart Component
|
|
2
|
-
|
|
3
|
-
A versatile and interactive bar chart component built with Chart.js and Fluent UI React. This component supports multiple series, stacking, mixed chart types (bar + line), and provides an intuitive legend interface.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Multiple Series Support**: Display multiple data series with different colors
|
|
8
|
-
- **Mixed Chart Types**: Support for both bar and line series in the same chart
|
|
9
|
-
- **Interactive Legend**: Toggle series visibility with click interactions
|
|
10
|
-
- **Stacked Charts**: Option to stack bars for comparative analysis
|
|
11
|
-
- **Fluent UI Integration**: Seamless integration with Fluent UI themes and design system
|
|
12
|
-
- **Data Labels**: Optional display of values directly on chart elements
|
|
13
|
-
- **Responsive Design**: Automatically adapts to container dimensions
|
|
14
|
-
- **TypeScript Support**: Full TypeScript support with generic types
|
|
15
|
-
- **Custom Tooltips**: Fluent UI styled tooltips with rich information
|
|
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 { BarChart } from './components/BarChart/BarChart';
|
|
28
|
-
import { webLightTheme } from '@fluentui/react-components';
|
|
29
|
-
|
|
30
|
-
interface SalesData {
|
|
31
|
-
month: string;
|
|
32
|
-
revenue: number;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const salesData: SalesData[] = [
|
|
36
|
-
{ month: 'Jan', revenue: 10000 },
|
|
37
|
-
{ month: 'Feb', revenue: 15000 },
|
|
38
|
-
{ month: 'Mar', revenue: 12000 },
|
|
39
|
-
{ month: 'Apr', revenue: 18000 },
|
|
40
|
-
];
|
|
41
|
-
|
|
42
|
-
function App() {
|
|
43
|
-
return (
|
|
44
|
-
<div style={{ width: '800px', height: '400px' }}>
|
|
45
|
-
<BarChart
|
|
46
|
-
data={[
|
|
47
|
-
{ label: 'Monthly Sales', data: salesData }
|
|
48
|
-
]}
|
|
49
|
-
getPrimary={(datum) => datum.month}
|
|
50
|
-
getSecondary={(datum) => datum.revenue}
|
|
51
|
-
title="Sales Performance"
|
|
52
|
-
theme={webLightTheme}
|
|
53
|
-
/>
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Props
|
|
60
|
-
|
|
61
|
-
### BarProps<T>
|
|
62
|
-
|
|
63
|
-
| Prop | Type | Required | Default | Description |
|
|
64
|
-
|------|------|----------|---------|-------------|
|
|
65
|
-
| `data` | `{ label: string; data: T[]; type?: 'bar' \| 'line' }[]` | Yes | - | Array of data series with labels, data points, and optional chart type |
|
|
66
|
-
| `getPrimary` | `(datum: T) => string \| number` | Yes | - | Function to extract the x-axis category from each data point |
|
|
67
|
-
| `getSecondary` | `(datum: T) => number` | Yes | - | Function to extract the y-axis value from each data point |
|
|
68
|
-
| `stacked` | `boolean` | No | `false` | Whether to stack the bars and enable dual y-axes for mixed types |
|
|
69
|
-
| `title` | `string` | No | - | Chart title displayed at the top |
|
|
70
|
-
| `showDatalabels` | `boolean` | No | `false` | Whether to show data values on chart elements |
|
|
71
|
-
| `theme` | `Theme` | Yes | - | Fluent UI theme object for styling |
|
|
72
|
-
|
|
73
|
-
## Advanced Usage
|
|
74
|
-
|
|
75
|
-
### Multiple Series
|
|
76
|
-
|
|
77
|
-
```tsx
|
|
78
|
-
interface ProductData {
|
|
79
|
-
quarter: string;
|
|
80
|
-
product1: number;
|
|
81
|
-
product2: number;
|
|
82
|
-
product3: number;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const productData: ProductData[] = [
|
|
86
|
-
{ quarter: 'Q1', product1: 15000, product2: 12000, product3: 8000 },
|
|
87
|
-
{ quarter: 'Q2', product1: 18000, product2: 14000, product3: 9500 },
|
|
88
|
-
{ quarter: 'Q3', product1: 16500, product2: 13500, product3: 8800 },
|
|
89
|
-
{ quarter: 'Q4', product1: 20000, product2: 16000, product3: 11000 },
|
|
90
|
-
];
|
|
91
|
-
|
|
92
|
-
<BarChart
|
|
93
|
-
data={[
|
|
94
|
-
{
|
|
95
|
-
label: 'Product A',
|
|
96
|
-
data: productData.map(d => ({ quarter: d.quarter, value: d.product1 }))
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
label: 'Product B',
|
|
100
|
-
data: productData.map(d => ({ quarter: d.quarter, value: d.product2 }))
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
label: 'Product C',
|
|
104
|
-
data: productData.map(d => ({ quarter: d.quarter, value: d.product3 }))
|
|
105
|
-
}
|
|
106
|
-
]}
|
|
107
|
-
getPrimary={(datum) => datum.quarter}
|
|
108
|
-
getSecondary={(datum) => datum.value}
|
|
109
|
-
title="Quarterly Product Sales"
|
|
110
|
-
showDatalabels={true}
|
|
111
|
-
theme={webLightTheme}
|
|
112
|
-
/>
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### Stacked Bar Chart
|
|
116
|
-
|
|
117
|
-
```tsx
|
|
118
|
-
<BarChart
|
|
119
|
-
data={[
|
|
120
|
-
{ label: 'Desktop Sales', data: salesData },
|
|
121
|
-
{ label: 'Mobile Sales', data: salesData },
|
|
122
|
-
{ label: 'Tablet Sales', data: salesData }
|
|
123
|
-
]}
|
|
124
|
-
getPrimary={(datum) => datum.region}
|
|
125
|
-
getSecondary={(datum) => datum.amount}
|
|
126
|
-
stacked={true}
|
|
127
|
-
title="Sales by Platform and Region"
|
|
128
|
-
theme={webLightTheme}
|
|
129
|
-
/>
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### Mixed Chart Types (Bar + Line)
|
|
133
|
-
|
|
134
|
-
```tsx
|
|
135
|
-
<BarChart
|
|
136
|
-
data={[
|
|
137
|
-
{
|
|
138
|
-
label: 'Revenue',
|
|
139
|
-
data: monthlyData,
|
|
140
|
-
type: 'bar'
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
label: 'Growth Rate',
|
|
144
|
-
data: monthlyData,
|
|
145
|
-
type: 'line'
|
|
146
|
-
}
|
|
147
|
-
]}
|
|
148
|
-
getPrimary={(datum) => datum.month}
|
|
149
|
-
getSecondary={(datum) => datum.value}
|
|
150
|
-
stacked={true} // Enables dual y-axes
|
|
151
|
-
title="Revenue vs Growth Rate"
|
|
152
|
-
theme={webLightTheme}
|
|
153
|
-
/>
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### Dark Theme
|
|
157
|
-
|
|
158
|
-
```tsx
|
|
159
|
-
import { webDarkTheme } from '@fluentui/react-components';
|
|
160
|
-
|
|
161
|
-
<BarChart
|
|
162
|
-
data={chartData}
|
|
163
|
-
getPrimary={(datum) => datum.category}
|
|
164
|
-
getSecondary={(datum) => datum.value}
|
|
165
|
-
title="Dark Theme Chart"
|
|
166
|
-
theme={webDarkTheme}
|
|
167
|
-
/>
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
## Data Structure
|
|
171
|
-
|
|
172
|
-
The component expects data in the following format:
|
|
173
|
-
|
|
174
|
-
```tsx
|
|
175
|
-
interface ChartSeries<T> {
|
|
176
|
-
label: string; // Series name (appears in legend)
|
|
177
|
-
data: T[]; // Array of data points
|
|
178
|
-
type?: 'bar' | 'line'; // Chart type (default: 'bar')
|
|
179
|
-
}
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Each data point `T` should contain:
|
|
183
|
-
- A primary value (x-axis category) - string or number
|
|
184
|
-
- A secondary value (y-axis value) - number
|
|
185
|
-
|
|
186
|
-
## Features in Detail
|
|
187
|
-
|
|
188
|
-
### Interactive Legend
|
|
189
|
-
- Click legend items to show/hide series
|
|
190
|
-
- At least one series must remain visible
|
|
191
|
-
- Colors automatically assigned from Fluent UI theme palette
|
|
192
|
-
- Visual feedback on hover and selection states
|
|
193
|
-
|
|
194
|
-
### Stacked Mode
|
|
195
|
-
When `stacked={true}`:
|
|
196
|
-
- Bar series stack on the left y-axis
|
|
197
|
-
- Line series display on the right y-axis (when mixed with bars)
|
|
198
|
-
- Enables comparative analysis between different data types
|
|
199
|
-
|
|
200
|
-
### Responsive Behavior
|
|
201
|
-
- Chart automatically resizes to fit container
|
|
202
|
-
- Legend adapts to available space
|
|
203
|
-
- Maintains readability across different screen sizes
|
|
204
|
-
- Uses CSS Grid for optimal layout
|
|
205
|
-
|
|
206
|
-
### Theme Integration
|
|
207
|
-
- Automatically uses theme colors, fonts, and spacing
|
|
208
|
-
- Supports both light and dark themes
|
|
209
|
-
- Consistent with Fluent UI design language
|
|
210
|
-
- Accessible color contrasts
|
|
211
|
-
|
|
212
|
-
## Styling
|
|
213
|
-
|
|
214
|
-
The component uses Fluent UI theme tokens:
|
|
215
|
-
|
|
216
|
-
```tsx
|
|
217
|
-
// Colors from theme palette
|
|
218
|
-
const seriesColors = getFluentPalette(theme);
|
|
219
|
-
|
|
220
|
-
// Typography
|
|
221
|
-
font-family: theme.fontFamilyBase;
|
|
222
|
-
font-size: theme.fontSizeBase200;
|
|
223
|
-
font-weight: theme.fontWeightSemibold;
|
|
224
|
-
|
|
225
|
-
// Colors
|
|
226
|
-
color: theme.colorNeutralForeground1;
|
|
227
|
-
grid-color: theme.colorNeutralStroke2;
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
## Performance Optimizations
|
|
231
|
-
|
|
232
|
-
The component includes several performance optimizations:
|
|
233
|
-
|
|
234
|
-
- `useMemo` for expensive color calculations
|
|
235
|
-
- `useMemo` for chart data transformation
|
|
236
|
-
- `useMemo` for chart options configuration
|
|
237
|
-
- Efficient series visibility state management
|
|
238
|
-
- Minimal re-renders on data changes
|
|
239
|
-
|
|
240
|
-
## Examples
|
|
241
|
-
|
|
242
|
-
### Sales Dashboard
|
|
243
|
-
```tsx
|
|
244
|
-
interface SalesMetrics {
|
|
245
|
-
region: string;
|
|
246
|
-
currentYear: number;
|
|
247
|
-
previousYear: number;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
<BarChart
|
|
251
|
-
data={[
|
|
252
|
-
{ label: '2024', data: salesMetrics },
|
|
253
|
-
{ label: '2023', data: salesMetrics }
|
|
254
|
-
]}
|
|
255
|
-
getPrimary={(datum) => datum.region}
|
|
256
|
-
getSecondary={(datum) => datum.currentYear}
|
|
257
|
-
title="Sales by Region - Year over Year"
|
|
258
|
-
showDatalabels={true}
|
|
259
|
-
/>
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
### Performance Metrics
|
|
263
|
-
```tsx
|
|
264
|
-
interface PerformanceData {
|
|
265
|
-
metric: string;
|
|
266
|
-
actual: number;
|
|
267
|
-
target: number;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
<BarChart
|
|
271
|
-
data={[
|
|
272
|
-
{ label: 'Actual', data: performanceData, type: 'bar' },
|
|
273
|
-
{ label: 'Target', data: performanceData, type: 'line' }
|
|
274
|
-
]}
|
|
275
|
-
getPrimary={(datum) => datum.metric}
|
|
276
|
-
getSecondary={(datum) => datum.actual}
|
|
277
|
-
stacked={true}
|
|
278
|
-
title="Performance vs Targets"
|
|
279
|
-
/>
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
## Accessibility
|
|
283
|
-
|
|
284
|
-
- Keyboard navigation support
|
|
285
|
-
- Screen reader compatible
|
|
286
|
-
- High contrast theme support
|
|
287
|
-
- Focus indicators on interactive elements
|
|
288
|
-
- ARIA labels for chart elements
|
|
289
|
-
|
|
290
|
-
## Browser Support
|
|
291
|
-
|
|
292
|
-
- Modern browsers with ES6+ support
|
|
293
|
-
- Canvas API required for Chart.js
|
|
294
|
-
- ResizeObserver for responsive features
|
|
295
|
-
- CSS Grid for layout
|
|
296
|
-
|
|
297
|
-
## Troubleshooting
|
|
298
|
-
|
|
299
|
-
### Common Issues
|
|
300
|
-
|
|
301
|
-
1. **Chart not rendering**: Ensure container has explicit width and height
|
|
302
|
-
2. **Data not displaying**: Verify `getPrimary` and `getSecondary` return valid values
|
|
303
|
-
3. **Legend not working**: Check that series labels are unique
|
|
304
|
-
4. **Stacked mode issues**: Ensure mixed types are properly configured
|
|
305
|
-
5. **Theme not applied**: Verify theme object is properly imported
|
|
306
|
-
|
|
307
|
-
### Performance Tips
|
|
308
|
-
|
|
309
|
-
- Limit data points for optimal performance (< 500 points per series)
|
|
310
|
-
- Use `React.memo` for parent components when data changes frequently
|
|
311
|
-
- Consider data virtualization for very large datasets
|
|
312
|
-
- Debounce resize events if needed
|
|
313
|
-
|
|
314
|
-
### Debug Mode
|
|
315
|
-
|
|
316
|
-
```tsx
|
|
317
|
-
// Add this to see chart configuration
|
|
318
|
-
console.log('Chart Data:', chartData);
|
|
319
|
-
console.log('Chart Options:', options);
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
## API Reference
|
|
323
|
-
|
|
324
|
-
### Utility Functions
|
|
325
|
-
|
|
326
|
-
The component uses several utility functions from `useGraphUtils`:
|
|
327
|
-
|
|
328
|
-
- `getFluentPalette(theme)`: Gets color palette from theme
|
|
329
|
-
- `lightenColor(color, amount)`: Lightens colors for better contrast
|
|
330
|
-
- `createFluentTooltip(theme)`: Creates theme-aware tooltips
|
|
331
|
-
- `createAxisLabelFormatter(options)`: Formats axis labels
|
|
332
|
-
|
|
333
|
-
## License
|
|
334
|
-
|
|
335
|
-
This component is part of the FluentUI React Graphs library.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './BarChart';
|