@diagrammo/dgmo 0.8.8 → 0.8.10

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/src/echarts.ts CHANGED
@@ -113,20 +113,25 @@ import { parseDataRowValues } from './chart';
113
113
  // Shared Constants
114
114
  // ============================================================
115
115
 
116
- const EMPHASIS_SELF = { focus: 'self' as const, blurScope: 'global' as const };
117
- const EMPHASIS_LINE = {
118
- ...EMPHASIS_SELF,
119
- scale: 2.5,
120
- itemStyle: {
121
- borderWidth: 2,
122
- borderColor: '#fff',
123
- shadowBlur: 8,
124
- shadowColor: 'rgba(0,0,0,0.4)',
125
- },
116
+ const EMPHASIS_SELF = {
117
+ focus: 'self' as const,
118
+ blurScope: 'global' as const,
119
+ itemStyle: { opacity: 1 },
126
120
  };
127
- const CHART_BASE: Pick<EChartsOption, 'backgroundColor' | 'animation'> = {
121
+ const EMPHASIS_SERIES = {
122
+ focus: 'series' as const,
123
+ blurScope: 'global' as const,
124
+ itemStyle: { opacity: 1 },
125
+ };
126
+ const BLUR_DIM = { itemStyle: { opacity: 0.15 }, lineStyle: { opacity: 0.15 } };
127
+ const EMPHASIS_LINE = { ...EMPHASIS_SELF };
128
+ const CHART_BASE: Pick<
129
+ EChartsOption,
130
+ 'backgroundColor' | 'animation' | 'tooltip'
131
+ > = {
128
132
  backgroundColor: 'transparent',
129
133
  animation: false,
134
+ tooltip: { show: false },
130
135
  };
131
136
  const CHART_BORDER_WIDTH = 2;
132
137
 
@@ -698,11 +703,6 @@ function buildChartCommons(
698
703
  },
699
704
  }
700
705
  : undefined;
701
- const tooltipTheme = {
702
- backgroundColor: palette.surface,
703
- borderColor: palette.border,
704
- textStyle: { color: palette.text },
705
- };
706
706
  return {
707
707
  textColor,
708
708
  axisLineColor,
@@ -710,7 +710,6 @@ function buildChartCommons(
710
710
  gridOpacity,
711
711
  colors,
712
712
  titleConfig,
713
- tooltipTheme,
714
713
  };
715
714
  }
716
715
 
@@ -729,37 +728,18 @@ export function buildExtendedChartOption(
729
728
  return {};
730
729
  }
731
730
 
732
- const {
733
- textColor,
734
- axisLineColor,
735
- gridOpacity,
736
- colors,
737
- titleConfig,
738
- tooltipTheme,
739
- } = buildChartCommons(parsed, palette, isDark);
731
+ const { textColor, axisLineColor, gridOpacity, colors, titleConfig } =
732
+ buildChartCommons(parsed, palette, isDark);
740
733
 
741
734
  // Sankey chart has different structure
742
735
  if (parsed.type === 'sankey') {
743
- return buildSankeyOption(
744
- parsed,
745
- textColor,
746
- colors,
747
- titleConfig,
748
- tooltipTheme
749
- );
736
+ return buildSankeyOption(parsed, textColor, colors, titleConfig);
750
737
  }
751
738
 
752
739
  // Chord diagram
753
740
  if (parsed.type === 'chord') {
754
741
  const bg = isDark ? palette.surface : palette.bg;
755
- return buildChordOption(
756
- parsed,
757
- textColor,
758
- colors,
759
- bg,
760
- titleConfig,
761
- tooltipTheme
762
- );
742
+ return buildChordOption(parsed, textColor, colors, bg, titleConfig);
763
743
  }
764
744
 
765
745
  // Function plot
@@ -771,8 +751,7 @@ export function buildExtendedChartOption(
771
751
  axisLineColor,
772
752
  gridOpacity,
773
753
  colors,
774
- titleConfig,
775
- tooltipTheme
754
+ titleConfig
776
755
  );
777
756
  }
778
757
 
@@ -787,22 +766,14 @@ export function buildExtendedChartOption(
787
766
  gridOpacity,
788
767
  colors,
789
768
  bg,
790
- titleConfig,
791
- tooltipTheme
769
+ titleConfig
792
770
  );
793
771
  }
