@quillsql/react 1.7.5 → 1.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/lib/ReportBuilder.js +1 -0
  2. package/lib/ReportBuilder.js.map +1 -1
  3. package/lib/SQLEditor.js +3 -3
  4. package/lib/SQLEditor.js.map +1 -1
  5. package/lib/Table.js +1 -1
  6. package/lib/Table.js.map +1 -1
  7. package/lib/components/BigModal/BigModal.js +1 -0
  8. package/lib/components/BigModal/BigModal.js.map +1 -1
  9. package/lib/components/Modal/Modal.js +1 -0
  10. package/lib/components/Modal/Modal.js.map +1 -1
  11. package/lib/hooks/useQuill.js +1 -0
  12. package/lib/hooks/useQuill.js.map +1 -1
  13. package/package.json +11 -4
  14. package/.eslintrc.json +0 -19
  15. package/.prettierrc +0 -11
  16. package/.vscode/settings.json +0 -10
  17. package/src/AddToDashboardModal.tsx +0 -1220
  18. package/src/BarList.tsx +0 -580
  19. package/src/Chart.tsx +0 -1337
  20. package/src/Context.tsx +0 -252
  21. package/src/Dashboard.tsx +0 -820
  22. package/src/DateRangePicker/Calendar.tsx +0 -442
  23. package/src/DateRangePicker/DateRangePicker.tsx +0 -261
  24. package/src/DateRangePicker/DateRangePickerButton.tsx +0 -250
  25. package/src/DateRangePicker/dateRangePickerUtils.tsx +0 -480
  26. package/src/DateRangePicker/index.ts +0 -4
  27. package/src/PieChart.tsx +0 -845
  28. package/src/QuillProvider.tsx +0 -81
  29. package/src/ReportBuilder.tsx +0 -2208
  30. package/src/SQLEditor.tsx +0 -1093
  31. package/src/Table.tsx +0 -1074
  32. package/src/TableChart.tsx +0 -428
  33. package/src/assets/ArrowDownHeadIcon.tsx +0 -11
  34. package/src/assets/ArrowDownIcon.tsx +0 -14
  35. package/src/assets/ArrowDownRightIcon.tsx +0 -14
  36. package/src/assets/ArrowLeftHeadIcon.tsx +0 -11
  37. package/src/assets/ArrowRightHeadIcon.tsx +0 -11
  38. package/src/assets/ArrowRightIcon.tsx +0 -14
  39. package/src/assets/ArrowUpHeadIcon.tsx +0 -11
  40. package/src/assets/ArrowUpIcon.tsx +0 -14
  41. package/src/assets/ArrowUpRightIcon.tsx +0 -14
  42. package/src/assets/CalendarIcon.tsx +0 -14
  43. package/src/assets/DoubleArrowLeftHeadIcon.tsx +0 -18
  44. package/src/assets/DoubleArrowRightHeadIcon.tsx +0 -20
  45. package/src/assets/ExclamationFilledIcon.tsx +0 -14
  46. package/src/assets/LoadingSpinner.tsx +0 -11
  47. package/src/assets/SearchIcon.tsx +0 -14
  48. package/src/assets/XCircleIcon.tsx +0 -14
  49. package/src/assets/index.ts +0 -16
  50. package/src/components/BigModal/BigModal.tsx +0 -108
  51. package/src/components/Dropdown/Dropdown.tsx +0 -169
  52. package/src/components/Dropdown/DropdownItem.tsx +0 -68
  53. package/src/components/Dropdown/index.ts +0 -2
  54. package/src/components/Modal/Modal.tsx +0 -132
  55. package/src/components/Modal/index.ts +0 -1
  56. package/src/components/selectUtils.ts +0 -60
  57. package/src/contexts/BaseColorContext.tsx +0 -5
  58. package/src/contexts/HoveredValueContext.tsx +0 -12
  59. package/src/contexts/RootStylesContext.tsx +0 -5
  60. package/src/contexts/SelectedValueContext.tsx +0 -13
  61. package/src/contexts/index.ts +0 -4
  62. package/src/hooks/index.ts +0 -4
  63. package/src/hooks/useInternalState.tsx +0 -18
  64. package/src/hooks/useOnClickOutside.tsx +0 -23
  65. package/src/hooks/useOnWindowResize.tsx +0 -17
  66. package/src/hooks/useQuill.ts +0 -138
  67. package/src/hooks/useSelectOnKeyDown.tsx +0 -80
  68. package/src/index.ts +0 -9
  69. package/src/lib/font.ts +0 -14
  70. package/src/lib/index.ts +0 -3
  71. package/src/lib/inputTypes.ts +0 -81
  72. package/src/lib/utils.tsx +0 -46
  73. package/tsconfig.json +0 -22
