@oneuptime/common 11.5.1 → 11.5.3

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 (66) hide show
  1. package/Server/Infrastructure/Postgres/SchemaMigrations/1783937343400-MigrationName.ts +1129 -0
  2. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +3 -1
  3. package/Server/Services/AnalyticsDatabaseService.ts +59 -7
  4. package/Server/Services/MetricService.ts +124 -28
  5. package/Server/Services/SpanService.ts +11 -0
  6. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +39 -0
  7. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +8 -5
  8. package/Server/Utils/Telemetry/LlmSpan.ts +38 -64
  9. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +84 -0
  10. package/Tests/Server/Services/MetricServiceAggregate.test.ts +167 -0
  11. package/Tests/Types/BaseDatabase/AggregationIntervalUtil.test.ts +40 -0
  12. package/Types/BaseDatabase/AggregateBy.ts +11 -1
  13. package/Types/BaseDatabase/AggregationInterval.ts +10 -0
  14. package/Types/BaseDatabase/AggregationIntervalUtil.ts +23 -0
  15. package/Types/Metrics/MetricFormulaConfigData.ts +5 -0
  16. package/Types/Metrics/MetricQueryConfigData.ts +19 -0
  17. package/Types/Telemetry/LlmConventions.ts +182 -0
  18. package/UI/Components/Charts/Area/AreaChart.tsx +15 -2
  19. package/UI/Components/Charts/Bar/BarChart.tsx +16 -2
  20. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +31 -32
  21. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +41 -17
  22. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +38 -34
  23. package/UI/Components/Charts/ChartLibrary/SparkChart/SparkChart.tsx +4 -3
  24. package/UI/Components/Charts/ChartLibrary/Utils/ChartColors.ts +48 -10
  25. package/UI/Components/Charts/Line/LineChart.tsx +15 -2
  26. package/UI/Components/Detail/PlaceholderText.tsx +1 -14
  27. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783937343400-MigrationName.js +384 -0
  28. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783937343400-MigrationName.js.map +1 -0
  29. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +3 -1
  30. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  31. package/build/dist/Server/Services/AnalyticsDatabaseService.js +43 -5
  32. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  33. package/build/dist/Server/Services/MetricService.js +110 -23
  34. package/build/dist/Server/Services/MetricService.js.map +1 -1
  35. package/build/dist/Server/Services/SpanService.js +10 -0
  36. package/build/dist/Server/Services/SpanService.js.map +1 -1
  37. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +32 -0
  38. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  39. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +2 -1
  40. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  41. package/build/dist/Server/Utils/Telemetry/LlmSpan.js +14 -54
  42. package/build/dist/Server/Utils/Telemetry/LlmSpan.js.map +1 -1
  43. package/build/dist/Types/BaseDatabase/AggregationInterval.js +10 -0
  44. package/build/dist/Types/BaseDatabase/AggregationInterval.js.map +1 -1
  45. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +13 -0
  46. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
  47. package/build/dist/Types/Telemetry/LlmConventions.js +149 -0
  48. package/build/dist/Types/Telemetry/LlmConventions.js.map +1 -0
  49. package/build/dist/UI/Components/Charts/Area/AreaChart.js +3 -1
  50. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  51. package/build/dist/UI/Components/Charts/Bar/BarChart.js +3 -1
  52. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  53. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +13 -9
  54. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  55. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +19 -7
  56. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  57. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +21 -9
  58. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  59. package/build/dist/UI/Components/Charts/ChartLibrary/SparkChart/SparkChart.js.map +1 -1
  60. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/ChartColors.js +26 -0
  61. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/ChartColors.js.map +1 -1
  62. package/build/dist/UI/Components/Charts/Line/LineChart.js +3 -1
  63. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  64. package/build/dist/UI/Components/Detail/PlaceholderText.js +1 -4
  65. package/build/dist/UI/Components/Detail/PlaceholderText.js.map +1 -1
  66. package/package.json +1 -1
@@ -1,5 +1,8 @@
1
1
  import { BarChart } from "../ChartLibrary/BarChart/BarChart";
2
- import { AvailableChartColorsKeys } from "../ChartLibrary/Utils/ChartColors";
2
+ import {
3
+ AvailableChartColorsKeys,
4
+ ChartColorValue,
5
+ } from "../ChartLibrary/Utils/ChartColors";
3
6
  import React, { FunctionComponent, ReactElement, useEffect } from "react";
