@flux-ui/statistics 3.0.0-next.75 → 3.0.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.
package/README.md CHANGED
@@ -28,5 +28,4 @@ Built on top of [Apache ECharts](https://echarts.apache.org/), themed to match t
28
28
  - [`@flux-ui/components`](../components)
29
29
  - [`@flux-ui/types`](../types)
30
30
  - [`@flux-ui/internals`](../internals)
31
- - [`@flux-ui/dashboard`](../dashboard)
32
31
  - [`@flux-ui/application`](../application)
@@ -4,6 +4,7 @@ export interface ChartLegendItem {
4
4
  readonly color?: string;
5
5
  readonly icon?: FluxIconName;
6
6
  readonly label: string;
7
+ readonly seriesIndex?: number;
7
8
  readonly value?: string | number;
8
9
  }
9
10
  export interface ChartLegendContext {
package/dist/index.js CHANGED
@@ -31,9 +31,16 @@ function useChartHoverSync(chartInstance, legendContext, options) {
31
31
  const { mode, seriesIndex: forcedSeriesIndex = 0 } = options;
32
32
  let attached = null;
33
33
  let syncing = false;
34
+ const toSeriesIndex = (itemIndex) => {
35
+ return legendContext.items.value[itemIndex]?.seriesIndex ?? itemIndex;
36
+ };
37
+ const toItemIndex = (seriesIndex) => {
38
+ const mapped = legendContext.items.value.findIndex((item) => item.seriesIndex === seriesIndex);
39
+ return mapped !== -1 ? mapped : seriesIndex;
40
+ };
34
41
  const onMouseOver = (params) => {
35
42
  if (syncing) return;
36
- const index = mode === "series" ? params.seriesIndex ?? null : params.dataIndex ?? null;
43
+ const index = mode === "series" ? params.seriesIndex !== void 0 ? toItemIndex(params.seriesIndex) : null : params.dataIndex ?? null;
37
44
  legendContext.hoveredIndex.value = index;
38
45
  };
39
46
  const onMouseOut = () => {
@@ -46,7 +53,7 @@ function useChartHoverSync(chartInstance, legendContext, options) {
46
53
  instance.dispatchAction({ type: "downplay" });
47
54
  if (index !== null) if (mode === "series") instance.dispatchAction({
48
55
  type: "highlight",
49
- seriesIndex: index
56
+ seriesIndex: toSeriesIndex(index)
50
57
  });
51
58
  else instance.dispatchAction({
52
59
  type: "highlight",
@@ -6929,6 +6936,51 @@ function buildBoxPlotTooltip(input) {
6929
6936
  } };
6930
6937
  }
6931
6938
  //#endregion
6939
+ //#region src/util/tooltips/buildCandlestickTooltip.ts
6940
+ function buildCandlestickTooltip(input) {
6941
+ const { t, styles, getSeries } = input;
6942
+ const formatter = (params) => {
6943
+ const param = Array.isArray(params) ? params[0] : params;
6944
+ if (!param) return "";
6945
+ const series = getSeries();
6946
+ const seriesIndex = param.seriesIndex ?? 0;
6947
+ const dataIndex = param.dataIndex ?? 0;
6948
+ const s = series[seriesIndex];
6949
+ const point = s?.data[dataIndex];
6950
+ if (!s || !point) return "";
6951
+ const positive = resolveChartColor(s.positiveColor) ?? "var(--success-500)";
6952
+ const negative = resolveChartColor(s.negativeColor) ?? "var(--danger-500)";
6953
+ const color = point.close >= point.open ? positive : negative;
6954
+ return renderTooltip(t, styles, [s.name ? t(String(s.name)) : "", point.label ? t(String(point.label)) : ""].filter(Boolean).join(" — "), [
6955
+ {
6956
+ name: "Open",
6957
+ value: point.open,
6958
+ color
6959
+ },
6960
+ {
6961
+ name: "Close",
6962
+ value: point.close,
6963
+ color
6964
+ },
6965
+ {
6966
+ name: "Lowest",
6967
+ value: point.low,
6968
+ color
6969
+ },
6970
+ {
6971
+ name: "Highest",
6972
+ value: point.high,
6973
+ color
6974
+ }
6975
+ ]);
6976
+ };
6977
+ return { tooltip: {
6978
+ show: true,
6979
+ trigger: "item",
6980
+ formatter
6981
+ } };
6982
+ }
6983
+ //#endregion
6932
6984
  //#region src/util/tooltips/buildCartesianTooltip.ts
6933
6985
  function buildCartesianTooltip(input) {
6934
6986
  const { t, styles, getSeriesIcons, valueFormatter } = input;
@@ -7057,7 +7109,7 @@ function buildTreemapTooltip(input) {
7057
7109
  if (!param) return "";
7058
7110
  const data = param.data;
7059
7111
  if (!data) return "";
7060
- const color = data.color ?? "var(--primary-600)";
7112
+ const color = data.itemStyle?.color ?? param.color ?? "var(--primary-600)";
7061
7113
  return renderTooltip(t, styles, data.name ? t(String(data.name)) : "", [{
7062
7114
  name: "",
7063
7115
  value: data.value ?? "",
@@ -7250,14 +7302,16 @@ function resolveCandlestickLabels(series, labels) {
7250
7302
  if (labels) return labels;
7251
7303
  for (const s of series) if (s.data.map((p) => p.label ?? "").filter(Boolean).length > 0) return s.data.map((p) => p.label ?? "");
7252
7304
  }
7253
- function candlestickLegendItemBuilder(s) {
7305
+ function candlestickLegendItemBuilder(s, _color, index) {
7254
7306
  return [{
7255
7307
  color: resolveChartColor(s.positiveColor) ?? "var(--success-500)",
7256
7308
  icon: s.icon,
7257
- label: "Up"
7309
+ label: "Up",
7310
+ seriesIndex: index
7258
7311
  }, {
7259
7312
  color: resolveChartColor(s.negativeColor) ?? "var(--danger-500)",
7260
- label: "Down"
7313
+ label: "Down",
7314
+ seriesIndex: index
7261
7315
  }];
7262
7316
  }
7263
7317
  function buildCandlestickChartOptions(input) {
@@ -7274,10 +7328,10 @@ function buildCandlestickChartOptions(input) {
7274
7328
  type: "category",
7275
7329
  data: xLabels
7276
7330
  } } : void 0;
7277
- const tooltipOptions = tooltip ? buildCartesianTooltip({
7331
+ const tooltipOptions = tooltip ? buildCandlestickTooltip({
7278
7332
  t,
7279
7333
  styles,
7280
- getSeriesIcons: () => series.map((s) => s.icon)
7334
+ getSeries: () => series
7281
7335
  }) : { tooltip: { show: false } };
7282
7336
  const echartsSeries = series.map((s) => toCandlestickSeries({
7283
7337
  ...s,
@@ -11305,6 +11359,9 @@ function useECharts(target, options) {
11305
11359
  chartInstance.value = markRaw(init(target.value));
11306
11360
  chartInstance.value.setOption(toValue(options));
11307
11361
  });
11362
+ watch(() => toValue(options), (value) => {
11363
+ chartInstance.value?.setOption(value, { notMerge: true });
11364
+ });
11308
11365
  onBeforeUnmount(() => {
11309
11366
  if (pendingResize !== null) {
11310
11367
  cancelAnimationFrame(pendingResize);
@@ -11352,7 +11409,9 @@ var FluxStatisticsChart_default = /* @__PURE__ */ defineComponent({
11352
11409
  setup(__props, { expose: __expose }) {
11353
11410
  const chart = useTemplateRef("chart");
11354
11411
  const defaults = buildBaseOptions();
11412
+ const themeVersion = useCssVarVersion();
11355
11413
  const { chartInstance } = useECharts(chart, computed(() => {
11414
+ themeVersion.value;
11356
11415
  const merged = merge({}, defaults, __props.options);
11357
11416
  if (__props.options && __props.options.color !== void 0) merged.color = __props.options.color;
11358
11417
  if (__props.options && __props.options.series !== void 0) merged.series = __props.options.series;
@@ -11802,9 +11861,12 @@ var FluxStatisticsComparison_default = /* @__PURE__ */ defineComponent({
11802
11861
  setup(__props) {
11803
11862
  const formattedCurrent = computed(() => __props.format ? __props.format(__props.current) : __props.current);
11804
11863
  const formattedPrevious = computed(() => __props.format ? __props.format(__props.previous) : __props.previous);
11864
+ const isDeltaIndeterminate = computed(() => __props.previous === 0 && __props.current !== 0);
11805
11865
  const deltaValue = computed(() => {
11806
11866
  if (__props.previous === 0) return 0;
11807
- return (__props.current - __props.previous) / Math.abs(__props.previous) * 100;
11867
+ const delta = (__props.current - __props.previous) / Math.abs(__props.previous) * 100;
11868
+ if (Math.round(delta * 10) / 10 === 0) return 0;
11869
+ return delta;
11808
11870
  });
11809
11871
  const deltaColor = computed(() => {
11810
11872
  if (deltaValue.value > 0) return "success";
@@ -11816,6 +11878,7 @@ var FluxStatisticsComparison_default = /* @__PURE__ */ defineComponent({
11816
11878
  if (deltaValue.value < 0) return "arrow-trend-down";
11817
11879
  });
11818
11880
  const formattedDelta = computed(() => {
11881
+ if (isDeltaIndeterminate.value) return "—";
11819
11882
  return `${deltaValue.value > 0 ? "+" : ""}${deltaValue.value.toFixed(1)}%`;
11820
11883
  });
11821
11884
  return (_ctx, _cache) => {
@@ -12223,7 +12286,7 @@ var FluxStatisticsLegend_default = /* @__PURE__ */ defineComponent({
12223
12286
  return (_ctx, _cache) => {
12224
12287
  return openBlock(), createElementBlock("div", { class: normalizeClass(containerClass.value) }, [hasSlot.value ? renderSlot(_ctx.$slots, "default", { key: 0 }) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(autoItems.value, (item, index) => {
12225
12288
  return openBlock(), createBlock(FluxStatisticsLegendItem_default, {
12226
- key: item.label,
12289
+ key: `${index}-${item.label}`,
12227
12290
  color: item.color,
12228
12291
  icon: item.icon,
12229
12292
  "is-hovered": unref(legendContext)?.hoveredIndex.value === index,