794
772
 
795
773
  // Funnel chart
796
774
  if (parsed.type === 'funnel') {
797
775
  const bg = isDark ? palette.surface : palette.bg;
798
- return buildFunnelOption(
799
- parsed,
800
- textColor,
801
- colors,
802
- bg,
803
- titleConfig,
804
- tooltipTheme
805
- );
776
+ return buildFunnelOption(parsed, textColor, colors, bg, titleConfig);
806
777
  }
807
778
 
808
779
  // Heatmap
@@ -812,8 +783,7 @@ export function buildExtendedChartOption(
812
783
  isDark,
813
784
  textColor,
814
785
  axisLineColor,
815
- titleConfig,
816
- tooltipTheme
786
+ titleConfig
817
787
  );
818
788
  }
819
789
 
@@ -824,8 +794,7 @@ function buildSankeyOption(
824
794
  parsed: ParsedExtendedChart,
825
795
  textColor: string,
826
796
  colors: string[],
827
- titleConfig: EChartsOption['title'],
828
- tooltipTheme: Record<string, unknown>
797
+ titleConfig: EChartsOption['title']
829
798
  ): EChartsOption {
830
799
  // Extract unique nodes from links
831
800
  const nodeSet = new Set<string>();
@@ -848,17 +817,15 @@ function buildSankeyOption(
848
817
  title: titleConfig,
849
818
  xAxis: { show: false },
850
819
  yAxis: { show: false },
851
- tooltip: {
852
- show: false,
853
- ...tooltipTheme,
854
- },
855
820
  series: [
856
821
  {
857
822
  type: 'sankey',
858
823
  emphasis: {
859
824
  focus: 'adjacency',
860
825
  blurScope: 'global' as const,
826
+ itemStyle: { opacity: 1 },
861
827
  },
828
+ blur: BLUR_DIM,
862
829
  nodeAlign: 'left',
863
830
  nodeGap: 12,
864
831
  nodeWidth: 20,
@@ -890,8 +857,7 @@ function buildChordOption(
890
857
  textColor: string,
891
858
  colors: string[],
892
859
  bg: string,
893
- titleConfig: EChartsOption['title'],
894
- tooltipTheme: Record<string, unknown>
860
+ titleConfig: EChartsOption['title']
895
861
  ): EChartsOption {
896
862
  // Extract unique nodes from links
897
863
  const nodeSet = new Set<string>();
@@ -936,19 +902,6 @@ function buildChordOption(
936
902
  return {
937
903
  ...CHART_BASE,
938
904
  title: titleConfig,
939
- tooltip: {
940
- trigger: 'item',
941
- ...tooltipTheme,
942
- formatter: (params: unknown) => {
943
- const p = params as {
944
- data?: { source: string; target: string; value: number };
945
- };
946
- if (p.data && p.data.source && p.data.target) {
947
- return `${p.data.source} → ${p.data.target}: ${p.data.value}`;
948
- }
949
- return '';
950
- },
951
- },
952
905
  xAxis: { show: false },
953
906
  yAxis: { show: false },
954
907
  series: [
@@ -1013,11 +966,13 @@ function buildChordOption(
1013
966
  },
1014
967
  emphasis: {
1015
968
  focus: 'adjacency',
969
+ itemStyle: { opacity: 1 },
1016
970
  lineStyle: {
1017
971
  width: 5,
1018
972
  opacity: 1,
1019
973
  },
1020
974
  },
975
+ blur: BLUR_DIM,
1021
976
  },
1022
977
  ],
1023
978
  };
@@ -1062,8 +1017,7 @@ function buildFunctionOption(
1062
1017
  axisLineColor: string,
1063
1018
  gridOpacity: number,
1064
1019
  colors: string[],
1065
- titleConfig: EChartsOption['title'],
1066
- tooltipTheme: Record<string, unknown>
1020
+ titleConfig: EChartsOption['title']
1067
1021
  ): EChartsOption {
1068
1022
  const xRange = parsed.xRange ?? { min: -10, max: 10 };
1069
1023
  const samples = 200;
@@ -1103,19 +1057,13 @@ function buildFunctionOption(
1103
1057
  },
1104
1058
  }),
1105
1059
  emphasis: EMPHASIS_SELF,
1060
+ blur: BLUR_DIM,
1106
1061
  };
1107
1062
  });
1108
1063
 
1109
1064
  return {
1110
1065
  ...CHART_BASE,
1111
1066
  title: titleConfig,
1112
- tooltip: {
1113
- trigger: 'axis',
1114
- ...tooltipTheme,
1115
- axisPointer: {
1116
- type: 'cross',
1117
- },
1118
- },
1119
1067
  legend: {
1120
1068
  data: (parsed.functions ?? []).map((fn) => fn.name),
1121
1069
  bottom: 10,
@@ -1499,8 +1447,7 @@ function buildScatterOption(
1499
1447
  gridOpacity: number,
1500
1448
  colors: string[],
1501
1449
  bg: string,
1502
- titleConfig: EChartsOption['title'],
1503
- tooltipTheme: Record<string, unknown>
1450
+ titleConfig: EChartsOption['title']
1504
1451
  ): EChartsOption {
1505
1452
  const points = parsed.scatterPoints ?? [];
1506
1453
  const defaultSize = 15;
@@ -1522,11 +1469,9 @@ function buildScatterOption(
1522
1469
 
1523
1470
  const emphasisConfig = {
1524
1471
  focus: 'self' as const,
1525
- itemStyle: {
1526
- shadowBlur: 10,
1527
- shadowColor: 'rgba(0, 0, 0, 0.3)',
1528
- },
1472
+ itemStyle: { opacity: 1 },
1529
1473
  };
1474
+ const blurConfig = BLUR_DIM;
1530
1475
 
1531
1476
  // Build series based on whether categories are present
1532
1477
  let series;
@@ -1567,6 +1512,7 @@ function buildScatterOption(
1567
1512
  },
1568
1513
  label: labelConfig,
1569
1514
  emphasis: emphasisConfig,
1515
+ blur: blurConfig,
1570
1516
  };
1571
1517
  });
1572
1518
  } else {
@@ -1593,30 +1539,11 @@ function buildScatterOption(
1593
1539
  data,
1594
1540
  label: labelConfig,
1595
1541
  emphasis: emphasisConfig,
1542
+ blur: blurConfig,
1596
1543
  },
1597
1544
  ];
1598
1545
  }
