remoraid 3.5.0 → 3.7.0

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.
@@ -725,7 +725,7 @@ var require_lodash = __commonJS((exports2, module2) => {
725
725
  }
726
726
  var runInContext = function runInContext(context) {
727
727
  context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
728
- var { Array: Array2, Date: Date2, Error: Error2, Function: Function2, Math: Math2, Object: Object2, RegExp: RegExp2, String, TypeError: TypeError2 } = context;
728
+ var { Array: Array2, Date: Date2, Error: Error2, Function: Function2, Math: Math2, Object: Object2, RegExp: RegExp2, String: String2, TypeError: TypeError2 } = context;
729
729
  var arrayProto = Array2.prototype, funcProto = Function2.prototype, objectProto = Object2.prototype;
730
730
  var coreJsData = context["__core-js_shared__"];
731
731
  var funcToString = funcProto.toString;
@@ -1041,7 +1041,7 @@ var require_lodash = __commonJS((exports2, module2) => {
1041
1041
  Stack2.prototype.has = stackHas;
1042
1042
  Stack2.prototype.set = stackSet;
1043
1043
  function arrayLikeKeys(value, inherited) {
1044
- var isArr = isArray(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result2 = skipIndexes ? baseTimes(value.length, String) : [], length = result2.length;
1044
+ var isArr = isArray(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result2 = skipIndexes ? baseTimes(value.length, String2) : [], length = result2.length;
1045
1045
  for (var key in value) {
1046
1046
  if ((inherited || hasOwnProperty.call(value, key)) && !(skipIndexes && (key == "length" || isBuff && (key == "offset" || key == "parent") || isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || isIndex(key, length)))) {
1047
1047
  result2.push(key);
@@ -5463,6 +5463,7 @@ __export(exports_data_visualization, {
5463
5463
  useNivoConfiguration: () => useNivoConfiguration,
5464
5464
  useChartsUserExperience: () => useChartsUserExperience,
5465
5465
  reduceTimeSeriesEntities: () => reduceTimeSeriesEntities,
5466
+ reduceTimeSeriesDimensions: () => reduceTimeSeriesDimensions,
5466
5467
  missingDataAlertProps: () => missingDataAlertProps,
5467
5468
  mergeTimeSeries: () => mergeTimeSeries,
5468
5469
  getChartTypeName: () => getChartTypeName,
@@ -5545,44 +5546,47 @@ function Tooltip({
5545
5546
  /* @__PURE__ */ jsx_runtime.jsxs(import_core.Stack, {
5546
5547
  gap: valuesVerticalGap,
5547
5548
  children: [
5548
- Object.entries(payload).sort((a, b) => Math.abs(Number(b[1].value)) - Math.abs(Number(a[1].value))).slice(0, maxItems ?? undefined).map(([key, { value, color, unit }], i) => /* @__PURE__ */ jsx_runtime.jsxs(import_core.Group, {
5549
- gap: valuesHorizontalGap,
5550
- wrap: "nowrap",
5551
- justify: "space-between",
5552
- children: [
5553
- /* @__PURE__ */ jsx_runtime.jsxs(import_core.Group, {
5554
- gap: "xs",
5555
- wrap: "nowrap",
5556
- align: "center",
5557
- children: [
5558
- color !== undefined && /* @__PURE__ */ jsx_runtime.jsx(import_core.Center, {
5559
- children: /* @__PURE__ */ jsx_runtime.jsx(import_icons_react.IconCircleFilled, {
5560
- ...theme.componentsProps.icons.medium,
5561
- color
5549
+ Object.entries(payload).sort((a, b) => Math.abs(Number(b[1].value)) - Math.abs(Number(a[1].value))).slice(0, maxItems ?? undefined).map(([key, { value, color, unit }], i) => {
5550
+ const formattedValue = String(valueFormat?.(value) ?? value);
5551
+ return /* @__PURE__ */ jsx_runtime.jsxs(import_core.Group, {
5552
+ gap: valuesHorizontalGap,
5553
+ wrap: "nowrap",
5554
+ justify: "space-between",
5555
+ children: [
5556
+ /* @__PURE__ */ jsx_runtime.jsxs(import_core.Group, {
5557
+ gap: "xs",
5558
+ wrap: "nowrap",
5559
+ align: "center",
5560
+ children: [
5561
+ color !== undefined && /* @__PURE__ */ jsx_runtime.jsx(import_core.Center, {
5562
+ children: /* @__PURE__ */ jsx_runtime.jsx(import_icons_react.IconCircleFilled, {
5563
+ ...theme.componentsProps.icons.medium,
5564
+ color
5565
+ })
5566
+ }),
5567
+ /* @__PURE__ */ jsx_runtime.jsx(import_core.Text, {
5568
+ size: "sm",
5569
+ ...componentsProps?.valueText,
5570
+ style: {
5571
+ textWrap: "nowrap",
5572
+ ...componentsProps?.valueText?.style
5573
+ },
5574
+ children: key
5562
5575
  })
5563
- }),
5564
- /* @__PURE__ */ jsx_runtime.jsx(import_core.Text, {
5565
- size: "sm",
5566
- ...componentsProps?.valueText,
5567
- style: {
5568
- textWrap: "nowrap",
5569
- ...componentsProps?.valueText?.style
5570
- },
5571
- children: key
5572
- })
5573
- ]
5574
- }, `entry-key-${i}`),
5575
- /* @__PURE__ */ jsx_runtime.jsx(import_core.Text, {
5576
- size: "sm",
5577
- ...componentsProps?.valueText,
5578
- style: {
5579
- textWrap: "nowrap",
5580
- ...componentsProps?.valueText?.style
5581
- },
5582
- children: `${valueFormat !== undefined ? valueFormat(value) : value} ${unit ?? ""}`
5583
- }, `entry-value-${i}`)
5584
- ]
5585
- }, i)),
5576
+ ]
5577
+ }, `entry-key-${i}`),
5578
+ /* @__PURE__ */ jsx_runtime.jsx(import_core.Text, {
5579
+ size: "sm",
5580
+ ...componentsProps?.valueText,
5581
+ style: {
5582
+ textWrap: "nowrap",
5583
+ ...componentsProps?.valueText?.style
5584
+ },
5585
+ children: unit ? `${formattedValue} ${unit}` : formattedValue
5586
+ }, `entry-value-${i}`)
5587
+ ]
5588
+ }, i);
5589
+ }),
5586
5590
  maxItems !== null && Object.entries(payload).length > maxItems && /* @__PURE__ */ jsx_runtime.jsxs(import_core.Text, {
5587
5591
  size: "sm",
5588
5592
  c: "dimmed",
@@ -5804,6 +5808,18 @@ var reduceTimeSeriesEntities = ({ values, units }, reducer, initial) => {
5804
5808
  }))
5805
5809
  };
5806
5810
  };
5811
+ var reduceTimeSeriesDimensions = ({ values }, reducer, initial, units) => {
5812
+ return {
5813
+ units,
5814
+ values: values.map(({ date, entities }) => ({
5815
+ date,
5816
+ entities: Object.fromEntries(Object.entries(entities).map(([entity, dimensions]) => [
5817
+ entity,
5818
+ Object.entries(dimensions).reduce(reducer, structuredClone(initial))
5819
+ ]))
5820
+ }))
5821
+ };
5822
+ };
5807
5823
  var emptyTimeSeriesData = {
5808
5824
  values: [],
5809
5825
  units: {}
@@ -5898,6 +5914,7 @@ function RingSummary({
5898
5914
  // src/data-visualization/components/Chart/index.tsx
5899
5915
  var import_lodash2 = __toESM(require_lodash());
5900
5916
  var import_d3_array = require("d3-array");
5917
+ var import_colors = require("@nivo/colors");
5901
5918
  var jsx_runtime5 = require("react/jsx-runtime");
5902
5919
  function Chart({
5903
5920
  type,
@@ -5918,11 +5935,13 @@ function Chart({
5918
5935
  let includeEntityChips = true;
5919
5936
  let includeLegend = false;
5920
5937
  let entities = [];
5938
+ let chartColors = [];
5921
5939
  let chart;
5922
5940
  const controls = [];
5923
5941
  if (type === "timeSeriesStackedAreas" /* TimeSeriesStackedAreas */) {
5924
5942
  includeEntityChips = options.includeEntityChips ?? true;
5925
5943
  includeLegend = options?.includeLegend ?? includeLegend;
5944
+ chartColors = componentsProps?.chart?.colors ?? options?.colors ?? nivoConfiguration.colors;
5926
5945
  data.values.sort((a, b) => a.date.getTime() - b.date.getTime());
5927
5946
  const guideValue = data.values.length > 0 ? data.values[data.values.length - 1 - windowOffset] : null;
5928
5947
  const chartData = [];
@@ -5952,7 +5971,6 @@ function Chart({
5952
5971
  } : undefined;
5953
5972
  const unit = data.units[options.dimension];
5954
5973
  chart = /* @__PURE__ */ jsx_runtime5.jsx(import_stream.ResponsiveStream, {
5955
- colors: options.colors ?? nivoConfiguration.colors,
5956
5974
  theme: nivoConfiguration.theme,
5957
5975
  data: chartData,
5958
5976
  keys: entities,
@@ -6011,7 +6029,8 @@ function Chart({
6011
6029
  }),
6012
6030
  curve: "linear",
6013
6031
  offsetType: "diverging",
6014
- ...componentsProps?.chart
6032
+ ...componentsProps?.chart,
6033
+ colors: chartColors
6015
6034
  }, entities.join(","));
6016
6035
  const increaseWindowOffsetButton = /* @__PURE__ */ jsx_runtime5.jsx(import_core10.RemoraidButton, {
6017
6036
  mounted: window !== null,
@@ -6115,11 +6134,13 @@ function Chart({
6115
6134
  p95Value = import_d3_array.quantileSorted(sortedSparklineData, 0.95) ?? 0;
6116
6135
  progress = Math.max(0, Math.min(100, p95Value === p5Value ? 0 : (currentValue - p5Value) / (p95Value - p5Value) * 100));
6117
6136
  }
6137
+ const formattedCurrentValue = String(options.valueFormat?.(currentValue) ?? currentValue);
6138
+ const unit = data.units[options.dimension];
6118
6139
  chart = /* @__PURE__ */ jsx_runtime5.jsx(RingSummary, {
6119
6140
  label: options.entity,
6120
6141
  color: options.color ?? chartsUserExperience.colors[0],
6121
6142
  progress,
6122
- value: sparklineData.length > 0 ? `${options.valueFormat?.(currentValue) ?? currentValue} ${data.units[options.dimension]}` : "No data",
6143
+ value: sparklineData.length > 0 ? unit ? `${formattedCurrentValue} ${unit}` : formattedCurrentValue : "No data",
6123
6144
  icon: options.icon,
6124
6145
  sparklineData,
6125
6146
  ...componentsProps?.chart
@@ -6130,6 +6151,7 @@ function Chart({
6130
6151
  }
6131
6152
  const includeControls = controls.length > 0;
6132
6153
  const numCols = Number(includeEntityChips) + Number(includeControls);
6154
+ const getEntityColor = import_colors.useOrdinalColorScale(chartColors, "id");
6133
6155
  return /* @__PURE__ */ jsx_runtime5.jsx(import_core9.Transition, {
6134
6156
  mounted,
6135
6157
  children: (transitionStyle) => /* @__PURE__ */ jsx_runtime5.jsxs(import_core9.Paper, {
@@ -6156,13 +6178,13 @@ function Chart({
6156
6178
  onChange: (newValue) => {
6157
6179
  setHiddenEntities(entities.filter((e) => !newValue.includes(e)));
6158
6180
  },
6159
- children: entities.map((entitiy, i) => /* @__PURE__ */ jsx_runtime5.jsx(import_core9.Chip, {
6160
- value: entitiy,
6181
+ children: entities.map((entity, i) => /* @__PURE__ */ jsx_runtime5.jsx(import_core9.Chip, {
6182
+ value: entity,
6161
6183
  icon: /* @__PURE__ */ jsx_runtime5.jsx(import_icons_react2.IconCheck, {
6162
6184
  ...theme.componentsProps.icons.tiny
6163
6185
  }),
6164
- color: chartsUserExperience.colors[i % chartsUserExperience.colors.length],
6165
- children: entitiy
6186
+ color: getEntityColor({ id: entity, path: "" }),
6187
+ children: entity
6166
6188
  }, i))
6167
6189
  })
6168
6190
  }),
@@ -6398,26 +6420,33 @@ var import_modals = require("@mantine/modals");
6398
6420
  var import_icons_react4 = require("@tabler/icons-react");
6399
6421
  var import_react5 = require("react");
6400
6422
  var import_core18 = require("remoraid/core");
6423
+ var import_colors2 = require("@nivo/colors");
6401
6424
  var jsx_runtime11 = require("react/jsx-runtime");
6402
6425
  var defaultTimeseriesExplorerWidgetId = "timeseries-explorer";
6403
6426
  function TimeSeriesExplorerWidget({
6404
6427
  data,
6405
6428
  isLoadingData,
6429
+ hideZeroOnlyEntities = true,
6406
6430
  widgetProps,
6407
6431
  componentsProps
6408
6432
  }) {
6409
- const { userExperience: chartsUserExperience } = useChartsUserExperience();
6433
+ const nivoConfiguration = useNivoConfiguration();
6410
6434
  const [selectedDimension, setSelectedDimension] = import_react5.useState(null);
6411
6435
  const dimensions = data ? Object.keys(data.units) : [];
6436
+ const chartColors = componentsProps?.primaryChart?.options?.colors ?? nivoConfiguration.colors;
6412
6437
  const entities = data && data.values.length > 0 ? Object.keys(data.values[0].entities) : [];
6413
- const entityColors = entities.reduce((t, entity, i) => ({
6438
+ const getEntityColor = import_colors2.useOrdinalColorScale(chartColors, "id");
6439
+ const entityColors = entities.reduce((t, entity) => ({
6414
6440
  ...t,
6415
- [entity]: chartsUserExperience.colors[i % chartsUserExperience.colors.length]
6441
+ [entity]: getEntityColor({ id: entity, path: "" })
6416
6442
  }), {});
6417
- const axisLegends = data ? dimensions.reduce((t, d) => ({
6418
- ...t,
6419
- [d]: `${d} in ${data.units[d]}`
6420
- }), {}) : {};
6443
+ const axisLegends = data ? dimensions.reduce((t, d) => {
6444
+ const unit = data.units[d];
6445
+ return {
6446
+ ...t,
6447
+ [d]: unit !== null ? `${d} in ${unit}` : d
6448
+ };
6449
+ }, {}) : {};
6421
6450
  import_react5.useEffect(() => {
6422
6451
  if (!dimensions || dimensions.length < 1) {
6423
6452
  if (selectedDimension) {
@@ -6495,15 +6524,17 @@ function TimeSeriesExplorerWidget({
6495
6524
  },
6496
6525
  ...componentsProps?.entitiesGrid,
6497
6526
  children: entities.map((entity) => {
6527
+ const entityChartData = reduceTimeSeriesEntities(data, (t, [e, value]) => e === entity ? { [entity]: value } : t, {
6528
+ [entity]: {
6529
+ [selectedDimension]: 0
6530
+ }
6531
+ });
6532
+ const hasNonZeroValue = entityChartData.values.some((v) => [v.entities[entity][selectedDimension]].flat(2)[0] !== 0);
6498
6533
  const entityChartProps = {
6499
6534
  type: "timeSeriesStackedAreas" /* TimeSeriesStackedAreas */,
6500
6535
  ...componentsProps?.chart,
6501
6536
  ...componentsProps?.entityChart,
6502
- data: reduceTimeSeriesEntities(data, (t, [e, value]) => e === entity ? { [entity]: value } : t, {
6503
- [entity]: {
6504
- [selectedDimension]: 0
6505
- }
6506
- }),
6537
+ data: entityChartData,
6507
6538
  options: {
6508
6539
  dimension: selectedDimension,
6509
6540
  axisBottomLegend: "Time",
@@ -6516,6 +6547,7 @@ function TimeSeriesExplorerWidget({
6516
6547
  };
6517
6548
  return /* @__PURE__ */ jsx_runtime11.jsx(Chart, {
6518
6549
  h: 275,
6550
+ mounted: !(hideZeroOnlyEntities && !hasNonZeroValue),
6519
6551
  ...entityChartProps,
6520
6552
  additionalControls: [
6521
6553
  /* @__PURE__ */ jsx_runtime11.jsx(import_core18.RemoraidButton, {
@@ -327,8 +327,8 @@ interface ChartsUserExperience {
327
327
  colors: string[];
328
328
  }
329
329
  interface NivoConfiguration {
330
+ colors: OrdinalColorScaleConfig;
330
331
  theme?: PartialNivoTheme;
331
- colors?: OrdinalColorScaleConfig;
332
332
  }
333
333
  interface NivoConfigurationDependencies {
334
334
  remoraidTheme: RemoraidTheme;
@@ -349,7 +349,7 @@ interface TimeSeriesData<
349
349
  Dimension extends string
350
350
  > {
351
351
  values: TimeSeriesValue<EntityName, Dimension>[];
352
- units: Record<Dimension, string>;
352
+ units: Record<Dimension, string | null>;
353
353
  }
354
354
  declare enum ChartType {
355
355
  TimeSeriesStackedAreas = "timeSeriesStackedAreas",
@@ -389,7 +389,7 @@ interface TooltipProps4 {
389
389
  payload: Record<string, {
390
390
  value: number | string
391
391
  color?: string
392
- unit?: string
392
+ unit?: string | null
393
393
  }>;
394
394
  label?: string;
395
395
  valueFormat?: (value: number | string) => number | string;
@@ -491,6 +491,7 @@ type PartialChartProps = Omit<Partial<ChartPropsGeneric<ChartType.TimeSeriesStac
491
491
  interface TimeSeriesExplorerWidgetProps {
492
492
  data?: TimeSeriesData<string, string>;
493
493
  isLoadingData?: boolean;
494
+ hideZeroOnlyEntities?: boolean;
494
495
  widgetProps?: Partial<WidgetProps>;
495
496
  componentsProps?: {
496
497
  contentContainer?: Partial<StackProps6>
@@ -501,7 +502,7 @@ interface TimeSeriesExplorerWidgetProps {
501
502
  missingDataAlert?: Partial<AlertMinimalProps>
502
503
  };
503
504
  }
504
- declare function TimeSeriesExplorerWidget({ data, isLoadingData, widgetProps, componentsProps }: TimeSeriesExplorerWidgetProps): ReactNode52;
505
+ declare function TimeSeriesExplorerWidget({ data, isLoadingData, hideZeroOnlyEntities, widgetProps, componentsProps }: TimeSeriesExplorerWidgetProps): ReactNode52;
505
506
  import { ReactNode as ReactNode53 } from "react";
506
507
  declare const defaultVerticalChartsWidgetId = "vertical-charts";
507
508
  interface VerticalChartsWidgetProps {
@@ -522,8 +523,13 @@ declare const reduceTimeSeriesEntities: <
522
523
  EOut extends string,
523
524
  D extends string
524
525
  >({ values, units }: TimeSeriesData<EIn, D>, reducer: (previousValue: Record<EOut, Record<D, number | number[]>>, currentValue: [EIn, Record<D, number | number[]>], currentIndex: number, array: [EIn, Record<D, number | number[]>][]) => Record<EOut, Record<D, number | number[]>>, initial: Record<EOut, Record<D, number | number[]>>) => TimeSeriesData<EOut, D>;
526
+ declare const reduceTimeSeriesDimensions: <
527
+ EntityName extends string,
528
+ DIn extends string,
529
+ DOut extends string
530
+ >({ values }: TimeSeriesData<EntityName, DIn>, reducer: (previousValue: Record<DOut, number | number[]>, currentValue: [DIn, number | number[]], currentIndex: number, array: [DIn, number | number[]][]) => Record<DOut, number | number[]>, initial: Record<DOut, number | number[]>, units: Record<DOut, string | null>) => TimeSeriesData<EntityName, DOut>;
525
531
  declare const emptyTimeSeriesData: TimeSeriesData<string, string>;
526
532
  declare const missingDataAlertProps: (props?: Partial<AlertMinimalProps>) => AlertMinimalProps;
527
533
  declare const downloadJson: (data: any, filename?: string) => void;
528
534
  declare const copyToClipboard: (value: string) => Promise<void>;
529
- export { useNivoConfiguration, useChartsUserExperience, reduceTimeSeriesEntities, missingDataAlertProps, mergeTimeSeries, getChartTypeName, emptyTimeSeriesData, downloadJson, defaultVerticalChartsWidgetId, defaultUserExperienceCookieName2 as defaultUserExperienceCookieName, defaultUserExperience2 as defaultUserExperience, defaultTimeseriesExplorerWidgetId, defaultSingleChartWidgetId, defaultJsonWidgetId, defaultChartsSettingsWidgetId, defaultChartHeights, createNivoConfiguration, copyToClipboard, VerticalChartsWidgetProps, VerticalChartsWidget, TimeSeriesValue, TimeSeriesStackedAreasChartWindow, TimeSeriesExplorerWidgetProps, TimeSeriesExplorerWidget, TimeSeriesData, SingleChartWidgetProps, SingleChartWidget, RemoraidDataVisualizationProviderProps, RemoraidDataVisualizationProvider, NivoConfigurationProviderProps, NivoConfigurationDependencies, NivoConfigurationCallback, NivoConfiguration, JSONWidgetProps, JSONWidget, ChartsUserExperience, ChartsSettingsProps, ChartsSettings, ChartType, ChartPropsGeneric, ChartProps, ChartOptions, ChartData, Chart };
535
+ export { useNivoConfiguration, useChartsUserExperience, reduceTimeSeriesEntities, reduceTimeSeriesDimensions, missingDataAlertProps, mergeTimeSeries, getChartTypeName, emptyTimeSeriesData, downloadJson, defaultVerticalChartsWidgetId, defaultUserExperienceCookieName2 as defaultUserExperienceCookieName, defaultUserExperience2 as defaultUserExperience, defaultTimeseriesExplorerWidgetId, defaultSingleChartWidgetId, defaultJsonWidgetId, defaultChartsSettingsWidgetId, defaultChartHeights, createNivoConfiguration, copyToClipboard, VerticalChartsWidgetProps, VerticalChartsWidget, TimeSeriesValue, TimeSeriesStackedAreasChartWindow, TimeSeriesExplorerWidgetProps, TimeSeriesExplorerWidget, TimeSeriesData, SingleChartWidgetProps, SingleChartWidget, RemoraidDataVisualizationProviderProps, RemoraidDataVisualizationProvider, NivoConfigurationProviderProps, NivoConfigurationDependencies, NivoConfigurationCallback, NivoConfiguration, JSONWidgetProps, JSONWidget, ChartsUserExperience, ChartsSettingsProps, ChartsSettings, ChartType, ChartPropsGeneric, ChartProps, ChartOptions, ChartData, Chart };
@@ -701,7 +701,7 @@ var require_lodash = __commonJS((exports, module) => {
701
701
  }
702
702
  var runInContext = function runInContext(context) {
703
703
  context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
704
- var { Array: Array2, Date: Date2, Error: Error2, Function: Function2, Math: Math2, Object: Object2, RegExp: RegExp2, String, TypeError: TypeError2 } = context;
704
+ var { Array: Array2, Date: Date2, Error: Error2, Function: Function2, Math: Math2, Object: Object2, RegExp: RegExp2, String: String2, TypeError: TypeError2 } = context;
705
705
  var arrayProto = Array2.prototype, funcProto = Function2.prototype, objectProto = Object2.prototype;
706
706
  var coreJsData = context["__core-js_shared__"];
707
707
  var funcToString = funcProto.toString;
@@ -1017,7 +1017,7 @@ var require_lodash = __commonJS((exports, module) => {
1017
1017
  Stack2.prototype.has = stackHas;
1018
1018
  Stack2.prototype.set = stackSet;
1019
1019
  function arrayLikeKeys(value, inherited) {
1020
- var isArr = isArray(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result2 = skipIndexes ? baseTimes(value.length, String) : [], length = result2.length;
1020
+ var isArr = isArray(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result2 = skipIndexes ? baseTimes(value.length, String2) : [], length = result2.length;
1021
1021
  for (var key in value) {
1022
1022
  if ((inherited || hasOwnProperty.call(value, key)) && !(skipIndexes && (key == "length" || isBuff && (key == "offset" || key == "parent") || isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || isIndex(key, length)))) {
1023
1023
  result2.push(key);
@@ -5503,44 +5503,47 @@ function Tooltip({
5503
5503
  /* @__PURE__ */ jsxs(Stack, {
5504
5504
  gap: valuesVerticalGap,
5505
5505
  children: [
5506
- Object.entries(payload).sort((a, b) => Math.abs(Number(b[1].value)) - Math.abs(Number(a[1].value))).slice(0, maxItems ?? undefined).map(([key, { value, color, unit }], i) => /* @__PURE__ */ jsxs(Group, {
5507
- gap: valuesHorizontalGap,
5508
- wrap: "nowrap",
5509
- justify: "space-between",
5510
- children: [
5511
- /* @__PURE__ */ jsxs(Group, {
5512
- gap: "xs",
5513
- wrap: "nowrap",
5514
- align: "center",
5515
- children: [
5516
- color !== undefined && /* @__PURE__ */ jsx(Center, {
5517
- children: /* @__PURE__ */ jsx(IconCircleFilled, {
5518
- ...theme.componentsProps.icons.medium,
5519
- color
5506
+ Object.entries(payload).sort((a, b) => Math.abs(Number(b[1].value)) - Math.abs(Number(a[1].value))).slice(0, maxItems ?? undefined).map(([key, { value, color, unit }], i) => {
5507
+ const formattedValue = String(valueFormat?.(value) ?? value);
5508
+ return /* @__PURE__ */ jsxs(Group, {
5509
+ gap: valuesHorizontalGap,
5510
+ wrap: "nowrap",
5511
+ justify: "space-between",
5512
+ children: [
5513
+ /* @__PURE__ */ jsxs(Group, {
5514
+ gap: "xs",
5515
+ wrap: "nowrap",
5516
+ align: "center",
5517
+ children: [
5518
+ color !== undefined && /* @__PURE__ */ jsx(Center, {
5519
+ children: /* @__PURE__ */ jsx(IconCircleFilled, {
5520
+ ...theme.componentsProps.icons.medium,
5521
+ color
5522
+ })
5523
+ }),
5524
+ /* @__PURE__ */ jsx(Text, {
5525
+ size: "sm",
5526
+ ...componentsProps?.valueText,
5527
+ style: {
5528
+ textWrap: "nowrap",
5529
+ ...componentsProps?.valueText?.style
5530
+ },
5531
+ children: key
5520
5532
  })
5521
- }),
5522
- /* @__PURE__ */ jsx(Text, {
5523
- size: "sm",
5524
- ...componentsProps?.valueText,
5525
- style: {
5526
- textWrap: "nowrap",
5527
- ...componentsProps?.valueText?.style
5528
- },
5529
- children: key
5530
- })
5531
- ]
5532
- }, `entry-key-${i}`),
5533
- /* @__PURE__ */ jsx(Text, {
5534
- size: "sm",
5535
- ...componentsProps?.valueText,
5536
- style: {
5537
- textWrap: "nowrap",
5538
- ...componentsProps?.valueText?.style
5539
- },
5540
- children: `${valueFormat !== undefined ? valueFormat(value) : value} ${unit ?? ""}`
5541
- }, `entry-value-${i}`)
5542
- ]
5543
- }, i)),
5533
+ ]
5534
+ }, `entry-key-${i}`),
5535
+ /* @__PURE__ */ jsx(Text, {
5536
+ size: "sm",
5537
+ ...componentsProps?.valueText,
5538
+ style: {
5539
+ textWrap: "nowrap",
5540
+ ...componentsProps?.valueText?.style
5541
+ },
5542
+ children: unit ? `${formattedValue} ${unit}` : formattedValue
5543
+ }, `entry-value-${i}`)
5544
+ ]
5545
+ }, i);
5546
+ }),
5544
5547
  maxItems !== null && Object.entries(payload).length > maxItems && /* @__PURE__ */ jsxs(Text, {
5545
5548
  size: "sm",
5546
5549
  c: "dimmed",
@@ -5609,10 +5612,7 @@ function ChartsUserExperienceProvider({
5609
5612
  }
5610
5613
 
5611
5614
  // src/data-visualization/components/RemoraidDataVisualizationProvider/NivoConfigurationProvider/index.tsx
5612
- import {
5613
- useHydratedMantineColorScheme,
5614
- useRemoraidTheme as useRemoraidTheme2
5615
- } from "remoraid/core";
5615
+ import { useHydratedMantineColorScheme, useRemoraidTheme as useRemoraidTheme2 } from "remoraid/core";
5616
5616
  import { jsx as jsx3 } from "react/jsx-runtime";
5617
5617
  var createNivoConfiguration = (customTheme, dependencies) => {
5618
5618
  const userExperience = dependencies?.userExperience ?? defaultUserExperience;
@@ -5782,6 +5782,18 @@ var reduceTimeSeriesEntities = ({ values, units }, reducer, initial) => {
5782
5782
  }))
5783
5783
  };
5784
5784
  };
5785
+ var reduceTimeSeriesDimensions = ({ values }, reducer, initial, units) => {
5786
+ return {
5787
+ units,
5788
+ values: values.map(({ date, entities }) => ({
5789
+ date,
5790
+ entities: Object.fromEntries(Object.entries(entities).map(([entity, dimensions]) => [
5791
+ entity,
5792
+ Object.entries(dimensions).reduce(reducer, structuredClone(initial))
5793
+ ]))
5794
+ }))
5795
+ };
5796
+ };
5785
5797
  var emptyTimeSeriesData = {
5786
5798
  values: [],
5787
5799
  units: {}
@@ -5883,6 +5895,7 @@ function RingSummary({
5883
5895
  // src/data-visualization/components/Chart/index.tsx
5884
5896
  var import_lodash2 = __toESM(require_lodash(), 1);
5885
5897
  import { quantileSorted } from "d3-array";
5898
+ import { useOrdinalColorScale } from "@nivo/colors";
5886
5899
  import { jsx as jsx5, jsxs as jsxs3, Fragment as Fragment2 } from "react/jsx-runtime";
5887
5900
  function Chart({
5888
5901
  type,
@@ -5903,11 +5916,13 @@ function Chart({
5903
5916
  let includeEntityChips = true;
5904
5917
  let includeLegend = false;
5905
5918
  let entities = [];
5919
+ let chartColors = [];
5906
5920
  let chart;
5907
5921
  const controls = [];
5908
5922
  if (type === "timeSeriesStackedAreas" /* TimeSeriesStackedAreas */) {
5909
5923
  includeEntityChips = options.includeEntityChips ?? true;
5910
5924
  includeLegend = options?.includeLegend ?? includeLegend;
5925
+ chartColors = componentsProps?.chart?.colors ?? options?.colors ?? nivoConfiguration.colors;
5911
5926
  data.values.sort((a, b) => a.date.getTime() - b.date.getTime());
5912
5927
  const guideValue = data.values.length > 0 ? data.values[data.values.length - 1 - windowOffset] : null;
5913
5928
  const chartData = [];
@@ -5937,7 +5952,6 @@ function Chart({
5937
5952
  } : undefined;
5938
5953
  const unit = data.units[options.dimension];
5939
5954
  chart = /* @__PURE__ */ jsx5(ResponsiveStream, {
5940
- colors: options.colors ?? nivoConfiguration.colors,
5941
5955
  theme: nivoConfiguration.theme,
5942
5956
  data: chartData,
5943
5957
  keys: entities,
@@ -5996,7 +6010,8 @@ function Chart({
5996
6010
  }),
5997
6011
  curve: "linear",
5998
6012
  offsetType: "diverging",
5999
- ...componentsProps?.chart
6013
+ ...componentsProps?.chart,
6014
+ colors: chartColors
6000
6015
  }, entities.join(","));
6001
6016
  const increaseWindowOffsetButton = /* @__PURE__ */ jsx5(RemoraidButton, {
6002
6017
  mounted: window !== null,
@@ -6100,11 +6115,13 @@ function Chart({
6100
6115
  p95Value = quantileSorted(sortedSparklineData, 0.95) ?? 0;
6101
6116
  progress = Math.max(0, Math.min(100, p95Value === p5Value ? 0 : (currentValue - p5Value) / (p95Value - p5Value) * 100));
6102
6117
  }
6118
+ const formattedCurrentValue = String(options.valueFormat?.(currentValue) ?? currentValue);
6119
+ const unit = data.units[options.dimension];
6103
6120
  chart = /* @__PURE__ */ jsx5(RingSummary, {
6104
6121
  label: options.entity,
6105
6122
  color: options.color ?? chartsUserExperience.colors[0],
6106
6123
  progress,
6107
- value: sparklineData.length > 0 ? `${options.valueFormat?.(currentValue) ?? currentValue} ${data.units[options.dimension]}` : "No data",
6124
+ value: sparklineData.length > 0 ? unit ? `${formattedCurrentValue} ${unit}` : formattedCurrentValue : "No data",
6108
6125
  icon: options.icon,
6109
6126
  sparklineData,
6110
6127
  ...componentsProps?.chart
@@ -6115,6 +6132,7 @@ function Chart({
6115
6132
  }
6116
6133
  const includeControls = controls.length > 0;
6117
6134
  const numCols = Number(includeEntityChips) + Number(includeControls);
6135
+ const getEntityColor = useOrdinalColorScale(chartColors, "id");
6118
6136
  return /* @__PURE__ */ jsx5(Transition, {
6119
6137
  mounted,
6120
6138
  children: (transitionStyle) => /* @__PURE__ */ jsxs3(Paper2, {
@@ -6141,13 +6159,13 @@ function Chart({
6141
6159
  onChange: (newValue) => {
6142
6160
  setHiddenEntities(entities.filter((e) => !newValue.includes(e)));
6143
6161
  },
6144
- children: entities.map((entitiy, i) => /* @__PURE__ */ jsx5(Chip, {
6145
- value: entitiy,
6162
+ children: entities.map((entity, i) => /* @__PURE__ */ jsx5(Chip, {
6163
+ value: entity,
6146
6164
  icon: /* @__PURE__ */ jsx5(IconCheck, {
6147
6165
  ...theme.componentsProps.icons.tiny
6148
6166
  }),
6149
- color: chartsUserExperience.colors[i % chartsUserExperience.colors.length],
6150
- children: entitiy
6167
+ color: getEntityColor({ id: entity, path: "" }),
6168
+ children: entity
6151
6169
  }, i))
6152
6170
  })
6153
6171
  }),
@@ -6407,26 +6425,33 @@ import {
6407
6425
  RemoraidButton as RemoraidButton2,
6408
6426
  Widget as Widget3
6409
6427
  } from "remoraid/core";
6428
+ import { useOrdinalColorScale as useOrdinalColorScale2 } from "@nivo/colors";
6410
6429
  import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
6411
6430
  var defaultTimeseriesExplorerWidgetId = "timeseries-explorer";
6412
6431
  function TimeSeriesExplorerWidget({
6413
6432
  data,
6414
6433
  isLoadingData,
6434
+ hideZeroOnlyEntities = true,
6415
6435
  widgetProps,
6416
6436
  componentsProps
6417
6437
  }) {
6418
- const { userExperience: chartsUserExperience } = useChartsUserExperience();
6438
+ const nivoConfiguration = useNivoConfiguration();
6419
6439
  const [selectedDimension, setSelectedDimension] = useState3(null);
6420
6440
  const dimensions = data ? Object.keys(data.units) : [];
6441
+ const chartColors = componentsProps?.primaryChart?.options?.colors ?? nivoConfiguration.colors;
6421
6442
  const entities = data && data.values.length > 0 ? Object.keys(data.values[0].entities) : [];
6422
- const entityColors = entities.reduce((t, entity, i) => ({
6443
+ const getEntityColor = useOrdinalColorScale2(chartColors, "id");
6444
+ const entityColors = entities.reduce((t, entity) => ({
6423
6445
  ...t,
6424
- [entity]: chartsUserExperience.colors[i % chartsUserExperience.colors.length]
6446
+ [entity]: getEntityColor({ id: entity, path: "" })
6425
6447
  }), {});
6426
- const axisLegends = data ? dimensions.reduce((t, d) => ({
6427
- ...t,
6428
- [d]: `${d} in ${data.units[d]}`
6429
- }), {}) : {};
6448
+ const axisLegends = data ? dimensions.reduce((t, d) => {
6449
+ const unit = data.units[d];
6450
+ return {
6451
+ ...t,
6452
+ [d]: unit !== null ? `${d} in ${unit}` : d
6453
+ };
6454
+ }, {}) : {};
6430
6455
  useEffect(() => {
6431
6456
  if (!dimensions || dimensions.length < 1) {
6432
6457
  if (selectedDimension) {
@@ -6504,15 +6529,17 @@ function TimeSeriesExplorerWidget({
6504
6529
  },
6505
6530
  ...componentsProps?.entitiesGrid,
6506
6531
  children: entities.map((entity) => {
6532
+ const entityChartData = reduceTimeSeriesEntities(data, (t, [e, value]) => e === entity ? { [entity]: value } : t, {
6533
+ [entity]: {
6534
+ [selectedDimension]: 0
6535
+ }
6536
+ });
6537
+ const hasNonZeroValue = entityChartData.values.some((v) => [v.entities[entity][selectedDimension]].flat(2)[0] !== 0);
6507
6538
  const entityChartProps = {
6508
6539
  type: "timeSeriesStackedAreas" /* TimeSeriesStackedAreas */,
6509
6540
  ...componentsProps?.chart,
6510
6541
  ...componentsProps?.entityChart,
6511
- data: reduceTimeSeriesEntities(data, (t, [e, value]) => e === entity ? { [entity]: value } : t, {
6512
- [entity]: {
6513
- [selectedDimension]: 0
6514
- }
6515
- }),
6542
+ data: entityChartData,
6516
6543
  options: {
6517
6544
  dimension: selectedDimension,
6518
6545
  axisBottomLegend: "Time",
@@ -6525,6 +6552,7 @@ function TimeSeriesExplorerWidget({
6525
6552
  };
6526
6553
  return /* @__PURE__ */ jsx10(Chart, {
6527
6554
  h: 275,
6555
+ mounted: !(hideZeroOnlyEntities && !hasNonZeroValue),
6528
6556
  ...entityChartProps,
6529
6557
  additionalControls: [
6530
6558
  /* @__PURE__ */ jsx10(RemoraidButton2, {
@@ -6557,6 +6585,7 @@ export {
6557
6585
  useNivoConfiguration,
6558
6586
  useChartsUserExperience,
6559
6587
  reduceTimeSeriesEntities,
6588
+ reduceTimeSeriesDimensions,
6560
6589
  missingDataAlertProps,
6561
6590
  mergeTimeSeries,
6562
6591
  getChartTypeName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remoraid",
3
- "version": "3.5.0",
3
+ "version": "3.7.0",
4
4
  "author": "Konrad Goldammer",
5
5
  "repository": {
6
6
  "type": "git",