package/src/PieChart.tsx DELETED
@@ -1,845 +0,0 @@
1
- /* eslint-disable @typescript-eslint/ban-ts-comment */
2
- /* eslint-disable react/display-name */
3
- // @ts-nocheck
4
- import React, { useRef, useState, useEffect, CSSProperties } from 'react';
5
- import { Pie, PieChart, ResponsiveContainer, Tooltip, Legend } from 'recharts';
6
-
7
- // const data = [
8
- // {
9
- // name: 'Project Nile',
10
- // pct_of_the_total: 0.208266213458027,
11
- // },
12
- // {
13
- // name: 'GA_Columbus',
14
- // pct_of_the_total: 0.102192710707096,
15
- // },
16
- // {
17
- // name: 'IN_Indianapolis',
18
- // pct_of_the_total: 0.0965229750772778,
19
- // },
20
- // {
21
- // name: 'MO_St Louis',
22
- // pct_of_the_total: 0.0732235559304729,
23
- // },
24
- // {
25
- // name: 'AL_Birmingham',
26
- // pct_of_the_total: 0.0555956813239389,
27
- // },
28
- // {
29
- // name: 'FL_Fort Myers',
30
- // pct_of_the_total: 0.0479532568651074,
31
- // },
32
- // {
33
- // name: 'GA_Macon',
34
- // pct_of_the_total: 0.0431507654834117,
35
- // },
36
- // {
37
- // name: 'NC_Charlotte',
38
- // pct_of_the_total: 0.034166792944838,
39
- // },
40
- // {
41
- // name: 'AL_Montgomery',
42
- // pct_of_the_total: 0.0298663023800594,
43
- // },
44
- // {
45
- // name: 'TN_Memphis',
46
- // pct_of_the_total: 0.0292140477651036,
47
- // },
48
- // {
49
- // name: 'SC_Greenville',
50
- // pct_of_the_total: 0.0288115667542858,
51
- // },
52
- // {
53
- // name: 'SC_Columbia',
54
- // pct_of_the_total: 0.0285805316472631,
55
- // },
56
- // {
57
- // name: 'NC_Fayetteville',
58
- // pct_of_the_total: 0.0279000448849207,
59
- // },
60
- // {
61
- // name: 'SC_Spartanburg',
62
- // pct_of_the_total: 0.0260196308313896,
63
- // },
64
- // {
65
- // name: 'NC_Greensboro',
66
- // pct_of_the_total: 0.0169521323221251,
67
- // },
68
- // {
69
- // name: 'FL_Orlando',
70
- // pct_of_the_total: 0.0167433815522564,
71
- // },
72
- // {
73
- // name: 'FL_Tampa',
74
- // pct_of_the_total: 0.0155513189530513,
75
- // },
76
- // {
77
- // name: 'NC_Raleigh',
78
- // pct_of_the_total: 0.0154308010765727,
79
- // },
80
- // {
81
- // name: 'FL_Jacksonville',
82
- // pct_of_the_total: 0.0152275224173022,
83
- // },
84
- // {
85
- // name: 'GA_LaGrange',
86
- // pct_of_the_total: 0.00867900369362145,
87
- // },
88
- // {
89
- // name: 'GA_Augusta',
90
- // pct_of_the_total: 0.0084582649800033,
91
- // },
92
- // {
93
- // name: 'TX_San Antonio',
94
- // pct_of_the_total: 0.00682971823492258,
95
- // },
96
- // {
97
- // name: 'FL_North Port',
98
- // pct_of_the_total: 0.00637954051173961,
99
- // },
100
- // {
101
- // name: 'No Portfolio',
102
- // pct_of_the_total: 0.00522734435854761,
103
- // },
104
- // ];
105
-
106
- const useOnWindowResize = (
107
- handler: { (): void },
108
- initialWindowSize?: number
109
- ) => {
110
- const [windowSize, setWindowSize] = useState<undefined | number>(
111
- initialWindowSize
112
- );
113
- useEffect(() => {
114
- const handleResize = () => {
115
- setWindowSize(window.innerWidth);
116
- handler();
117
- };
118
- handleResize();
119
- window.addEventListener('resize', handleResize);
120
-
121
- return () => window.removeEventListener('resize', handleResize);
122
- }, [handler, windowSize]);
123
- };
124
-
125
- const ChartLegend = (categories: string[], colors: string[]) => {
126
- const legendRef = useRef<HTMLDivElement>(null);
127
-
128
- // useOnWindowResize(() => {
129
- // const calculateHeight = (height: number | undefined) =>
130
- // height
131
- // ? Number(height) + 20 // 20px extra padding
132
- // : 60; // default height
133
- // setLegendHeight(calculateHeight(legendRef.current?.clientHeight));
134
- // });
135
-
136
- return (
137
- <div ref={legendRef} className="qq-flex qq-items-center qq-justify-end">
138
- <Legend
139
- // @ts-ignore
140
- categories={categories}
141
- colors={colors}
142
- />
143
- </div>
144
- );
145
- };
146
-
147
- export type ValueFormatter = {
148
- (value: number): string;
149
- };
150
-
151
- const iconVariantValues = [
152
- 'simple',
153
- 'light',
154
- 'shadow',
155
- 'solid',
156
- 'outlined',
157
- ] as const;
158
-
159
- export type IconVariant = (typeof iconVariantValues)[number];
160
-
161
- export type HorizontalPosition = 'left' | 'right';
162
-
163
- export type VerticalPosition = 'top' | 'bottom';
164
-
165
- export type ButtonVariant = 'primary' | 'secondary' | 'light';
166
-
167
- const deltaTypeValues = [
168
- 'increase',
169
- 'moderateIncrease',
170
- 'decrease',
171
- 'moderateDecrease',
172
- 'unchanged',
173
- ] as const;
174
-
175
- export type DeltaType = (typeof deltaTypeValues)[number];
176
-
177
- const sizeValues = ['xs', 'sm', 'md', 'lg', 'xl'] as const;
178
-
179
- export type Size = (typeof sizeValues)[number];
180
-
181
- const colorValues = [
182
- 'slate',
183
- 'gray',
184
- 'zinc',
185
- 'neutral',
186
- 'stone',
187
- 'red',
188
- 'orange',
189
- 'amber',
190
- 'yellow',
191
- 'lime',
192
- 'green',
193
- 'emerald',
194
- 'teal',
195
- 'cyan',
196
- 'sky',
197
- 'blue',
198
- 'indigo',
199
- 'violet',
200
- 'purple',
201
- 'fuchsia',
202
- 'pink',
203
- 'rose',
204
- ] as const;
205
-
206
- export type Color = (typeof colorValues)[number];
207
-
208
- const justifyContentValues = [
209
- 'start',
210
- 'end',
211
- 'center',
212
- 'between',
213
- 'around',
214
- 'evenly',
215
- ] as const;
216
- export type JustifyContent = (typeof justifyContentValues)[number];
217
-
218
- const alignItemsValues = [
219
- 'start',
220
- 'end',
221
- 'center',
222
- 'baseline',
223
- 'stretch',
224
- ] as const;
225
- export type AlignItems = (typeof alignItemsValues)[number];
226
-
227
- export type FlexDirection = 'row' | 'col' | 'row-reverse' | 'col-reverse';
228
-
229
- export const defaultValueFormatter: ValueFormatter = (value: number) =>
230
- (value * 1).toFixed(1) + '%';
231
-
232
- export const sumNumericArray = (arr: number[]) =>
233
- arr.reduce((prefixSum, num) => prefixSum + num, 0);
234
-
235
- // export const parseData = (data: any[], colors: any[]) =>
236
- // data.map((dataPoint: any, idx: number) => {
237
- // const baseColor = idx < colors.length ? colors[idx] : BaseColors.Gray;
238
- // const hexCode = hexColors[baseColor ?? BaseColors.Gray];
239
- // return {
240
- // ...dataPoint,
241
- // color: colors[idx],
242
- // fill: colors[idx],
243
- // };
244
- // });
245
-
246
- // @ts-ignore
247
- export const parseData = (data, colors, categoryKey, valueKey) => {
248
- const maxItems = 20;
249
- const slicedData = data.slice(0, maxItems);
250
-
251
- let totalValue = slicedData.reduce(
252
- (acc, dataPoint) => acc + Number(dataPoint[valueKey]),
253
- 0
254
- );
255
-
256
- if (totalValue !== 100) {
257
- slicedData.forEach(dataPoint => {
258
- dataPoint[valueKey] = (Number(dataPoint[valueKey]) * 100) / totalValue;
259
- });
260
- totalValue = 100;
261
- }
262
-
263
- const parsedData = slicedData.map((dataPoint, idx) => {
264
- const baseColor =
265
- idx < colors.length ? colors[idx] : colors[colors.length - 1];
266
- return {
267
- ...dataPoint,
268
- color: baseColor,
269
- fill: baseColor,
270
- };
271
- });
272
-
273
- if (data.length > maxItems) {
274
- const otherData = data.slice(maxItems);
275
- const otherSum = otherData.reduce(
276
- (acc, dataPoint) => acc + Number(dataPoint[valueKey]),
277
- 0
278
- );
279
- const otherColor = colors[colors.length - 1];
280
- const normalizedOtherSum = (otherSum * 100) / totalValue;
281
- parsedData.push({
282
- [categoryKey]: 'Other',
283
- [valueKey]: normalizedOtherSum,
284
- color: otherColor,
285
- fill: otherColor,
286
- });
287
- }
288
-
289
- return parsedData;
290
- };
291
-
292
- const calculateDefaultLabel = (data: any[], category: string) =>
293
- sumNumericArray(data.map(dataPoint => dataPoint[category]));
294
-
295
- export const parseLabelInput = (
296
- labelInput: string | undefined,
297
- valueFormatter: ValueFormatter,
298
- data: any[],
299
- category: string
300
- ) =>
301
- labelInput
302
- ? labelInput
303
- : valueFormatter(calculateDefaultLabel(data, category));
304
-
305
- export const ChartTooltipFrame = ({
306
- children,
307
- theme,
308
- }: {
309
- children: React.ReactNode;
310
- }) => (
311
- <div
312
- style={{
313
- borderStyle: 'solid',
314
- borderColor: theme?.borderColor || '#E5E7EB',
315
- borderWidth: 1,
316
- background: theme?.backgroundColor || '#ffffff',
317
- fontSize: theme?.fontSize || '14px',
318
- borderRadius: '6px',
319
- boxShadow:
320
- '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
321
- }}
322
- // style={{ transform: 'translateX(-120px)' }}
323
- // className="qq-bg-white qq-text-sm qq-rounded-md qq-shadow-lg"
324
- // className={twMerge(
325
- // 'bg-white',
326
- // 'font-normal',
327
- // 'border-[12px]',
328
- // 'border-[1px]',
329
- // 'text-[#212121]'
330
- // // boxShadow.lg
331
- // )}
332
- >
333
- {children}
334
- </div>
335
- );
336
-
337
- export interface ChartTooltipRowProps {
338
- value: string;
339
- name: string;
340
- color: Color;
341
- theme: any;
342
- }
343
-
344
- export const ChartTooltipRow = ({
345
- value,
346
- name,
347
- color,
348
- theme,
349
- }: ChartTooltipRowProps) => (
350
- <div
351
- style={{
352
- display: 'flex',
353
- alignItems: 'center',
354
- justifyContent: 'space-between',
355
- minWidth: 120,
356
- // minHeight: 27,
357
- // margin: '0 2rem',
358
- }}
359
- >
360
- <div
361
- style={{
362
- display: 'flex',
363
- alignItems: 'center',
364
- justifyContent: 'space-between',
365
- // margin: '0 0.5rem',
366
- // minWidth: 120,
367
- }}
368
- >
369
- <span
370
- style={{
371
- background: color,
372
- borderWidth: 2,
373
- borderStyle: 'solid',
374
- borderColor: 'white',
375
- height: '8px',
376
- width: '8px',
377
- boxShadow:
378
- '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
379
- borderRadius: '9999px',
380
- marginRight: 5,
381
- }}
382
- // className={twMerge(
383
- // 'shrink-0',
384
- // 'bg-black',
385
- // 'bg-white',
386
- // 'border-black',
387
- // sizing.sm.height,
388
- // sizing.sm.width,
389
- // 'qq-h-3',
390
- // 'qq-w-3',
391
- // 'qq-shadow',
392
- // 'qq-rounded-full'
393
- // border.md.all,
394
- // boxShadow.md
395
- // )}
396
- />
397
- <p
398
- // className={twMerge(
399
- // 'font-medium tabular-nums text-right whitespace-nowrap',
400
- // 'text-[#212121] !important'
401
- // )}
402
- style={{
403
- marginTop: 0,
404
- marginBottom: 0,
405
- fontFamily: theme?.fontFamily,
406
- color: theme?.primaryTextColor,
407
- paddingTop: 2,
408
- paddingBottom: 2,
409
- fontSize: theme?.fontSizeSmall || '14px',
410
- fontWeight: theme?.fontWeightMedium || '500',
411
- }}
412
- // className="qq-font-medium qq-tabular-nums qq-text-right qq-whitespace-nowrap"
413
- >
414
- {value}
415
- </p>
416
- </div>
417
- <p
418
- style={{
419
- marginTop: 0,
420
- marginBottom: 0,
421
- fontFamily: theme?.fontFamily,
422
- color: theme?.secondaryTextColor,
423
- whiteSpace: 'nowrap',
424
- overflow: 'hidden',
425
- textOverflow: 'ellipsis',
426
- textAlign: 'right',
427
- fontSize: theme?.fontSizeSmall || '14px',
428
- fontWeight: theme?.fontWeightNormal || '400',
429
- }}
430
- // className={twMerge(
431
- // 'qq-text-right qq-whitespace-nowrap'
432
- // getColorClassNames(DEFAULT_COLOR, colorPalette.text).textColor,
433
- // 'qq-text-gray-500'
434
- // fontWeight.sm
435
- // )}
436
- >
437
- {name}
438
- </p>
439
- </div>
440
- );
441
-
442
- export interface DonutChartTooltipProps {
443
- active: boolean | undefined;
444
- payload: any;
445
- valueFormatter: ValueFormatter;
446
- theme: any;
447
- }
448
-
449
- export const DonutChartTooltip = ({
450
- active,
451
- payload,
452
- valueFormatter,
453
- theme,
454
- }: DonutChartTooltipProps) => {
455
- if (active && payload[0]) {
456
- const payloadRow = payload[0];
457
- return (
458
- <ChartTooltipFrame theme={theme}>
459
- <div
460
- // style={{ transform: 'translateX(-120px)' }}
461
- // className={twMerge('qq-px-4', 'qq-py-2')}
462
- style={{
463
- paddingLeft: '1rem',
464
- paddingRight: '1rem',
465
- paddingTop: '8px',
466
- paddingBottom: '8px',
467
- }}
468
- >
469
- <ChartTooltipRow
470
- value={valueFormatter(payloadRow.value)}
471
- name={payloadRow.name}
472
- color={payloadRow.payload.color}
473
- theme={theme}
474
- />
475
- </div>
476
- </ChartTooltipFrame>
477
- );
478
- }
479
- return null;
480
- };
481
-
482
- type DonutChartVariant = 'donut' | 'pie';
483
-
484
- export interface DonutChartProps extends React.HTMLAttributes<HTMLDivElement> {
485
- category?: string;
486
- index?: string;
487
- colors?: any[];
488
- data: any[];
489
- variant?: DonutChartVariant;
490
- valueFormatter?: ValueFormatter;
491
- label?: string;
492
- showLabel?: boolean;
493
- showAnimation?: boolean;
494
- showTooltip?: boolean;
495
- containerStyle?: CSSProperties;
496
- }
497
-
498
- // @ts-ignore
499
- export function findComplementaryAndAnalogousColors(color1, color2) {
500
- // Calculate the hue of the first color
501
- const color1HSL = rgbToHsl(hexToRgb(color1));
502
- const color2HSL = rgbToHsl(hexToRgb(color2));
503
- const color1Hue = color1HSL.h;
504
-
505
- // Calculate the complementary color of the first color
506
- const complementaryHue = (color1Hue + 180) % 360;
507
- const complementaryColor = hslToRgb({
508
- h: complementaryHue,
509
- s: color1HSL.s,
510
- l: color1HSL.l,
511
- });
512
-
513
- // Find an analogous hue to the first color
514
- const analogousHue1 = (color1Hue + 30) % 360;
515
- const analogousHue2 = (color1Hue - 30 + 360) % 360;
516
-
517
- // Convert the analogous hues back to RGB colors
518
- const analogousColor1 = hslToRgb({
519
- h: analogousHue1,
520
- s: color1HSL.s,
521
- l: color1HSL.l,
522
- });
523
- const analogousColor2 = hslToRgb({
524
- h: analogousHue2,
525
- s: color1HSL.s,
526
- l: color1HSL.l,
527
- });
528
-
529
- // Calculate the average hue between the two colors
530
- const avgHue = (color1HSL.h + color2HSL.h) / 2;
531
-
532
- // Generate a new HSL object with the average hue and the same saturation and lightness as color1
533
- const analogousHsl = { h: avgHue, s: color1HSL.s, l: color1HSL.l };
534
-
535
- return [
536
- color1,
537
- color2,
538
- rgbToHex(hslToRgb(analogousHsl)),
539
- // rgbToHex(complementaryColor),
540
- // rgbToHex(analogousColor1),
541
- // rgbToHex(analogousColor2),
542
- ];
543
- }
544
-
545
- // @ts-ignore
546
- function hexToRgb(hex) {
547
- const r = parseInt(hex.substring(1, 3), 16);
548
- const g = parseInt(hex.substring(3, 5), 16);
549
- const b = parseInt(hex.substring(5, 7), 16);
550
- return { r, g, b };
551
- }
552
-
553
- // @ts-ignore
554
- function rgbToHex(rgb) {
555
- const rHex = rgb.r.toString(16).padStart(2, '0');
556
- const gHex = rgb.g.toString(16).padStart(2, '0');
557
- const bHex = rgb.b.toString(16).padStart(2, '0');
558
- return `#${rHex}${gHex}${bHex}`;
559
- }
560
-
561
- // @ts-ignore
562
- function rgbToHsl(rgb) {
563
- const r = rgb.r / 255;
564
- const g = rgb.g / 255;
565
- const b = rgb.b / 255;
566
-
567
- const max = Math.max(r, g, b);
568
- const min = Math.min(r, g, b);
569
-
570
- let h = 0,
571
- s = 0,
572
- l = (max + min) / 2;
573
-
574
- if (max !== min) {
575
- let d = max - min;
576
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
577
-
578
- switch (max) {
579
- case r:
580
- h = (g - b) / d + (g < b ? 6 : 0);
581
- break;
582
- case g:
583
- h = (b - r) / d + 2;
584
- break;
585
- case b:
586
- h = (r - g) / d + 4;
587
- break;
588
- }
589
-
590
- h /= 6;
591
- }
592
-
593
- return { h: h * 360, s: s * 100, l: l * 100 };
594
- }
595
-
596
- // @ts-ignore
597
- function hslToRgb(hsl) {
598
- const h = hsl.h / 360;
599
- const s = hsl.s / 100;
600
- const l = hsl.l / 100;
601
-
602
- let r, g, b;
603
-
604
- if (s === 0) {
605
- r = g = b = l;
606
- } else {
607
- // @ts-ignore
608
- const hue2rgb = (p, q, t) => {
609
- if (t < 0) t += 1;
610
- if (t > 1) t -= 1;
611
- if (t < 1 / 6) return p + (q - p) * 6 * t;
612
- if (t < 1 / 2) return q;
613
- if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
614
- return p;
615
- };
616
-
617
- const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
618
- const p = 2 * l - q;
619
- r = hue2rgb(p, q, h + 1 / 3);
620
- g = hue2rgb(p, q, h);
621
- b = hue2rgb(p, q, h - 1 / 3);
622
- }
623
-
624
- return {
625
- r: Math.round(r * 255),
626
- g: Math.round(g * 255),
627
- b: Math.round(b * 255),
628
- };
629
- }
630
-
631
- // @ts-ignore
632
- function generateColorGradientSteps(n, colors) {
633
- const numColors = colors.length;
634
-
635
- // If there are fewer than two colors, return the original array
636
- if (numColors < 2) {
637
- return colors;
638
- }
639
-
640
- // Initialize the output array with the first color
641
- const output = [colors[0]];
642
-
643
- // Calculate the number of gradient steps between each pair of colors
644
- const stepsPerPair = Math.floor(n / (numColors - 1));
645
-
646
- // Generate the gradient steps for each pair of colors
647
- for (let i = 1; i < numColors; i++) {
648
- const color1 = colors[i - 1];
649
- const color2 = colors[i];
650
- const gradientSteps = generateGradientSteps(color1, color2, stepsPerPair);
651
- output.push(...gradientSteps);
652
- }
653
-
654
- // If there are remaining steps, add the last color as a stopgap measure
655
- while (output.length < n) {
656
- output.push(colors[numColors - 1]);
657
- }
658
-
659
- return output;
660
- }
661
-
662
- //@ts-ignore
663
- function generateGradientSteps(color1, color2, n) {
664
- // Convert the colors to RGB objects
665
- const rgb1 = hexToRgb(color1);
666
- const rgb2 = hexToRgb(color2);
667
-
668
- // Calculate the RGB color difference between the two colors
669
- const diffR = rgb2.r - rgb1.r;
670
- const diffG = rgb2.g - rgb1.g;
671
- const diffB = rgb2.b - rgb1.b;
672
-
673
- // Calculate the RGB gradient step size between the two colors
674
- const stepR = diffR / (n + 1);
675
- const stepG = diffG / (n + 1);
676
- const stepB = diffB / (n + 1);
677
-
678
- // Generate the RGB gradient steps
679
- const gradientSteps = [];
680
- for (let i = 1; i <= n; i++) {
681
- const r = Math.round(rgb1.r + stepR * i);
682
- const g = Math.round(rgb1.g + stepG * i);
683
- const b = Math.round(rgb1.b + stepB * i);
684
- gradientSteps.push(rgbToHex({ r, g, b }));
685
- }
686
-
687
- return gradientSteps;
688
- }
689
-
690
- const PieChartWrapper = React.forwardRef<HTMLDivElement, DonutChartProps>(
691
- (props, ref) => {
692
- const {
693
- category = 'pct_of_the_total',
694
- index = 'status',
695
- data,
696
- colors = [],
697
- variant = 'donut',
698
- valueFormatter = defaultValueFormatter,
699
- label,
700
- showLabel = true,
701
- showAnimation = true,
702
- showTooltip = true,
703
- className,
704
- containerStyle,
705
- theme,
706
- ...other
707
- } = props;
708
- const isDonut = variant == 'donut';
709
-
710
- const parsedLabelInput = parseLabelInput(
711
- label,
712
- valueFormatter,
713
- data,
714
- category
715
- );
716
-
717
- const newColors = generateColorGradientSteps(
718
- data.length,
719
- findComplementaryAndAnalogousColors(colors[0], colors[1])
720
- );
721
-
722
- return (
723
- <div
724
- ref={ref}
725
- style={{
726
- ...containerStyle,
727
- width: '100%',
728
- // height: '100%',
729
- display: 'flex',
730
- flexDirection: 'row',
731
- alignItems: 'center',
732
- boxSizing: 'content-box',
733
- }}
734
- // className={twMerge(
735
- // 'w-full h-full flex flex-row items-center',
736
- // className
737
- // )}
738
- {...other}
739
- >
740
- <ResponsiveContainer width="100%" height="100%">
741
- <PieChart>
742
- <Pie
743
- // style={{ transform: 'translateX(-120px)' }}
744
- data={parseData(
745
- data,
746
- colors.length >= data.length
747
- ? colors
748
- : generateColorGradientSteps(Math.min(21, data.length), [
749
- ...findComplementaryAndAnalogousColors(
750
- colors[0],
751
- colors[1]
752
- ),
753
- ...colors.slice(2),
754
- ]),
755
- index,
756
- category
757
- )}
758
- cx="50%"
759
- cy="50%"
760
- startAngle={90}
761
- endAngle={-270}
762
- innerRadius={isDonut ? '70%' : '0%'}
763
- outerRadius="100%"
764
- paddingAngle={0}
765
- dataKey={category}
766
- nameKey={index}
767
- isAnimationActive={true}
768
- />
769
- {/* <Legend
770
- layout="vertical"
771
- align="center"
772
- verticalAlign="middle"
773
- wrapperStyle={{
774
- paddingLeft: '20px',
775
- transform: 'translateX(120px)',
776
- }}
777
- content={({ payload }) => (
778
- <Legend2 payload={payload} colors={newColors} />
779
- )}
780
- /> */}
781
- <Tooltip
782
- wrapperStyle={{
783
- outline: 'none',
784
- }}
785
- content={({ active, payload }) => (
786
- <DonutChartTooltip
787
- active={active}
788
- payload={payload}
789
- valueFormatter={valueFormatter}
790
- theme={theme}
791
- />
792
- )}
793
- />
794
- </PieChart>
795
- </ResponsiveContainer>
796
- </div>
797
- );
798
- }
799
- );
800
-
801
- function Legend2({ payload, colors }: { payload: any; colors: string[] }) {
802
- return (
803
- <div
804
- // className="flex flex-col min-w-[130px] max-w-[130px] w-full"
805
- >
806
- {/* @ts-ignore */}
807
- {payload.map((item, idx) => {
808
- if (idx > 9) {
809
- return null;
810
- }
811
- return (
812
- <div
813
- key={item.value}
814
- // className="flex flex-row items-center min-w-[130px] max-w-[130px]"
815
- >
816
- <div
817
- style={{
818
- height: 8,
819
- width: 8,
820
- borderRadius: 8,
821
- background: colors[idx],
822
- marginRight: 8,
823
- marginTop: 2,
824
- }}
825
- />
826
- <div
827
- style={{
828
- whiteSpace: 'nowrap',
829
- overflow: 'hidden',
830
- textOverflow: 'ellipsis',
831
- display: 'block',
832
- maxWidth: 120,
833
- }}
834
- // className="qq-text-sm qq-text-gray-600 qq-whitespace-nowrap qq-overflow-hidden qq-overflow-ellipsis qq-text-sm qq-font-normal"
835
- >
836
- {item.value}
837
- </div>
838
- </div>
839
- );
840
- })}
841
- </div>
842
- );
843
- }
844
-
845
- export default PieChartWrapper;