1599
1546
 
1600
- // Tooltip adapts to available data
1601
- const tooltip = {
1602
- trigger: 'item' as const,
1603
- ...tooltipTheme,
1604
- formatter: (params: unknown) => {
1605
- const p = params as {
1606
- seriesName: string;
1607
- name: string;
1608
- value: number[];
1609
- };
1610
- const xLabel = parsed.xlabel || 'x';
1611
- const yLabel = parsed.ylabel || 'y';
1612
- let html = `<strong>${p.name}</strong>`;
1613
- if (hasCategories) html += `<br/>${p.seriesName}`;
1614
- html += `<br/>${xLabel}: ${p.value[0]}<br/>${yLabel}: ${p.value[1]}`;
1615
- if (hasSize) html += `<br/>${parsed.sizelabel || 'size'}: ${p.value[2]}`;
1616
- return html;
1617
- },
1618
- };
1619
-
1620
1547
  // Auto-fit axes to data range with ~10% padding
1621
1548
  const xValues = points.map((p) => p.x);
1622
1549
  const yValues = points.map((p) => p.y);
@@ -1716,7 +1643,6 @@ function buildScatterOption(
1716
1643
  ...CHART_BASE,
1717
1644
  title: titleConfig,
1718
1645
  ...(legendConfig && { legend: legendConfig }),
1719
- tooltip,
1720
1646
  grid: {
1721
1647
  left: `${gridLeft}%`,
1722
1648
  right: `${gridRight}%`,
@@ -1788,8 +1714,7 @@ function buildHeatmapOption(
1788
1714
  isDark: boolean,
1789
1715
  textColor: string,
1790
1716
  axisLineColor: string,
1791
- titleConfig: EChartsOption['title'],
1792
- tooltipTheme: Record<string, unknown>
1717
+ titleConfig: EChartsOption['title']
1793
1718
  ): EChartsOption {
1794
1719
  const bg = isDark ? palette.surface : palette.bg;
1795
1720
  const heatmapRows = parsed.heatmapRows ?? [];
@@ -1812,16 +1737,6 @@ function buildHeatmapOption(
1812
1737
  return {
1813
1738
  ...CHART_BASE,
1814
1739
  title: titleConfig,
1815
- tooltip: {
1816
- trigger: 'item',
1817
- ...tooltipTheme,
1818
- formatter: (params: unknown) => {
1819
- const p = params as { data: [number, number, number] };
1820
- const colName = columns[p.data[0]] ?? p.data[0];
1821
- const rowName = rowLabels[p.data[1]] ?? p.data[1];
1822
- return `${rowName} / ${colName}: <strong>${p.data[2]}</strong>`;
1823
- },
1824
- },
1825
1740
  grid: {
1826
1741
  left: '3%',
1827
1742
  right: '10%',
@@ -1892,11 +1807,8 @@ function buildHeatmapOption(
1892
1807
  },
1893
1808
  emphasis: {
1894
1809
  ...EMPHASIS_SELF,
1895
- itemStyle: {
1896
- shadowBlur: 10,
1897
- shadowColor: 'rgba(0, 0, 0, 0.5)',
1898
- },
1899
1810
  },
1811
+ blur: BLUR_DIM,
1900
1812
  },
1901
1813
  ],
1902
1814
  };
@@ -1910,12 +1822,10 @@ function buildFunnelOption(
1910
1822
  textColor: string,
1911
1823
  colors: string[],
1912
1824
  bg: string,
1913
- titleConfig: EChartsOption['title'],
1914
- tooltipTheme: Record<string, unknown>
1825
+ titleConfig: EChartsOption['title']
1915
1826
  ): EChartsOption {
1916
1827
  // Sort data descending by value for funnel ordering
1917
1828
  const sorted = [...parsed.data].sort((a, b) => b.value - a.value);
1918
- const topValue = sorted.length > 0 ? sorted[0].value : 1;
1919
1829
 
1920
1830
  const data = sorted.map((d) => {
1921
1831
  const stroke = d.color ?? colors[parsed.data.indexOf(d) % colors.length];
@@ -1955,25 +1865,6 @@ function buildFunnelOption(
1955
1865
  title: titleConfig,
1956
1866
  xAxis: { show: false },
1957
1867
  yAxis: { show: false },
1958
- tooltip: {
1959
- trigger: 'item',
1960
- ...tooltipTheme,
1961
- formatter: (params: unknown) => {
1962
- const p = params as { name: string; value: number; dataIndex: number };
1963
- const val = p.value;
1964
- const prev = prevValueMap.get(p.name) ?? val;
1965
- const isFirst = p.dataIndex === 0;
1966
- if (isFirst) return '';
1967
- const parts: string[] = [];
1968
- const stepDrop = ((1 - val / prev) * 100).toFixed(1);
1969
- parts.push(`Step drop-off: ${stepDrop}%`);
1970
- if (topValue > 0) {
1971
- const totalDrop = ((1 - val / topValue) * 100).toFixed(1);
1972
- parts.push(`Overall drop-off: ${totalDrop}%`);
1973
- }
1974
- return parts.join('<br/>');
1975
- },
1976
- },
1977
1868
  series: [
1978
1869
  {
1979
1870
  type: 'funnel',
@@ -1992,10 +1883,8 @@ function buildFunnelOption(
1992
1883
  },
1993
1884
  emphasis: {
1994
1885
  ...EMPHASIS_SELF,
1995
- label: {
1996
- fontSize: 15,
1997
- },
1998
1886
  },
1887
+ blur: BLUR_DIM,
1999
1888
  data,
2000
1889
  },
2001
1890
  {
@@ -2144,7 +2033,6 @@ export function buildSimpleChartOption(
2144
2033
  gridOpacity,
2145
2034
  colors,
2146
2035
  titleConfig,
2147
- tooltipTheme,
2148
2036
  } = buildChartCommons(parsed, palette, isDark);
2149
2037
  const bg = isDark ? palette.surface : palette.bg;
2150
2038
 
@@ -2159,7 +2047,6 @@ export function buildSimpleChartOption(
2159
2047
  colors,
2160
2048
  bg,
2161
2049
  titleConfig,
2162
- tooltipTheme,
2163
2050
  chartWidth
2164
2051
  );
2165
2052
  case 'bar-stacked':
@@ -2172,7 +2059,6 @@ export function buildSimpleChartOption(
2172
2059
  colors,
2173
2060
  bg,
2174
2061
  titleConfig,
2175
- tooltipTheme,
2176
2062
  chartWidth
2177
2063
  );
2178
2064
  case 'line':
@@ -2186,7 +2072,6 @@ export function buildSimpleChartOption(
2186
2072
  gridOpacity,
2187
2073
  colors,
2188
2074
  titleConfig,
2189
- tooltipTheme,
2190
2075
  chartWidth
2191
2076
  )
2192
2077
  : buildLineOption(
@@ -2197,7 +2082,6 @@ export function buildSimpleChartOption(
2197
2082
  splitLineColor,
2198
2083
  gridOpacity,
2199
2084
  titleConfig,
2200
- tooltipTheme,
2201
2085
  chartWidth
2202
2086
  );
2203
2087
  case 'area':
@@ -2209,7 +2093,6 @@ export function buildSimpleChartOption(
2209
2093
  splitLineColor,
2210
2094
  gridOpacity,
2211
2095
  titleConfig,
2212
- tooltipTheme,
2213
2096
  chartWidth
2214
2097
  );
2215
2098
  case 'pie':
@@ -2219,7 +2102,6 @@ export function buildSimpleChartOption(
2219
2102
  getSegmentColors(palette, parsed.data.length),
2220
2103
  bg,
2221
2104
  titleConfig,
2222
- tooltipTheme,
2223
2105
  false
2224
2106
  );
2225
2107
  case 'doughnut':
@@ -2229,7 +2111,6 @@ export function buildSimpleChartOption(
2229
2111
  getSegmentColors(palette, parsed.data.length),
2230
2112
  bg,
2231
2113
  titleConfig,
2232
- tooltipTheme,
2233
2114
  true
2234
2115
  );
2235
2116
  case 'radar':
@@ -2239,8 +2120,7 @@ export function buildSimpleChartOption(
2239
2120
  isDark,
2240
2121
  textColor,
2241
2122
  gridOpacity,
2242
- titleConfig,
2243
- tooltipTheme
2123
+ titleConfig
2244
2124
  );
2245
2125
  case 'polar-area':
2246
2126
  return buildPolarAreaOption(
@@ -2248,8 +2128,7 @@ export function buildSimpleChartOption(
2248
2128
  textColor,
2249
2129
  getSegmentColors(palette, parsed.data.length),
2250
2130
  bg,
2251
- titleConfig,
2252
- tooltipTheme
2131
+ titleConfig
2253
2132
  );
2254
2133
  }
2255
2134
  }
@@ -2262,9 +2141,11 @@ function makeChartGrid(options: {
2262
2141
  yLabel?: string;
2263
2142
  hasTitle: boolean;
2264
2143
  hasLegend?: boolean;
2144
+ isHorizontal?: boolean;
2265
2145
  }): Record<string, unknown> {
2146
+ const left = options.yLabel ? '12%' : '3%';
2266
2147
  return {
2267
- left: options.yLabel ? '12%' : '3%',
2148
+ left,
2268
2149
  right: '4%',
2269
2150
  bottom: options.hasLegend ? '15%' : options.xLabel ? '10%' : '3%',
2270
2151
  top: options.hasTitle ? '15%' : '5%',
@@ -2272,6 +2153,23 @@ function makeChartGrid(options: {
2272
2153
  };
2273
2154
  }
2274
2155
 
2156
+ /** Wrap a label string at word boundaries to fit within `maxChars` per line. */
2157
+ function wrapLabel(text: string, maxChars: number): string {
2158
+ const words = text.split(' ');
2159
+ const lines: string[] = [];
2160
+ let current = '';
2161
+ for (const word of words) {
2162
+ if (current && current.length + 1 + word.length > maxChars) {
2163
+ lines.push(current);
2164
+ current = word;
2165
+ } else {
2166
+ current = current ? current + ' ' + word : word;
2167
+ }
2168
+ }
2169
+ if (current) lines.push(current);
2170
+ return lines.join('\n');
2171
+ }
2172
+
2275
2173
  // ── Bar ──────────────────────────────────────────────────────
2276
2174
 
2277
2175
  function buildBarOption(
@@ -2283,7 +2181,6 @@ function buildBarOption(
2283
2181
  colors: string[],
2284
2182
  bg: string,
2285
2183
  titleConfig: EChartsOption['title'],
2286
- tooltipTheme: Record<string, unknown>,
2287
2184
  chartWidth?: number
2288
2185
  ): EChartsOption {
2289
2186
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
@@ -2301,12 +2198,16 @@ function buildBarOption(
2301
2198
  };
2302
2199
  });
2303
2200
 
2304
- // When category labels are on the y-axis (horizontal bars), they can be wide —
2305
- // compute a nameGap that clears the longest label so the ylabel doesn't overlap.
2201
+ // For horizontal bars, wrap long category labels at word boundaries so they
2202
+ // don't consume too much horizontal space on the y-axis.
2203
+ const catLabels = isHorizontal ? labels.map((l) => wrapLabel(l, 12)) : labels;
2204
+
2205
+ // Compute the max visible line width after wrapping for nameGap calculation.
2206
+ const maxVisibleLen = Math.max(
2207
+ ...catLabels.map((l) => Math.max(...l.split('\n').map((seg) => seg.length)))
2208
+ );
2306
2209
  const hCatGap =
2307
- isHorizontal && yLabel
2308
- ? Math.max(40, Math.max(...labels.map((l) => l.length)) * 8 + 16)
2309
- : undefined;
2210
+ isHorizontal && yLabel ? Math.max(40, maxVisibleLen * 8 + 16) : undefined;
2310
2211
  const categoryAxis = makeGridAxis(
2311
2212
  'category',
2312
2213
  textColor,
@@ -2314,17 +2215,22 @@ function buildBarOption(
2314
2215
  splitLineColor,
2315
2216
  gridOpacity,
2316
2217
  isHorizontal ? yLabel : xLabel,
2317
- labels,
2218
+ catLabels,
2318
2219
  hCatGap,
2319
2220
  !isHorizontal ? chartWidth : undefined
2320
2221
  );
2222
+ // For horizontal bars, the xlabel sits on the value axis (bottom).
2223
+ // Use a moderate nameGap so it doesn't drift.
2224
+ const hValueGap = isHorizontal && xLabel ? 40 : undefined;
2321
2225
  const valueAxis = makeGridAxis(
2322
2226
  'value',
2323
2227
  textColor,
2324
2228
  axisLineColor,
2325
2229
  splitLineColor,
2326
2230
  gridOpacity,
2327
- isHorizontal ? xLabel : yLabel
2231
+ isHorizontal ? xLabel : yLabel,
2232
+ undefined,
2233
+ hValueGap
2328
2234
  );
2329
2235
 
2330
2236
  // xAxis is always the bottom axis, yAxis is always the left axis in ECharts
@@ -2332,14 +2238,20 @@ function buildBarOption(
2332
2238
  return {
2333
2239
  ...CHART_BASE,
2334
2240
  title: titleConfig,
2335
- grid: makeChartGrid({ xLabel, yLabel, hasTitle: !!parsed.title }),
2241
+ grid: makeChartGrid({
2242
+ xLabel,
2243
+ yLabel,
2244
+ hasTitle: !!parsed.title,
2245
+ isHorizontal,
2246
+ }),
2336
2247
  xAxis: isHorizontal ? valueAxis : categoryAxis,
2337
- yAxis: isHorizontal ? categoryAxis : valueAxis,
2248
+ yAxis: isHorizontal ? { ...categoryAxis, inverse: true } : valueAxis,
2338
2249
  series: [
2339
2250
  {
2340
2251
  type: 'bar',
2341
2252
  data,
2342
2253
  emphasis: EMPHASIS_SELF,
2254
+ blur: BLUR_DIM,
2343
2255
  },
2344
2256
  ],
2345
2257
  };
@@ -2369,7 +2281,7 @@ function buildMarkArea(
2369
2281
  if (eras.length === 0) return undefined;
2370
2282
  return {
2371
2283
  silent: false,
2372
- tooltip: { show: true },
2284
+ tooltip: { show: false },
2373
2285
  data: eras.map((era) => {
2374
2286
  const startIdx = labels.indexOf(era.start);
2375
2287
  const endIdx = labels.indexOf(era.end);
@@ -2404,7 +2316,6 @@ function buildLineOption(
2404
2316
  splitLineColor: string,
2405
2317
  gridOpacity: number,
2406
2318
  titleConfig: EChartsOption['title'],
2407
- tooltipTheme: Record<string, unknown>,
2408
2319
  chartWidth?: number
2409
2320
  ): EChartsOption {
2410
2321
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
@@ -2419,11 +2330,6 @@ function buildLineOption(
2419
2330
  return {
2420
2331
  ...CHART_BASE,
2421
2332
  title: titleConfig,
2422
- tooltip: {
2423
- trigger: 'axis',
2424
- ...tooltipTheme,
2425
- axisPointer: { type: 'line' },
2426
- },
2427
2333
  grid: makeChartGrid({ xLabel, yLabel, hasTitle: !!parsed.title }),
2428
2334
  xAxis: makeGridAxis(
2429
2335
  'category',
@@ -2454,6 +2360,7 @@ function buildLineOption(
2454
2360
  lineStyle: { color: lineColor, width: 3 },
2455
2361
  itemStyle: { color: lineColor },
2456
2362
  emphasis: EMPHASIS_LINE,
2363
+ blur: BLUR_DIM,
2457
2364
  ...(markArea && { markArea }),
2458
2365
  },
2459
2366
  ],
@@ -2471,7 +2378,6 @@ function buildMultiLineOption(
2471
2378
  gridOpacity: number,
2472
2379
  colors: string[],
2473
2380
  titleConfig: EChartsOption['title'],
2474
- tooltipTheme: Record<string, unknown>,
2475
2381
  chartWidth?: number
2476
2382
  ): EChartsOption {
2477
2383
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
@@ -2495,6 +2401,7 @@ function buildMultiLineOption(
2495
2401
  lineStyle: { color, width: 3 },
2496
2402
  itemStyle: { color },
2497
2403
  emphasis: EMPHASIS_LINE,
2404
+ blur: BLUR_DIM,
2498
2405
  ...(idx === 0 && markArea && { markArea }),
2499
2406
  };
2500
2407
  });
@@ -2502,11 +2409,6 @@ function buildMultiLineOption(
2502
2409
  return {
2503
2410
  ...CHART_BASE,
2504
2411
  title: titleConfig,
2505
- tooltip: {
2506
- trigger: 'axis',
2507
- ...tooltipTheme,
2508
- axisPointer: { type: 'line' },
2509
- },
2510
2412
  legend: {
2511
2413
  data: seriesNames,
2512
2414
  bottom: 10,
@@ -2552,7 +2454,6 @@ function buildAreaOption(
2552
2454
  splitLineColor: string,
2553
2455
  gridOpacity: number,
2554
2456
  titleConfig: EChartsOption['title'],
2555
- tooltipTheme: Record<string, unknown>,
2556
2457
  chartWidth?: number
2557
2458
  ): EChartsOption {
2558
2459
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
@@ -2567,11 +2468,6 @@ function buildAreaOption(
2567
2468
  return {
2568
2469
  ...CHART_BASE,
2569
2470
  title: titleConfig,
2570
- tooltip: {
2571
- trigger: 'axis',
2572
- ...tooltipTheme,
2573
- axisPointer: { type: 'line' },
2574
- },
2575
2471
  grid: makeChartGrid({ xLabel, yLabel, hasTitle: !!parsed.title }),
2576
2472
  xAxis: makeGridAxis(
2577
2473
  'category',
@@ -2603,6 +2499,7 @@ function buildAreaOption(
2603
2499
  itemStyle: { color: lineColor },
2604
2500
  areaStyle: { opacity: 0.25 },
2605
2501
  emphasis: EMPHASIS_LINE,
2502
+ blur: BLUR_DIM,
2606
2503
  ...(markArea && { markArea }),
2607
2504
  },
2608
2505
  ],
@@ -2665,7 +2562,6 @@ function buildPieOption(
2665
2562
  colors: string[],
2666
2563
  bg: string,
2667
2564
  titleConfig: EChartsOption['title'],
2668
- tooltipTheme: Record<string, unknown>,
2669
2565
  isDoughnut: boolean
2670
2566
  ): EChartsOption {
2671
2567
  const HIDE_AXES = { xAxis: { show: false }, yAxis: { show: false } };
@@ -2688,10 +2584,6 @@ function buildPieOption(
2688
2584
  ...CHART_BASE,
2689
2585
  ...HIDE_AXES,
2690
2586
  title: titleConfig,
2691
- tooltip: {
2692
- trigger: 'item',
2693
- ...tooltipTheme,
2694
- },
2695
2587
  series: [
2696
2588
  {
2697
2589
  type: 'pie',
@@ -2708,6 +2600,7 @@ function buildPieOption(
2708
2600
  },
2709
2601
  labelLine: { show: true },
2710
2602
  emphasis: EMPHASIS_SELF,
2603
+ blur: BLUR_DIM,
2711
2604
  },
2712
2605
  ],
2713
2606
  };
@@ -2721,8 +2614,7 @@ function buildRadarOption(
2721
2614
  isDark: boolean,
2722
2615
  textColor: string,
2723
2616
  gridOpacity: number,
2724
- titleConfig: EChartsOption['title'],
2725
- tooltipTheme: Record<string, unknown>
2617
+ titleConfig: EChartsOption['title']
2726
2618
  ): EChartsOption {
2727
2619
  const bg = isDark ? palette.surface : palette.bg;
2728
2620
  const radarColor =
@@ -2740,10 +2632,6 @@ function buildRadarOption(
2740
2632
  title: titleConfig,
2741
2633
  xAxis: { show: false },
2742
2634
  yAxis: { show: false },
2743
- tooltip: {
2744
- trigger: 'item',
2745
- ...tooltipTheme,
2746
- },
2747
2635
  radar: {
2748
2636
  indicator,
2749
2637
  axisName: {
@@ -2781,6 +2669,7 @@ function buildRadarOption(
2781
2669
  },
2782
2670
  ],
2783
2671
  emphasis: EMPHASIS_SELF,
2672
+ blur: BLUR_DIM,
2784
2673
  },
2785
2674
  ],
2786
2675
  };
@@ -2793,8 +2682,7 @@ function buildPolarAreaOption(
2793
2682
  textColor: string,
2794
2683
  colors: string[],
2795
2684
  bg: string,
2796
- titleConfig: EChartsOption['title'],
2797
- tooltipTheme: Record<string, unknown>
2685
+ titleConfig: EChartsOption['title']
2798
2686
  ): EChartsOption {
2799
2687
  const data = parsed.data.map((d, i) => {
2800
2688
  const stroke = d.color ?? colors[i % colors.length];
@@ -2814,10 +2702,6 @@ function buildPolarAreaOption(
2814
2702
  title: titleConfig,
2815
2703
  xAxis: { show: false },
2816
2704
  yAxis: { show: false },
2817
- tooltip: {
2818
- trigger: 'item',
2819
- ...tooltipTheme,
2820
- },
2821
2705
  series: [
2822
2706
  {
2823
2707
  type: 'pie',
@@ -2836,6 +2720,7 @@ function buildPolarAreaOption(
2836
2720
  },
2837
2721
  labelLine: { show: true },
2838
2722
  emphasis: EMPHASIS_SELF,
2723
+ blur: BLUR_DIM,
2839
2724
  },
2840
2725
  ],
2841
2726
  };
@@ -2852,7 +2737,6 @@ function buildBarStackedOption(
2852
2737
  colors: string[],
2853
2738
  bg: string,
2854
2739
  titleConfig: EChartsOption['title'],
2855
- tooltipTheme: Record<string, unknown>,
2856
2740
  chartWidth?: number
2857
2741
  ): EChartsOption {
2858
2742
  const { xLabel, yLabel } = resolveAxisLabels(parsed);
@@ -2884,7 +2768,8 @@ function buildBarStackedOption(
2884
2768
  fontWeight: 'bold' as const,
2885
2769
  fontFamily: FONT_FAMILY,
2886
2770
  },
2887
- emphasis: EMPHASIS_SELF,
2771
+ emphasis: EMPHASIS_SERIES,
2772
+ blur: BLUR_DIM,
2888
2773
  };
2889
2774
  });
2890
2775
 
@@ -2932,7 +2817,7 @@ function buildBarStackedOption(
2932
2817
  hasLegend: true,
2933
2818
  }),
2934
2819
  xAxis: isHorizontal ? valueAxis : categoryAxis,
2935
- yAxis: isHorizontal ? categoryAxis : valueAxis,
2820
+ yAxis: isHorizontal ? { ...categoryAxis, inverse: true } : valueAxis,
2936
2821
  series,
2937
2822
  };
2938
2823
  }