4
7
  import SeriesPoint from "../Types/SeriesPoints";
5
8
  import { XAxis } from "../Types/XAxis/XAxis";
@@ -29,6 +32,13 @@ export interface ComponentProps {
29
32
  heightInPx?: number | undefined;
30
33
  referenceLines?: Array<ChartReferenceLineProps> | undefined;
31
34
  showLegend?: boolean | undefined;
35
+ /*
36
+ * Optional per-series color override. Each entry may be a named palette key
37
+ * or a raw hex string. When provided (and non-empty), it replaces the
38
+ * default BarChartPalette so callers can assign custom colors; the array is
39
+ * indexed by series position (index % length), matching the default palette.
40
+ */
41
+ colors?: Array<ChartColorValue> | undefined;
32
42
  }
33
43
 
34
44
  export interface BarInternalProps extends ComponentProps {
@@ -71,7 +81,11 @@ const BarChartElement: FunctionComponent<BarInternalProps> = (
71
81
  tickGap={30}
72
82
  index={"Time"}
73
83
  categories={categories}
74
- colors={BarChartPalette}
84
+ colors={
85
+ props.colors && props.colors.length > 0
86
+ ? props.colors
87
+ : BarChartPalette
88
+ }
75
89
  valueFormatter={props.yAxis.options.formatter || undefined}
76
90
  showTooltip={true}
77
91
  showLegend={props.showLegend !== false}
@@ -26,10 +26,11 @@ import { AxisDomain } from "recharts/types/util/types";
26
26
  import { useOnWindowResize } from "../Utils/UseWindowOnResize";
27
27
  import {
28
28
  AvailableChartColors,
29
- AvailableChartColorsKeys,
29
+ ChartColorValue,
30
30
  constructCategoryColors,
31
31
  getColorClassName,
32
32
  getColorHex,
33
+ isHexColorValue,
33
34
  } from "../Utils/ChartColors";
34
35
  import { cx } from "../Utils/Cx";
35
36
  import { getYAxisDomain } from "../Utils/GetYAxisDomain";
@@ -40,8 +41,8 @@ import ChartCurve from "../../Types/ChartCurve";
40
41
 
41
42
  interface LegendItemProps {
42
43
  name: string;
43
- color: AvailableChartColorsKeys;
44
- onClick?: (name: string, color: AvailableChartColorsKeys) => void;
44
+ color: ChartColorValue;
45
+ onClick?: (name: string, color: ChartColorValue) => void;
45
46
  activeLegend?: string;
46
47
  }
47
48
 
@@ -76,6 +77,11 @@ const LegendItem: ({
76
77
  getColorClassName(color, "bg"),
77
78
  activeLegend && activeLegend !== name ? "opacity-40" : "opacity-100",
78
79
  )}
80
+ style={
81
+ isHexColorValue(color)
82
+ ? { backgroundColor: getColorHex(color) }
83
+ : undefined
84
+ }
79
85
  aria-hidden={true}
80
86
  />
81
87
  <p
@@ -163,7 +169,7 @@ const ScrollButton: ({
163
169
 
164
170
  interface LegendProps extends React.OlHTMLAttributes<HTMLOListElement> {
165
171
  categories: string[];
166
- colors?: AvailableChartColorsKeys[];
172
+ colors?: ChartColorValue[];
167
173
  onClickLegendItem?: (category: string, color: string) => void;
168
174
  activeLegend?: string;
169
175
  enableLegendSlider?: boolean;
@@ -307,7 +313,7 @@ const Legend: React.ForwardRefExoticComponent<
307
313
  <LegendItem
308
314
  key={`item-${index}`}
309
315
  name={category}
310
- color={colors[index] as AvailableChartColorsKeys}
316
+ color={colors[index] as ChartColorValue}
311
317
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
312
318
  onClick={onClickLegendItem as any}
313
319
  activeLegend={activeLegend!}
@@ -356,7 +362,7 @@ type PayloadItem = {
356
362
  category: string;
357
363
  value: number;
358
364
  index: string;
359
- color: AvailableChartColorsKeys;
365
+ color: ChartColorValue;
360
366
  type?: string;
361
367
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
362
368
  payload: any;
@@ -366,7 +372,7 @@ type PayloadItem = {
366
372
  const ChartLegend: (
367
373
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
368
374
  { payload }: any,
369
- categoryColors: Map<string, AvailableChartColorsKeys>,
375
+ categoryColors: Map<string, ChartColorValue>,
370
376
  setLegendHeight: React.Dispatch<React.SetStateAction<number>>,
371
377
  activeLegend: string | undefined,
372
378
  onClick?: (category: string, color: string) => void,
@@ -376,7 +382,7 @@ const ChartLegend: (
376
382
  ) => React.JSX.Element = (
377
383
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
378
384
  { payload }: any,
379
- categoryColors: Map<string, AvailableChartColorsKeys>,
385
+ categoryColors: Map<string, ChartColorValue>,
380
386
  setLegendHeight: React.Dispatch<React.SetStateAction<number>>,
381
387
  activeLegend: string | undefined,
382
388
  onClick?: (category: string, color: string) => void,
@@ -485,6 +491,11 @@ const ChartTooltip: ({
485
491
  "h-[3px] w-3.5 shrink-0 rounded-full",
486
492
  getColorClassName(color, "bg"),
487
493
  )}
494
+ style={
495
+ isHexColorValue(color)
496
+ ? { backgroundColor: getColorHex(color) }
497
+ : undefined
498
+ }
488
499
  />
489
500
  <p
490
501
  className={cx(
@@ -534,7 +545,7 @@ interface AreaChartProps extends React.HTMLAttributes<HTMLDivElement> {
534
545
  data: Record<string, any>[];
535
546
  index: string;
536
547
  categories: string[];
537
- colors?: AvailableChartColorsKeys[];
548
+ colors?: ChartColorValue[];
538
549
  valueFormatter?: (value: number) => string;
539
550
  startEndOnly?: boolean;
540
551
  showXAxis?: boolean;
@@ -620,7 +631,7 @@ const AreaChart: React.ForwardRefExoticComponent<
620
631
  const [activeLegend, setActiveLegend] = React.useState<string | undefined>(
621
632
  undefined,
622
633
  );
623
- const categoryColors: Map<string, string | number> =
634
+ const categoryColors: Map<string, ChartColorValue> =
624
635
  constructCategoryColors(categories, colors);
625
636
 
626
637
  const yAxisDomain: (number | "auto")[] = getYAxisDomain(
@@ -716,9 +727,8 @@ const AreaChart: React.ForwardRefExoticComponent<
716
727
  >
717
728
  <defs>
718
729
  {categories.map((category: string, i: number) => {
719
- const colorKey: AvailableChartColorsKeys =
720
- (colors[i % colors.length] as AvailableChartColorsKeys) ||
721
- "blue";
730
+ const colorKey: ChartColorValue =
731
+ (colors[i % colors.length] as ChartColorValue) || "blue";
722
732
  const hex: string = getColorHex(colorKey);
723
733
  return (
724
734
  <linearGradient
@@ -833,7 +843,7 @@ const AreaChart: React.ForwardRefExoticComponent<
833
843
  index: item.payload[index],
834
844
  color: categoryColors.get(
835
845
  item.dataKey,
836
- ) as AvailableChartColorsKeys,
846
+ ) as ChartColorValue,
837
847
  type: item.type,
838
848
  payload: item.payload,
839
849
  };
@@ -921,10 +931,11 @@ const AreaChart: React.ForwardRefExoticComponent<
921
931
  ) : null}
922
932
  {categories.map((category: string) => {
923
933
  const gradientId: string = `gradient-${category.replace(/[^a-zA-Z0-9]/g, "_")}`;
924
- const colorKey: AvailableChartColorsKeys = categoryColors.get(
934
+ const colorKey: ChartColorValue = categoryColors.get(
925
935
  category,
926
- ) as AvailableChartColorsKeys;
936
+ ) as ChartColorValue;
927
937
  const hex: string = getColorHex(colorKey);
938
+ const isCustomColor: boolean = isHexColorValue(colorKey);
928
939
 
929
940
  return (
930
941
  <Area
@@ -954,24 +965,18 @@ const AreaChart: React.ForwardRefExoticComponent<
954
965
  strokeLinecap: slc,
955
966
  strokeLinejoin: slj,
956
967
  strokeWidth,
957
- dataKey,
958
968
  } = dotProps;
959
969
  return (
960
970
  <Dot
961
971
  className={cx(
962
972
  "stroke-white",
963
973
  onValueChange ? "cursor-pointer" : "",
964
- getColorClassName(
965
- categoryColors.get(
966
- dataKey,
967
- ) as AvailableChartColorsKeys,
968
- "fill",
969
- ),
974
+ getColorClassName(colorKey, "fill"),
970
975
  )}
971
976
  cx={cxCoord}
972
977
  cy={cyCoord}
973
978
  r={5}
974
- fill=""
979
+ fill={isCustomColor ? hex : ""}
975
980
  stroke={stroke}
976
981
  strokeLinecap={slc}
977
982
  strokeLinejoin={slj}
@@ -992,7 +997,6 @@ const AreaChart: React.ForwardRefExoticComponent<
992
997
  strokeWidth,
993
998
  cx: cxCoord,
994
999
  cy: cyCoord,
995
- dataKey,
996
1000
  index: dotIndex,
997
1001
  } = dotProps;
998
1002
 
@@ -1012,19 +1016,14 @@ const AreaChart: React.ForwardRefExoticComponent<
1012
1016
  cy={cyCoord}
1013
1017
  r={5}
1014
1018
  stroke={stroke}
1015
- fill=""
1019
+ fill={isCustomColor ? hex : ""}
1016
1020
  strokeLinecap={slc}
1017
1021
  strokeLinejoin={slj}
1018
1022
  strokeWidth={strokeWidth}
1019
1023
  className={cx(
1020
1024
  "stroke-white",
1021
1025
  onValueChange ? "cursor-pointer" : "",
1022
- getColorClassName(
1023
- categoryColors.get(
1024
- dataKey,
1025
- ) as AvailableChartColorsKeys,
1026
- "fill",
1027
- ),
1026
+ getColorClassName(colorKey, "fill"),
1028
1027
  )}
1029
1028
  />
1030
1029
  );
@@ -22,9 +22,11 @@ import type { AxisDomain } from "recharts/types/util/types";
22
22
 
23
23
  import {
24
24
  AvailableChartColors,
25
- type AvailableChartColorsKeys,
25
+ type ChartColorValue,
26
26
  constructCategoryColors,
27
27
  getColorClassName,
28
+ getColorHex,
29
+ isHexColorValue,
28
30
  } from "../Utils/ChartColors";
29
31
  import { cx } from "../Utils/Cx";
30
32
  import { getYAxisDomain } from "../Utils/GetYAxisDomain";
@@ -73,7 +75,7 @@ const renderShape: (
73
75
  activeLegend: string | undefined,
74
76
  layout: string,
75
77
  ): React.ReactElement => {
76
- const { fillOpacity, name, payload, value } = props;
78
+ const { fillOpacity, name, payload, value, fill } = props;
77
79
  let { x, width, y, height } = props;
78
80
 
79
81
  if (layout === "horizontal" && height < 0) {
@@ -120,6 +122,12 @@ const renderShape: (
120
122
  return (
121
123
  <path
122
124
  d={path}
125
+ /*
126
+ * A custom hex color is passed through as the Bar's `fill` prop; apply
127
+ * it directly on the path. For named palette colors `fill` is "" and the
128
+ * path inherits the Tailwind `fill-*` class set on the parent Bar.
129
+ */
130
+ {...(fill ? { fill } : {})}
123
131
  opacity={
124
132
  activeBar || (activeLegend && activeLegend !== name)
125
133
  ? deepEqual(activeBar, { ...payload, value })
@@ -135,7 +143,7 @@ const renderShape: (
135
143
 
136
144
  interface LegendItemProps {
137
145
  name: string;
138
- color: AvailableChartColorsKeys;
146
+ color: ChartColorValue;
139
147
  onClick?: (name: string, color: string) => void;
140
148
  activeLegend?: string;
141
149
  }
@@ -167,6 +175,11 @@ const LegendItem: React.FunctionComponent<LegendItemProps> = ({
167
175
  getColorClassName(color, "bg"),
168
176
  activeLegend && activeLegend !== name ? "opacity-40" : "opacity-100",
169
177
  )}
178
+ style={
179
+ isHexColorValue(color)
180
+ ? { backgroundColor: getColorHex(color) }
181
+ : undefined
182
+ }
170
183
  aria-hidden={true}
171
184
  />
172
185
  <p
@@ -252,7 +265,7 @@ const ScrollButton: React.FunctionComponent<ScrollButtonProps> = ({
252
265
 
253
266
  interface LegendProps extends React.OlHTMLAttributes<HTMLOListElement> {
254
267
  categories: string[];
255
- colors?: AvailableChartColorsKeys[];
268
+ colors?: ChartColorValue[];
256
269
  onClickLegendItem?: (category: string, color: string) => void;
257
270
  activeLegend?: string;
258
271
  enableLegendSlider?: boolean;
@@ -398,7 +411,7 @@ const Legend: React.ForwardRefExoticComponent<
398
411
  <LegendItem
399
412
  key={`item-${index}`}
400
413
  name={category}
401
- color={colors[index] as AvailableChartColorsKeys}
414
+ color={colors[index] as ChartColorValue}
402
415
  {...(onClickLegendItem ? { onClick: onClickLegendItem } : {})}
403
416
  {...(activeLegend ? { activeLegend: activeLegend } : {})}
404
417
  />
@@ -443,7 +456,7 @@ Legend.displayName = "Legend";
443
456
 
444
457
  const ChartLegend: (
445
458
  payload: any,
446
- categoryColors: Map<string, AvailableChartColorsKeys>,
459
+ categoryColors: Map<string, ChartColorValue>,
447
460
  setLegendHeight: React.Dispatch<React.SetStateAction<number>>,
448
461
  activeLegend: string | undefined,
449
462
  onClick?: (category: string, color: string) => void,
@@ -452,7 +465,7 @@ const ChartLegend: (
452
465
  yAxisWidth?: number,
453
466
  ) => React.ReactElement = (
454
467
  { payload }: any,
455
- categoryColors: Map<string, AvailableChartColorsKeys>,
468
+ categoryColors: Map<string, ChartColorValue>,
456
469
  setLegendHeight: React.Dispatch<React.SetStateAction<number>>,
457
470
  activeLegend: string | undefined,
458
471
  onClick?: (category: string, color: string) => void,
@@ -497,7 +510,7 @@ const ChartLegend: (
497
510
  return entry.value;
498
511
  })}
499
512
  colors={filteredPayload.map((entry: any) => {
500
- return categoryColors.get(entry.value) as AvailableChartColorsKeys;
513
+ return categoryColors.get(entry.value) as ChartColorValue;
501
514
  })}
502
515
  {...(onClick ? { onClickLegendItem: onClick } : {})}
503
516
  {...(activeLegend ? { activeLegend: activeLegend } : {})}
@@ -518,7 +531,7 @@ type PayloadItem = {
518
531
  category: string; // eslint-disable-line react/no-unused-prop-types
519
532
  value: number; // eslint-disable-line react/no-unused-prop-types
520
533
  index: string; // eslint-disable-line react/no-unused-prop-types
521
- color: AvailableChartColorsKeys; // eslint-disable-line react/no-unused-prop-types
534
+ color: ChartColorValue; // eslint-disable-line react/no-unused-prop-types
522
535
  type?: string; // eslint-disable-line react/no-unused-prop-types
523
536
  payload: any;
524
537
  };
@@ -575,6 +588,11 @@ const ChartTooltip: React.FunctionComponent<ChartTooltipProps> = ({
575
588
  "size-2 shrink-0 rounded-xs",
576
589
  getColorClassName(color, "bg"),
577
590
  )}
591
+ style={
592
+ isHexColorValue(color)
593
+ ? { backgroundColor: getColorHex(color) }
594
+ : undefined
595
+ }
578
596
  />
579
597
  <p
580
598
  className={cx(
@@ -622,7 +640,7 @@ interface BarChartProps extends React.HTMLAttributes<HTMLDivElement> {
622
640
  data: Record<string, any>[];
623
641
  index: string;
624
642
  categories: string[];
625
- colors?: AvailableChartColorsKeys[];
643
+ colors?: ChartColorValue[];
626
644
  valueFormatter?: (value: number) => string;
627
645
  startEndOnly?: boolean;
628
646
  showXAxis?: boolean;
@@ -699,7 +717,7 @@ const BarChart: React.ForwardRefExoticComponent<
699
717
  const [activeLegend, setActiveLegend] = React.useState<string | undefined>(
700
718
  undefined,
701
719
  );
702
- const categoryColors: Map<string, AvailableChartColorsKeys> =
720
+ const categoryColors: Map<string, ChartColorValue> =
703
721
  constructCategoryColors(categories, colors);
704
722
  const [activeBar, setActiveBar] = React.useState<any | undefined>(
705
723
  undefined,
@@ -942,7 +960,7 @@ const BarChart: React.ForwardRefExoticComponent<
942
960
  index: item.payload[index],
943
961
  color: categoryColors.get(
944
962
  item.dataKey,
945
- ) as AvailableChartColorsKeys,
963
+ ) as ChartColorValue,
946
964
  type: item.type,
947
965
  payload: item.payload,
948
966
  };
@@ -1000,13 +1018,14 @@ const BarChart: React.ForwardRefExoticComponent<
1000
1018
  />
1001
1019
  ) : null}
1002
1020
  {categories.map((category: string) => {
1021
+ const barColor: ChartColorValue = categoryColors.get(
1022
+ category,
1023
+ ) as ChartColorValue;
1024
+ const isCustomColor: boolean = isHexColorValue(barColor);
1003
1025
  return (
1004
1026
  <Bar
1005
1027
  className={cx(
1006
- getColorClassName(
1007
- categoryColors.get(category) as AvailableChartColorsKeys,
1008
- "fill",
1009
- ),
1028
+ getColorClassName(barColor, "fill"),
1010
1029
  onValueChange ? "cursor-pointer" : "",
1011
1030
  )}
1012
1031
  key={category}
@@ -1015,7 +1034,12 @@ const BarChart: React.ForwardRefExoticComponent<
1015
1034
  dataKey={category}
1016
1035
  {...(stacked ? { stackId: "stack" } : {})}
1017
1036
  isAnimationActive={false}
1018
- fill=""
1037
+ /*
1038
+ * Custom hex → apply the color inline (Tailwind has no class
1039
+ * for arbitrary user hex); named palette → keep "" so the
1040
+ * `fill-*` class on the Bar cascades to the shape path.
1041
+ */
1042
+ fill={isCustomColor ? getColorHex(barColor) : ""}
1019
1043
  shape={shapeRenderer}
1020
1044
  onClick={onBarClick}
1021
1045
  />
@@ -27,9 +27,11 @@ import { AxisDomain } from "recharts/types/util/types";
27
27
  import { useOnWindowResize } from "../Utils/UseWindowOnResize";
28
28
  import {
29
29
  AvailableChartColors,
30
- AvailableChartColorsKeys,
30
+ ChartColorValue,
31
31
  constructCategoryColors,
32
32
  getColorClassName,
33
+ getColorHex,
34
+ isHexColorValue,
33
35
  } from "../Utils/ChartColors";
34
36
  import { cx } from "../Utils/Cx";
35
37
  import { getYAxisDomain } from "../Utils/GetYAxisDomain";
@@ -40,8 +42,8 @@ import ChartCurve from "../../Types/ChartCurve";
40
42
 
41
43
  interface LegendItemProps {
42
44
  name: string;
43
- color: AvailableChartColorsKeys;
44
- onClick?: (name: string, color: AvailableChartColorsKeys) => void;
45
+ color: ChartColorValue;
46
+ onClick?: (name: string, color: ChartColorValue) => void;
45
47
  activeLegend?: string;
46
48
  }
47
49
 
@@ -77,6 +79,11 @@ const LegendItem: ({
77
79
  getColorClassName(color, "bg"),
78
80
  activeLegend && activeLegend !== name ? "opacity-40" : "opacity-100",
79
81
  )}
82
+ style={
83
+ isHexColorValue(color)
84
+ ? { backgroundColor: getColorHex(color) }
85
+ : undefined
86
+ }
80
87
  aria-hidden={true}
81
88
  />
82
89
  <p
@@ -166,7 +173,7 @@ const ScrollButton: ({
166
173
 
167
174
  interface LegendProps extends React.OlHTMLAttributes<HTMLOListElement> {
168
175
  categories: string[];
169
- colors?: AvailableChartColorsKeys[];
176
+ colors?: ChartColorValue[];
170
177
  onClickLegendItem?: (category: string, color: string) => void;
171
178
  activeLegend?: string;
172
179
  enableLegendSlider?: boolean;
@@ -310,7 +317,7 @@ const Legend: React.ForwardRefExoticComponent<
310
317
  <LegendItem
311
318
  key={`item-${index}`}
312
319
  name={category}
313
- color={colors[index] as AvailableChartColorsKeys}
320
+ color={colors[index] as ChartColorValue}
314
321
  onClick={onClickLegendItem as any}
315
322
  activeLegend={activeLegend!}
316
323
  />
@@ -356,7 +363,7 @@ Legend.displayName = "Legend";
356
363
 
357
364
  const ChartLegend: (
358
365
  { payload }: any,
359
- categoryColors: Map<string, AvailableChartColorsKeys>,
366
+ categoryColors: Map<string, ChartColorValue>,
360
367
  setLegendHeight: React.Dispatch<React.SetStateAction<number>>,
361
368
  activeLegend: string | undefined,
362
369
  onClick?: (category: string, color: string) => void,
@@ -365,7 +372,7 @@ const ChartLegend: (
365
372
  yAxisWidth?: number,
366
373
  ) => React.JSX.Element = (
367
374
  { payload }: any,
368
- categoryColors: Map<string, AvailableChartColorsKeys>,
375
+ categoryColors: Map<string, ChartColorValue>,
369
376
  setLegendHeight: React.Dispatch<React.SetStateAction<number>>,
370
377
  activeLegend: string | undefined,
371
378
  onClick?: (category: string, color: string) => void,
@@ -432,7 +439,7 @@ export type PayloadItem = {
432
439
  // eslint-disable-next-line react/no-unused-prop-types
433
440
  index: string;
434
441
  // eslint-disable-next-line react/no-unused-prop-types
435
- color: AvailableChartColorsKeys;
442
+ color: ChartColorValue;
436
443
  // eslint-disable-next-line react/no-unused-prop-types
437
444
  type?: string;
438
445
  // eslint-disable-next-line react/no-unused-prop-types
@@ -499,6 +506,11 @@ const ChartTooltip: ({
499
506
  "h-[3px] w-3.5 shrink-0 rounded-full",
500
507
  getColorClassName(color, "bg"),
501
508
  )}
509
+ style={
510
+ isHexColorValue(color)
511
+ ? { backgroundColor: getColorHex(color) }
512
+ : undefined
513
+ }
502
514
  />
503
515
  <p
504
516
  className={cx(
@@ -551,7 +563,7 @@ interface LineChartProps extends React.HTMLAttributes<HTMLDivElement> {
551
563
  data: Record<string, any>[];
552
564
  index: string;
553
565
  categories: string[];
554
- colors?: AvailableChartColorsKeys[];
566
+ colors?: ChartColorValue[];
555
567
  valueFormatter?: (value: number) => string;
556
568
  startEndOnly?: boolean;
557
569
  showXAxis?: boolean;
@@ -628,7 +640,7 @@ const LineChart: React.ForwardRefExoticComponent<
628
640
  const [activeLegend, setActiveLegend] = React.useState<string | undefined>(
629
641
  undefined,
630
642
  );
631
- const categoryColors: Map<string, string | number> =
643
+ const categoryColors: Map<string, ChartColorValue> =
632
644
  constructCategoryColors(categories, colors);
633
645
 
634
646
  const yAxisDomain: (number | "auto")[] = getYAxisDomain(
@@ -828,7 +840,7 @@ const LineChart: React.ForwardRefExoticComponent<
828
840
  index: item.payload[index],
829
841
  color: categoryColors.get(
830
842
  item.dataKey,
831
- ) as AvailableChartColorsKeys,
843
+ ) as ChartColorValue,
832
844
  type: item.type,
833
845
  payload: item.payload,
834
846
  };
@@ -887,14 +899,14 @@ const LineChart: React.ForwardRefExoticComponent<
887
899
  />
888
900
  ) : null}
889
901
  {categories.map((category: string) => {
902
+ const lineColor: ChartColorValue = categoryColors.get(
903
+ category,
904
+ ) as ChartColorValue;
905
+ const isCustomColor: boolean = isHexColorValue(lineColor);
906
+ const lineHex: string = getColorHex(lineColor);
890
907
  return (
891
908
  <Line
892
- className={cx(
893
- getColorClassName(
894
- categoryColors.get(category) as AvailableChartColorsKeys,
895
- "stroke",
896
- ),
897
- )}
909
+ className={cx(getColorClassName(lineColor, "stroke"))}
898
910
  strokeOpacity={
899
911
  activeDot || (activeLegend && activeLegend !== category)
900
912
  ? 0.3
@@ -908,24 +920,18 @@ const LineChart: React.ForwardRefExoticComponent<
908
920
  strokeLinecap,
909
921
  strokeLinejoin,
910
922
  strokeWidth,
911
- dataKey,
912
923
  } = props;
913
924
  return (
914
925
  <Dot
915
926
  className={cx(
916
927
  "stroke-white",
917
928
  onValueChange ? "cursor-pointer" : "",
918
- getColorClassName(
919
- categoryColors.get(
920
- dataKey,
921
- ) as AvailableChartColorsKeys,
922
- "fill",
923
- ),
929
+ getColorClassName(lineColor, "fill"),
924
930
  )}
925
931
  cx={cxCoord}
926
932
  cy={cyCoord}
927
933
  r={5}
928
- fill=""
934
+ fill={isCustomColor ? lineHex : ""}
929
935
  stroke={stroke}
930
936
  strokeLinecap={strokeLinecap}
931
937
  strokeLinejoin={strokeLinejoin}
@@ -944,7 +950,6 @@ const LineChart: React.ForwardRefExoticComponent<
944
950
  strokeWidth,
945
951
  cx: cxCoord,
946
952
  cy: cyCoord,
947
- dataKey,
948
953
  index,
949
954
  } = props;
950
955
 
@@ -964,19 +969,14 @@ const LineChart: React.ForwardRefExoticComponent<
964
969
  cy={cyCoord}
965
970
  r={5}
966
971
  stroke={stroke}
967
- fill=""
972
+ fill={isCustomColor ? lineHex : ""}
968
973
  strokeLinecap={strokeLinecap}
969
974
  strokeLinejoin={strokeLinejoin}
970
975
  strokeWidth={strokeWidth}
971
976
  className={cx(
972
977
  "stroke-white",
973
978
  onValueChange ? "cursor-pointer" : "",
974
- getColorClassName(
975
- categoryColors.get(
976
- dataKey,
977
- ) as AvailableChartColorsKeys,
978
- "fill",
979
- ),
979
+ getColorClassName(lineColor, "fill"),
980
980
  )}
981
981
  />
982
982
  );
@@ -987,7 +987,11 @@ const LineChart: React.ForwardRefExoticComponent<
987
987
  name={category}
988
988
  type={props.curve || ChartCurve.LINEAR}
989
989
  dataKey={category}
990
- stroke=""
990
+ /*
991
+ * Custom hex → set the stroke inline; named palette → keep ""
992
+ * so the `stroke-*` Tailwind class on the Line applies.
993
+ */
994
+ stroke={isCustomColor ? lineHex : ""}
991
995
  strokeWidth={2}
992
996
  strokeLinejoin="round"
993
997
  strokeLinecap="round"
@@ -21,6 +21,7 @@ import type { AxisDomain } from "recharts/types/util/types";
21
21
  import {
22
22
  AvailableChartColors,
23
23
  type AvailableChartColorsKeys,
24
+ type ChartColorValue,
24
25
  constructCategoryColors,
25
26
  getColorClassName,
26
27
  } from "../Utils/ChartColors";
@@ -64,7 +65,7 @@ const SparkAreaChart: React.ForwardRefExoticComponent<
64
65
  ...other
65
66
  } = props;
66
67
 
67
- const categoryColors: Map<string, AvailableChartColorsKeys> =
68
+ const categoryColors: Map<string, ChartColorValue> =
68
69
  constructCategoryColors(categories, colors);
69
70
  const yAxisDomain: AxisDomain = getYAxisDomain(
70
71
  autoMinValue,
@@ -209,7 +210,7 @@ const SparkLineChart: React.ForwardRefExoticComponent<
209
210
  ...other
210
211
  } = props;
211
212
 
212
- const categoryColors: Map<string, AvailableChartColorsKeys> =
213
+ const categoryColors: Map<string, ChartColorValue> =
213
214
  constructCategoryColors(categories, colors);
214
215
  const yAxisDomain: AxisDomain = getYAxisDomain(
215
216
  autoMinValue,
@@ -304,7 +305,7 @@ const SparkBarChart: React.ForwardRefExoticComponent<
304
305
  ...other
305
306
  } = props;
306
307
 
307
- const categoryColors: Map<string, AvailableChartColorsKeys> =
308
+ const categoryColors: Map<string, ChartColorValue> =
308
309
  constructCategoryColors(categories, colors);
309
310
 
310
311
  const yAxisDomain: AxisDomain = getYAxisDomain(