@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
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
# ScatterChart Component
|
|
2
|
-
|
|
3
|
-
A versatile scatter chart component built with Chart.js and Fluent UI React. This component displays data as points on a two-dimensional coordinate system, making it perfect for visualizing correlations, distributions, and relationships between two continuous variables.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Two-Dimensional Data Visualization**: Plot data points using X and Y coordinates
|
|
8
|
-
- **Multiple Series Support**: Compare multiple datasets with different colored point series
|
|
9
|
-
- **Interactive Legend**: Toggle series visibility with click interactions
|
|
10
|
-
- **Correlation Analysis**: Ideal for identifying patterns and relationships
|
|
11
|
-
- **Fluent UI Integration**: Seamless integration with Fluent UI themes and design system
|
|
12
|
-
- **Data Labels**: Optional display of values directly on data points
|
|
13
|
-
- **Responsive Design**: Automatically adapts to container dimensions
|
|
14
|
-
- **TypeScript Support**: Full TypeScript support with generic types
|
|
15
|
-
- **Custom Tooltips**: Rich tooltips showing detailed point information
|
|
16
|
-
- **Linear Scaling**: Automatic scaling for both X and Y axes
|
|
17
|
-
|
|
18
|
-
## Installation
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npm install chart.js react-chartjs-2 chartjs-plugin-datalabels @fluentui/react-components
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Basic Usage
|
|
25
|
-
|
|
26
|
-
```tsx
|
|
27
|
-
import React from 'react';
|
|
28
|
-
import { ScatterChart } from './components/scatterChart/ScatterChart';
|
|
29
|
-
import { webLightTheme } from '@fluentui/react-components';
|
|
30
|
-
|
|
31
|
-
interface SalesData {
|
|
32
|
-
adSpend: number;
|
|
33
|
-
revenue: number;
|
|
34
|
-
region: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const salesData: SalesData[] = [
|
|
38
|
-
{ adSpend: 1000, revenue: 15000, region: 'North' },
|
|
39
|
-
{ adSpend: 1500, revenue: 22000, region: 'North' },
|
|
40
|
-
{ adSpend: 800, revenue: 12000, region: 'North' },
|
|
41
|
-
{ adSpend: 2000, revenue: 28000, region: 'North' },
|
|
42
|
-
{ adSpend: 1200, revenue: 18000, region: 'North' },
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
function App() {
|
|
46
|
-
return (
|
|
47
|
-
<div style={{ width: '800px', height: '500px' }}>
|
|
48
|
-
<ScatterChart
|
|
49
|
-
data={[
|
|
50
|
-
{ label: 'Sales Performance', data: salesData }
|
|
51
|
-
]}
|
|
52
|
-
getX={(datum) => datum.adSpend}
|
|
53
|
-
getY={(datum) => datum.revenue}
|
|
54
|
-
title="Advertising Spend vs Revenue"
|
|
55
|
-
theme={webLightTheme}
|
|
56
|
-
/>
|
|
57
|
-
</div>
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Props
|
|
63
|
-
|
|
64
|
-
### ScatterChartProps<T>
|
|
65
|
-
|
|
66
|
-
| Prop | Type | Required | Default | Description |
|
|
67
|
-
|------|------|----------|---------|-------------|
|
|
68
|
-
| `data` | `{ label: string; data: T[] }[]` | Yes | - | Array of data series with labels and data points |
|
|
69
|
-
| `getX` | `(datum: T) => number` | Yes | - | Function to extract the X-axis value from each data point |
|
|
70
|
-
| `getY` | `(datum: T) => number` | Yes | - | Function to extract the Y-axis value from each data point |
|
|
71
|
-
| `title` | `string` | No | - | Chart title displayed at the top |
|
|
72
|
-
| `showDataLabels` | `boolean` | No | `false` | Whether to show data values on data points |
|
|
73
|
-
| `theme` | `Theme` | No | `webLightTheme` | Fluent UI theme object for styling |
|
|
74
|
-
|
|
75
|
-
## Advanced Usage
|
|
76
|
-
|
|
77
|
-
### Multi-Variable Analysis
|
|
78
|
-
|
|
79
|
-
```tsx
|
|
80
|
-
interface ProductMetrics {
|
|
81
|
-
price: number;
|
|
82
|
-
quality: number;
|
|
83
|
-
customerSatisfaction: number;
|
|
84
|
-
marketShare: number;
|
|
85
|
-
category: string;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const productData: ProductMetrics[] = [
|
|
89
|
-
{ price: 299, quality: 85, customerSatisfaction: 88, marketShare: 15, category: 'Electronics' },
|
|
90
|
-
{ price: 149, quality: 78, customerSatisfaction: 82, marketShare: 22, category: 'Electronics' },
|
|
91
|
-
{ price: 599, quality: 95, customerSatisfaction: 94, marketShare: 8, category: 'Electronics' },
|
|
92
|
-
{ price: 899, quality: 92, customerSatisfaction: 90, marketShare: 5, category: 'Electronics' },
|
|
93
|
-
];
|
|
94
|
-
|
|
95
|
-
<ScatterChart
|
|
96
|
-
data={[{ label: 'Product Analysis', data: productData }]}
|
|
97
|
-
getX={(datum) => datum.price}
|
|
98
|
-
getY={(datum) => datum.quality}
|
|
99
|
-
title="Price vs Quality Analysis"
|
|
100
|
-
showDataLabels={true}
|
|
101
|
-
theme={webLightTheme}
|
|
102
|
-
/>
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### Comparative Market Analysis
|
|
106
|
-
|
|
107
|
-
```tsx
|
|
108
|
-
interface CompanyPerformance {
|
|
109
|
-
revenue: number;
|
|
110
|
-
profitMargin: number;
|
|
111
|
-
employees: number;
|
|
112
|
-
marketCap: number;
|
|
113
|
-
industry: string;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const techCompanies: CompanyPerformance[] = [
|
|
117
|
-
{ revenue: 50000, profitMargin: 25, employees: 500, marketCap: 1000000, industry: 'Tech' },
|
|
118
|
-
{ revenue: 75000, profitMargin: 18, employees: 750, marketCap: 1500000, industry: 'Tech' },
|
|
119
|
-
{ revenue: 120000, profitMargin: 22, employees: 1200, marketCap: 2500000, industry: 'Tech' },
|
|
120
|
-
];
|
|
121
|
-
|
|
122
|
-
const financeCompanies: CompanyPerformance[] = [
|
|
123
|
-
{ revenue: 80000, profitMargin: 15, employees: 800, marketCap: 1800000, industry: 'Finance' },
|
|
124
|
-
{ revenue: 95000, profitMargin: 12, employees: 950, marketCap: 2100000, industry: 'Finance' },
|
|
125
|
-
{ revenue: 110000, profitMargin: 18, employees: 1100, marketCap: 2800000, industry: 'Finance' },
|
|
126
|
-
];
|
|
127
|
-
|
|
128
|
-
<ScatterChart
|
|
129
|
-
data={[
|
|
130
|
-
{ label: 'Technology Companies', data: techCompanies },
|
|
131
|
-
{ label: 'Financial Companies', data: financeCompanies }
|
|
132
|
-
]}
|
|
133
|
-
getX={(datum) => datum.revenue}
|
|
134
|
-
getY={(datum) => datum.profitMargin}
|
|
135
|
-
title="Revenue vs Profit Margin by Industry"
|
|
136
|
-
showDataLabels={true}
|
|
137
|
-
theme={webLightTheme}
|
|
138
|
-
/>
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Performance vs Resource Analysis
|
|
142
|
-
|
|
143
|
-
```tsx
|
|
144
|
-
interface TeamMetrics {
|
|
145
|
-
teamSize: number;
|
|
146
|
-
productivity: number;
|
|
147
|
-
satisfaction: number;
|
|
148
|
-
experience: number;
|
|
149
|
-
department: string;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const teamData: TeamMetrics[] = [
|
|
153
|
-
{ teamSize: 8, productivity: 85, satisfaction: 88, experience: 3.2, department: 'Engineering' },
|
|
154
|
-
{ teamSize: 12, productivity: 78, satisfaction: 82, experience: 2.8, department: 'Engineering' },
|
|
155
|
-
{ teamSize: 6, productivity: 92, satisfaction: 90, experience: 4.1, department: 'Engineering' },
|
|
156
|
-
{ teamSize: 15, productivity: 75, satisfaction: 79, experience: 2.5, department: 'Engineering' },
|
|
157
|
-
];
|
|
158
|
-
|
|
159
|
-
<ScatterChart
|
|
160
|
-
data={[{ label: 'Engineering Teams', data: teamData }]}
|
|
161
|
-
getX={(datum) => datum.teamSize}
|
|
162
|
-
getY={(datum) => datum.productivity}
|
|
163
|
-
title="Team Size vs Productivity"
|
|
164
|
-
showDataLabels={true}
|
|
165
|
-
theme={webLightTheme}
|
|
166
|
-
/>
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Risk vs Return Analysis
|
|
170
|
-
|
|
171
|
-
```tsx
|
|
172
|
-
interface InvestmentOption {
|
|
173
|
-
risk: number; // Risk percentage
|
|
174
|
-
expectedReturn: number; // Expected return percentage
|
|
175
|
-
volatility: number; // Volatility measure
|
|
176
|
-
liquidity: number; // Liquidity score
|
|
177
|
-
assetClass: string;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const investments: InvestmentOption[] = [
|
|
181
|
-
{ risk: 15, expectedReturn: 8, volatility: 12, liquidity: 95, assetClass: 'Bonds' },
|
|
182
|
-
{ risk: 35, expectedReturn: 15, volatility: 25, liquidity: 88, assetClass: 'Stocks' },
|
|
183
|
-
{ risk: 50, expectedReturn: 22, volatility: 40, liquidity: 70, assetClass: 'Growth Stocks' },
|
|
184
|
-
{ risk: 25, expectedReturn: 12, volatility: 18, liquidity: 82, assetClass: 'Balanced Fund' },
|
|
185
|
-
];
|
|
186
|
-
|
|
187
|
-
<ScatterChart
|
|
188
|
-
data={[{ label: 'Investment Options', data: investments }]}
|
|
189
|
-
getX={(datum) => datum.risk}
|
|
190
|
-
getY={(datum) => datum.expectedReturn}
|
|
191
|
-
title="Investment Risk vs Expected Return"
|
|
192
|
-
showDataLabels={true}
|
|
193
|
-
theme={webLightTheme}
|
|
194
|
-
/>
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
## Data Structure
|
|
198
|
-
|
|
199
|
-
The component expects data in the following format:
|
|
200
|
-
|
|
201
|
-
```tsx
|
|
202
|
-
interface ChartSeries<T> {
|
|
203
|
-
label: string; // Series name (appears in legend)
|
|
204
|
-
data: T[]; // Array of data points
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
Each data point `T` should contain:
|
|
209
|
-
|
|
210
|
-
- An X-axis value (horizontal position) - number
|
|
211
|
-
- A Y-axis value (vertical position) - number
|
|
212
|
-
|
|
213
|
-
## Coordinate System
|
|
214
|
-
|
|
215
|
-
### X-Axis (Horizontal)
|
|
216
|
-
|
|
217
|
-
- Represents the independent variable
|
|
218
|
-
- Linear scale with automatic range detection
|
|
219
|
-
- Left-to-right increases in value
|
|
220
|
-
|
|
221
|
-
### Y-Axis (Vertical)
|
|
222
|
-
|
|
223
|
-
- Represents the dependent variable
|
|
224
|
-
- Linear scale with automatic range detection
|
|
225
|
-
- Bottom-to-top increases in value
|
|
226
|
-
|
|
227
|
-
## Use Cases
|
|
228
|
-
|
|
229
|
-
Scatter charts are particularly effective for:
|
|
230
|
-
|
|
231
|
-
### Correlation Analysis
|
|
232
|
-
|
|
233
|
-
- **Sales Performance**: Marketing spend vs revenue
|
|
234
|
-
- **Quality Control**: Input variables vs output quality
|
|
235
|
-
- **Resource Optimization**: Input resources vs productivity
|
|
236
|
-
|
|
237
|
-
### Market Research
|
|
238
|
-
|
|
239
|
-
- **Competitive Analysis**: Price vs quality positioning
|
|
240
|
-
- **Customer Segmentation**: Spend vs frequency analysis
|
|
241
|
-
- **Product Portfolio**: Performance vs investment analysis
|
|
242
|
-
|
|
243
|
-
### Scientific Data
|
|
244
|
-
|
|
245
|
-
- **Experimental Results**: Variable relationships
|
|
246
|
-
- **Performance Metrics**: Multiple factor analysis
|
|
247
|
-
- **Trend Identification**: Pattern recognition in data
|
|
248
|
-
|
|
249
|
-
### Financial Analysis
|
|
250
|
-
|
|
251
|
-
- **Risk Assessment**: Risk vs return portfolios
|
|
252
|
-
- **Performance Evaluation**: Benchmark comparisons
|
|
253
|
-
- **Market Analysis**: Valuation vs fundamentals
|
|
254
|
-
|
|
255
|
-
## Interactive Features
|
|
256
|
-
|
|
257
|
-
### Legend Controls
|
|
258
|
-
|
|
259
|
-
- Click legend items to show/hide data series
|
|
260
|
-
- Visual feedback on hover states
|
|
261
|
-
- At least one series must remain visible
|
|
262
|
-
- Colors automatically assigned from theme palette
|
|
263
|
-
|
|
264
|
-
### Point Interactions
|
|
265
|
-
|
|
266
|
-
- Hover effects on data points
|
|
267
|
-
- Rich tooltips showing X and Y coordinates
|
|
268
|
-
- Smooth transitions and animations
|
|
269
|
-
|
|
270
|
-
### Zoom and Pan
|
|
271
|
-
|
|
272
|
-
- Mouse wheel zoom functionality
|
|
273
|
-
- Pan by dragging (when enabled)
|
|
274
|
-
- Reset zoom controls
|
|
275
|
-
|
|
276
|
-
## Styling and Theme Integration
|
|
277
|
-
|
|
278
|
-
The component uses Fluent UI theme tokens:
|
|
279
|
-
|
|
280
|
-
```tsx
|
|
281
|
-
// Point styling
|
|
282
|
-
backgroundColor: Derived from theme palette
|
|
283
|
-
borderColor: Same as background color
|
|
284
|
-
pointRadius: 4
|
|
285
|
-
pointHoverRadius: 6
|
|
286
|
-
|
|
287
|
-
// Typography
|
|
288
|
-
fontFamily: theme.fontFamilyBase
|
|
289
|
-
fontSize: theme.fontSizeBase200
|
|
290
|
-
fontWeight: theme.fontWeightSemibold
|
|
291
|
-
color: theme.colorNeutralForeground1
|
|
292
|
-
|
|
293
|
-
// Grid and axes
|
|
294
|
-
labelColor: theme.colorNeutralForeground1
|
|
295
|
-
gridColor: theme.colorNeutralStroke2
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
## Performance Optimizations
|
|
299
|
-
|
|
300
|
-
The component includes several React optimizations:
|
|
301
|
-
|
|
302
|
-
````tsx
|
|
303
|
-
// Memoized color calculations
|
|
304
|
-
const seriesColors = useMemo(() => {
|
|
305
|
-
return data.reduce((acc, series, idx) => {
|
|
306
|
-
const base = getFluentPalette(theme)[
|
|
307
|
-
idx % getFluentPalette(theme).length
|
|
308
|
-
];
|
|
309
|
-
acc[series.label] = lightenColor(base, 0.3);
|
|
310
|
-
return acc;
|
|
311
|
-
}, {} as Record<string, string>);
|
|
312
|
-
}, [data, theme]);
|
|
313
|
-
|
|
314
|
-
// Memoized chart data transformation
|
|
315
|
-
const chartData = useMemo(() => {
|
|
316
|
-
return {
|
|
317
|
-
datasets: data
|
|
318
|
-
.filter(series => visibleSeries.includes(series.label))
|
|
319
|
-
.map(series => ({
|
|
320
|
-
label: series.label,
|
|
321
|
-
data: series.data.map(d => ({ x: getX(d), y: getY(d) })),
|
|
322
|
-
backgroundColor: seriesColors[series.label],
|
|
323
|
-
borderColor: seriesColors[series.label],
|
|
324
|
-
pointRadius: 4,
|
|
325
|
-
})),
|
|
326
|
-
};
|
|
327
|
-
}, [data, visibleSeries, getX, getY, seriesColors]);
|
|
328
|
-
|
|
329
|
-
// Memoized theme properties
|
|
330
|
-
const { fontFamily, fontSize, labelColor, gridColor } = useMemo(() => ({
|
|
331
|
-
fontFamily: theme.fontFamilyBase,
|
|
332
|
-
fontSize: parseInt(theme.fontSizeBase200.replace('px', '')) || 14,
|
|
333
|
-
labelColor: theme.colorNeutralForeground1,
|
|
334
|
-
gridColor: theme.colorNeutralStroke2,
|
|
335
|
-
}), [theme]);
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Chart as ChartJS,
|
|
3
|
-
ChartOptions,
|
|
4
|
-
Legend,
|
|
5
|
-
LinearScale,
|
|
6
|
-
PointElement,
|
|
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 RenderLegend from '../../components/RenderLegend/RenderLegend';
|
|
14
|
-
import { Scatter } from 'react-chartjs-2';
|
|
15
|
-
import { useChartUtils } from '../../hooks/useChartUtils';
|
|
16
|
-
import { useGraphGlobalStyles } from '../../graphGlobalStyles/useGraphGlobalStyles';
|
|
17
|
-
|
|
18
|
-
ChartJS.register(ChartDataLabels);
|
|
19
|
-
ChartJS.register(LinearScale, PointElement, Tooltip, Legend);
|
|
20
|
-
|
|
21
|
-
export interface ScatterChartProps<T> {
|
|
22
|
-
data: { label: string; data: T[] }[];
|
|
23
|
-
getX: (datum: T) => number;
|
|
24
|
-
getY: (datum: T) => number;
|
|
25
|
-
title?: string;
|
|
26
|
-
showDataLabels?: boolean;
|
|
27
|
-
theme?: Theme;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export default function ScatterChart<T extends object>({
|
|
31
|
-
data,
|
|
32
|
-
getX,
|
|
33
|
-
getY,
|
|
34
|
-
title,
|
|
35
|
-
showDataLabels = false,
|
|
36
|
-
theme = webLightTheme,
|
|
37
|
-
}: ScatterChartProps<T>) {
|
|
38
|
-
const [visibleSeries, setVisibleSeries] = useState(() =>
|
|
39
|
-
data.map(s => s.label)
|
|
40
|
-
);
|
|
41
|
-
const styles = useGraphGlobalStyles();
|
|
42
|
-
const { getFluentPalette, lightenColor, createFluentTooltip } = useChartUtils(
|
|
43
|
-
theme
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
const seriesColors = useMemo(() => {
|
|
47
|
-
return data.reduce((acc, series, idx) => {
|
|
48
|
-
const base = getFluentPalette(theme)[
|
|
49
|
-
idx % getFluentPalette(theme).length
|
|
50
|
-
];
|
|
51
|
-
acc[series.label] = lightenColor(base, 0.3);
|
|
52
|
-
return acc;
|
|
53
|
-
}, {} as Record<string, string>);
|
|
54
|
-
}, [data, theme]);
|
|
55
|
-
|
|
56
|
-
const toggleSeries = React.useCallback((label: string) => {
|
|
57
|
-
setVisibleSeries(prev =>
|
|
58
|
-
prev.includes(label) ? prev.filter(l => l !== label) : [...prev, label]
|
|
59
|
-
);
|
|
60
|
-
}, []);
|
|
61
|
-
|
|
62
|
-
const chartData = useMemo(() => {
|
|
63
|
-
return {
|
|
64
|
-
datasets: data
|
|
65
|
-
.filter(series => visibleSeries.includes(series.label))
|
|
66
|
-
.map(series => ({
|
|
67
|
-
label: series.label,
|
|
68
|
-
data: series.data.map(d => ({ x: getX(d), y: getY(d) })),
|
|
69
|
-
backgroundColor: seriesColors[series.label],
|
|
70
|
-
borderColor: seriesColors[series.label],
|
|
71
|
-
pointRadius: 4,
|
|
72
|
-
})),
|
|
73
|
-
};
|
|
74
|
-
}, [data, visibleSeries, getX, getY, seriesColors]);
|
|
75
|
-
|
|
76
|
-
const { fontFamily, fontSize, labelColor, gridColor } = useMemo(() => ({
|
|
77
|
-
fontFamily: theme.fontFamilyBase,
|
|
78
|
-
fontSize: parseInt(theme.fontSizeBase200.replace('px', '')) || 14,
|
|
79
|
-
labelColor: theme.colorNeutralForeground1,
|
|
80
|
-
gridColor: theme.colorNeutralStroke2,
|
|
81
|
-
}), [theme]);
|
|
82
|
-
|
|
83
|
-
const options = useMemo<ChartOptions<'scatter'>>(() => ({
|
|
84
|
-
responsive: true,
|
|
85
|
-
maintainAspectRatio: false,
|
|
86
|
-
plugins: {
|
|
87
|
-
title: {
|
|
88
|
-
display: !!title,
|
|
89
|
-
text: title,
|
|
90
|
-
font: {
|
|
91
|
-
size: 14,
|
|
92
|
-
family: theme.fontFamilyBase,
|
|
93
|
-
weight: theme.fontWeightSemibold,
|
|
94
|
-
},
|
|
95
|
-
color: theme.colorNeutralForeground1,
|
|
96
|
-
padding: {
|
|
97
|
-
top: 20,
|
|
98
|
-
bottom: 20,
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
datalabels: {
|
|
102
|
-
display: showDataLabels,
|
|
103
|
-
color: theme.colorNeutralForeground1,
|
|
104
|
-
font: {
|
|
105
|
-
family: theme.fontFamilyBase,
|
|
106
|
-
size: parseInt(theme.fontSizeBase200.replace('px', '')) || 14,
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
legend: { display: false },
|
|
110
|
-
tooltip: createFluentTooltip<'scatter'>(theme),
|
|
111
|
-
},
|
|
112
|
-
scales: {
|
|
113
|
-
x: {
|
|
114
|
-
type: 'linear',
|
|
115
|
-
position: 'bottom',
|
|
116
|
-
ticks: {
|
|
117
|
-
color: labelColor,
|
|
118
|
-
font: { family: fontFamily, size: fontSize },
|
|
119
|
-
},
|
|
120
|
-
grid: { color: gridColor },
|
|
121
|
-
},
|
|
122
|
-
y: {
|
|
123
|
-
type: 'linear',
|
|
124
|
-
ticks: {
|
|
125
|
-
color: labelColor,
|
|
126
|
-
font: { family: fontFamily, size: fontSize },
|
|
127
|
-
},
|
|
128
|
-
grid: { color: gridColor },
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
}), [
|
|
132
|
-
theme,
|
|
133
|
-
title,
|
|
134
|
-
showDataLabels,
|
|
135
|
-
createFluentTooltip,
|
|
136
|
-
labelColor,
|
|
137
|
-
fontFamily,
|
|
138
|
-
fontSize,
|
|
139
|
-
gridColor,
|
|
140
|
-
]);
|
|
141
|
-
|
|
142
|
-
return (
|
|
143
|
-
<div className={styles.chartWithLegend}>
|
|
144
|
-
<div className={styles.chartArea}>
|
|
145
|
-
<Scatter data={chartData} options={options} />
|
|
146
|
-
</div>
|
|
147
|
-
<RenderLegend
|
|
148
|
-
data={data}
|
|
149
|
-
visibleSeries={visibleSeries}
|
|
150
|
-
seriesColors={seriesColors}
|
|
151
|
-
toggleSeries={toggleSeries}
|
|
152
|
-
/>
|
|
153
|
-
</div>
|
|
154
|
-
);
|
|
155
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './ScatterChart';
|