@xq-labs/data-ui-v2 0.3.0 → 0.4.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.
@@ -193,7 +193,7 @@ const stateConfig = {
193
193
  ### 7.1 组件定位
194
194
 
195
195
  `BarLineChart` 用于承接大多数柱线组合场景。
196
- 推荐先通过 `data + xAxisKey + series` 表达业务数据,再用 `variant`、`preset`、`customOption` 做增强。
196
+ 推荐先通过 `data + xAxisKey + series` 表达业务数据,再用 `variant`、`preset`、`barBackground`、`customOption` 做增强。
197
197
 
198
198
  ### 7.2 Props
199
199
 
@@ -206,12 +206,30 @@ const stateConfig = {
206
206
  | `preset` | `String` | `'compare'` | 预设:`compare` / `trend` / `rank` |
207
207
  | `barWidth` | `Number` | `18` | 柱体宽度 |
208
208
  | `barGap` | `Number \| String` | `8` | 柱间距 |
209
+ | `barBackground` | `Object` | `{}` | 柱形背景配置,为当前图中的柱系列渲染整列高度背景柱 |
209
210
  | `xAxisScroll` | `Object` | `{}` | X 轴类目滚动配置,只作用于横轴 |
210
211
  | `customOption` | `Object` | `{}` | 对 ECharts option 的补充覆盖 |
211
212
  | `loading` | `Boolean` | `false` | 是否显示统一遮罩式 loading(非 ECharts 原生 loading) |
212
213
  | `stateConfig` | `Object` | `{}` | 统一状态配置,原样透传给 `BaseChart` |
213
214
  | `height` | `String \| Number` | `320` | 容器高度 |
214
215
 
216
+ `barBackground` 推荐写法:
217
+
218
+ ```js
219
+ const barBackground = {
220
+ show: true,
221
+ colors: ['#FFFFFF', '#D8E4FF'],
222
+ opacity: 0.2
223
+ }
224
+ ```
225
+
226
+ 说明:
227
+
228
+ - `show`:是否开启柱形背景。
229
+ - `colors`:可选背景色板,支持 1~3 个色值;建议传不带 alpha 的颜色值,不传时按当前柱形默认背景色推导。
230
+ - `opacity`:背景柱透明度,推荐传 `0 ~ 1` 之间的小数。
231
+ - 背景高度语义:按当前坐标轴整列高度铺满,用来强化柱槽轮廓,不跟随单个数据值缩放。
232
+
215
233
  ### 7.3 BarLineChart 数据格式
216
234
 
217
235
  `BarLineChart` 的数据通常拆成两部分:
@@ -742,6 +760,7 @@ const data = [
742
760
  series,
743
761
  variant: 'cylinder',
744
762
  preset: 'compare',
763
+ barBackground,
745
764
  xAxisScroll,
746
765
  stateConfig,
747
766
  customOption
@@ -27,6 +27,7 @@ Playground 中 `BarLineChart` 按分组路由组织:
27
27
  preset,
28
28
  barWidth,
29
29
  barGap,
30
+ barBackground,
30
31
  xAxisScroll,
31
32
  customOption,
32
33
  stateConfig
@@ -42,6 +43,7 @@ Playground 中 `BarLineChart` 按分组路由组织:
42
43
  - `variant`:`flat` / `cylinder` / `cube`。
43
44
  - `preset`:展示预设。
44
45
  - `barWidth`、`barGap`:柱体宽度与间距。
46
+ - `barBackground`:柱形背景配置,用于为当前图中的柱系列补整列高度背景柱。
45
47
  - `xAxisScroll`:X 轴滚动配置,用于类目过多时默认展示最新数据窗口。
46
48
  - `customOption`:ECharts 展示细节覆盖。
47
49
  - `stateConfig`:统一收拢空态文案、空态图和 loading 文案。
@@ -57,6 +59,12 @@ const xAxisScroll = {
57
59
  inside: true
58
60
  }
59
61
 
62
+ const barBackground = {
63
+ show: true,
64
+ colors: ['#FFFFFF', '#D8E4FF'],
65
+ opacity: 0.2
66
+ }
67
+
60
68
  const stateConfig = {
61
69
  empty: {
62
70
  text: '暂无柱线图数据',
@@ -77,13 +85,24 @@ const stateConfig = {
77
85
  - `showSlider`:是否显示底部滚动条。
78
86
  - `inside`:是否允许鼠标滚轮 / 触控板在图表内部滚动。
79
87
 
88
+ `barBackground` 字段说明:
89
+
90
+ - `show`:是否开启柱形背景。
91
+ - `colors`:可选背景色板,支持 1~3 个色值;建议传不带 alpha 的颜色值,不传时按当前柱形默认背景色推导。
92
+ - `opacity`:背景柱透明度,推荐传 `0 ~ 1` 之间的小数。
93
+
94
+ 背景高度语义:
95
+
96
+ - `barBackground` 渲染的是当前坐标轴下的整列高度背景柱,不跟随单个数据值缩放。
97
+
80
98
  ## 3. 如何自定义(推荐顺序)
81
99
 
82
100
  1. **优先 `series` 表达业务语义**:先确定字段、柱线类型、双轴和堆叠关系。
83
101
  2. **用 `series.colors` 控制系列配色**:把业务色板放在系列层。
84
- 3. **用 `xAxisScroll` 控制横轴窗口**:类目较多时默认展示最新 `visibleCount` 个类目。
85
- 4. **`stateConfig` 收拢状态文案**:空态图、空态文案、loading 文案统一从这里传。
86
- 5. **`customOption` 补充细节**:用于 tooltip、legend、grid、坐标轴样式、dataZoom 等展示项。
102
+ 3. **用 `barBackground` 强化柱槽轮廓**:需要整列高度背景时,再开启背景柱并调透明度。
103
+ 4. **用 `xAxisScroll` 控制横轴窗口**:类目较多时默认展示最新 `visibleCount` 个类目。
104
+ 5. **`stateConfig` 收拢状态文案**:空态图、空态文案、loading 文案统一从这里传。
105
+ 6. **`customOption` 补充细节**:用于 tooltip、legend、grid、坐标轴样式、dataZoom 等展示项。
87
106
 
88
107
  不建议用 `customOption` 直接整体替换关键业务结构。
89
108
  如果必须完全自定义滚动条,可通过 `customOption.dataZoom` 覆盖 `xAxisScroll` 生成结果。
@@ -91,5 +110,5 @@ const stateConfig = {
91
110
  ## 4. 可执行验收要点
92
111
 
93
112
  - 页面分组名称与路由一致:基础用法、圆柱样式、方柱样式、进阶配置、customOption 与自定义、实验室。
94
- - 文档示例包含 `series.colors`、`xAxisScroll`、`stateConfig` 与 `customOption`。
113
+ - 文档示例包含 `series.colors`、`barBackground`、`xAxisScroll`、`stateConfig` 与 `customOption`。
95
114
  - 文档明确实验室边界与推荐自定义顺序。
@@ -1,5 +1,5 @@
1
1
  import '../../theme-chalk/index.css';
2
- import { B as BarLineChart } from '../index-d01ce220.js';
2
+ import { B as BarLineChart } from '../index-914fbae3.js';
3
3
  import { w as withInstall } from '../with-install-e405b463.js';
4
4
  import 'echarts/core';
5
5
  import 'echarts/charts';
@@ -129,6 +129,19 @@ function resolveSeriesColor$1(item, index) {
129
129
  }
130
130
  return DEFAULT_COLORS[index % DEFAULT_COLORS.length];
131
131
  }
132
+ function collectBarSeries(normalizedSeries) {
133
+ return normalizedSeries.map(function (item, originalIndex) {
134
+ return _objectSpread2(_objectSpread2({}, item), {}, {
135
+ originalIndex: originalIndex
136
+ });
137
+ }).filter(function (item) {
138
+ return item.kind === 'bar';
139
+ }).map(function (item, barSeriesIndex) {
140
+ return _objectSpread2(_objectSpread2({}, item), {}, {
141
+ barSeriesIndex: barSeriesIndex
142
+ });
143
+ });
144
+ }
132
145
 
133
146
  /**
134
147
  * 归一化颜色入参。
@@ -479,6 +492,53 @@ function createBarLayout(barSeries, barWidth, barGap) {
479
492
  barGap: resolvedBarGap
480
493
  };
481
494
  }
495
+ function pickBackgroundSlotSeries(barSeries) {
496
+ var renderedStacks = new Set();
497
+ return barSeries.filter(function (item) {
498
+ if (!item.stack) {
499
+ return true;
500
+ }
501
+ if (renderedStacks.has(item.stack)) {
502
+ return false;
503
+ }
504
+ renderedStacks.add(item.stack);
505
+ return true;
506
+ });
507
+ }
508
+ function createBackgroundSeriesData(rawData) {
509
+ return rawData.map(function (row, rowIndex) {
510
+ return {
511
+ value: [rowIndex]
512
+ };
513
+ });
514
+ }
515
+ function resolveBackgroundFaceAlpha(key, opacity) {
516
+ var alphaMap = {
517
+ left: 0.82,
518
+ right: 1,
519
+ top: 1.8,
520
+ middle: 0.82,
521
+ bottom: 1.28,
522
+ legend: 1
523
+ };
524
+ var ratio = alphaMap[key] || 1;
525
+ return Math.max(0, Math.min(1, opacity * ratio));
526
+ }
527
+ function applyBackgroundFaceAlphaToColorMap(colorMap, opacity) {
528
+ return Object.keys(colorMap || {}).reduce(function (result, key) {
529
+ result[key] = applyAlphaToColor(colorMap[key], resolveBackgroundFaceAlpha(key, opacity));
530
+ return result;
531
+ }, {});
532
+ }
533
+ function normalizeBackgroundColors(barBackground, item) {
534
+ if (Array.isArray(barBackground && barBackground.colors) && barBackground.colors.length > 0) {
535
+ return barBackground.colors;
536
+ }
537
+ if (Array.isArray(item && item.colors) && item.colors.length > 0) {
538
+ return item.colors;
539
+ }
540
+ return undefined;
541
+ }
482
542
 
483
543
  /**
484
544
  * 创建堆叠累加器。
@@ -607,13 +667,7 @@ function buildCustomBarSeries(_ref) {
607
667
  barGap = _ref.barGap,
608
668
  createRenderItem = _ref.createRenderItem,
609
669
  resolveColorMap = _ref.resolveColorMap;
610
- var barSeries = normalizedSeries.map(function (item, originalIndex) {
611
- return _objectSpread2(_objectSpread2({}, item), {}, {
612
- originalIndex: originalIndex
613
- });
614
- }).filter(function (item) {
615
- return item.kind === 'bar';
616
- });
670
+ var barSeries = collectBarSeries(normalizedSeries);
617
671
  var layout = createBarLayout(barSeries, barWidth, barGap);
618
672
  var barSeriesWithData = buildBarSeriesData(rawData, barSeries);
619
673
  return barSeriesWithData.map(function (item, index) {
@@ -642,6 +696,57 @@ function buildCustomBarSeries(_ref) {
642
696
  };
643
697
  });
644
698
  }
699
+ function buildBackgroundCustomBarSeries(_ref2) {
700
+ var rawData = _ref2.rawData,
701
+ normalizedSeries = _ref2.normalizedSeries,
702
+ barWidth = _ref2.barWidth,
703
+ barGap = _ref2.barGap,
704
+ _ref2$barBackground = _ref2.barBackground,
705
+ barBackground = _ref2$barBackground === void 0 ? {} : _ref2$barBackground,
706
+ createRenderItem = _ref2.createRenderItem,
707
+ resolveColorMap = _ref2.resolveColorMap;
708
+ if (!barBackground.show) {
709
+ return [];
710
+ }
711
+ var barSeries = collectBarSeries(normalizedSeries);
712
+ if (!barSeries.length) {
713
+ return [];
714
+ }
715
+ var layout = createBarLayout(barSeries, barWidth, barGap);
716
+ var backgroundSeriesData = createBackgroundSeriesData(rawData);
717
+ return pickBackgroundSlotSeries(barSeries).map(function (item) {
718
+ var slotKey = item.stack || "__slot_".concat(item.barSeriesIndex);
719
+ var slotIndex = layout.slotMap[slotKey];
720
+ var fallbackColor = resolveSeriesColor$1(item, item.originalIndex);
721
+ var palette = normalizeBackgroundColors(barBackground, item);
722
+ var baseColorMap = resolveColorMap ? resolveColorMap(palette, fallbackColor) : {
723
+ legend: fallbackColor
724
+ };
725
+ var backgroundColorMap = applyBackgroundFaceAlphaToColorMap(baseColorMap, barBackground.opacity);
726
+ return {
727
+ name: item.name,
728
+ type: 'custom',
729
+ stack: item.stack,
730
+ yAxisIndex: item.yAxisIndex || 0,
731
+ isBackground: true,
732
+ silent: true,
733
+ tooltip: {
734
+ show: false
735
+ },
736
+ renderItem: createRenderItem(layout, slotIndex, backgroundColorMap, _objectSpread2(_objectSpread2({}, item), {}, {
737
+ isBackground: true
738
+ })),
739
+ encode: {
740
+ x: 0
741
+ },
742
+ itemStyle: {
743
+ color: backgroundColorMap.legend || applyAlphaToColor(fallbackColor, barBackground.opacity)
744
+ },
745
+ data: backgroundSeriesData,
746
+ z: 0
747
+ };
748
+ });
749
+ }
645
750
 
646
751
  /**
647
752
  * 归一化 flat 模式下的 `barGap`。
@@ -705,6 +810,27 @@ function resolveFlatBarColors(item, index) {
705
810
  end: darkenColor(fallbackColor, 0.12)
706
811
  };
707
812
  }
813
+ function resolveFlatBackgroundColors(item, index, barBackground) {
814
+ var paletteSource = Array.isArray(barBackground.colors) && barBackground.colors.length > 0 ? {
815
+ colors: barBackground.colors
816
+ } : item;
817
+ var colorMap = resolveFlatBarColors(paletteSource, index);
818
+ return {
819
+ start: applyAlphaToColor(colorMap.start, barBackground.opacity),
820
+ middle: applyAlphaToColor(colorMap.middle, barBackground.opacity),
821
+ end: applyAlphaToColor(colorMap.end, barBackground.opacity)
822
+ };
823
+ }
824
+ function shouldEnableBackground(item, renderedStacks) {
825
+ if (!item.stack) {
826
+ return true;
827
+ }
828
+ if (renderedStacks.has(item.stack)) {
829
+ return false;
830
+ }
831
+ renderedStacks.add(item.stack);
832
+ return true;
833
+ }
708
834
 
709
835
  /**
710
836
  * 创建柱体纵向渐变。
@@ -736,9 +862,12 @@ function createFlatBarLineSeries(_ref) {
736
862
  var normalizedSeries = _ref.normalizedSeries,
737
863
  rawData = _ref.rawData,
738
864
  barWidth = _ref.barWidth,
739
- barGap = _ref.barGap;
865
+ barGap = _ref.barGap,
866
+ _ref$barBackground = _ref.barBackground,
867
+ barBackground = _ref$barBackground === void 0 ? {} : _ref$barBackground;
740
868
  var resolvedBarWidth = Number.isFinite(Number(barWidth)) ? Number(barWidth) : 18;
741
869
  var resolvedBarGap = toBarGapValue(barGap);
870
+ var renderedStacks = new Set();
742
871
  return normalizedSeries.map(function (item, index) {
743
872
  var isLine = item.kind === 'line';
744
873
  var color = resolveSeriesColor(item, index);
@@ -759,11 +888,18 @@ function createFlatBarLineSeries(_ref) {
759
888
  yAxisIndex: item.yAxisIndex
760
889
  });
761
890
  }
891
+ var showBackground = barBackground.show && shouldEnableBackground(item, renderedStacks);
892
+ var backgroundColors = resolveFlatBackgroundColors(item, index, barBackground);
762
893
  return _objectSpread2(_objectSpread2({}, baseSeries), {}, {
763
894
  stack: item.stack,
764
895
  barWidth: resolvedBarWidth,
765
- barGap: resolvedBarGap
766
- });
896
+ barGap: resolvedBarGap,
897
+ showBackground: showBackground
898
+ }, showBackground ? {
899
+ backgroundStyle: {
900
+ color: createBarGradient(backgroundColors)
901
+ }
902
+ } : {});
767
903
  });
768
904
  }
769
905
 
@@ -827,9 +963,63 @@ function createFaceGradient(x0, y0, x1, y1, startColor, endColor) {
827
963
  * 创建方柱渲染器。
828
964
  * 参考案例使用三块 polygon 拼接成立方体,而不是“正面 rect + 顶面/侧面”。
829
965
  */
830
- function createCubeRenderItem(layout, slotIndex, colorMap) {
966
+ function createCubeRenderItem(layout, slotIndex, colorMap, seriesItem) {
831
967
  return function renderItem(params, api) {
832
968
  var rowIndex = api.value(0);
969
+ var offsetX = getBarOffset(layout, slotIndex);
970
+ var centerPoint = api.coord([rowIndex, 0]);
971
+ var centerX = centerPoint[0] + offsetX;
972
+ var halfWidth = layout.barWidth / 2;
973
+ var offsetY = Math.tan(Math.PI / 9) * halfWidth;
974
+ var leftFaceGradient = createFaceGradient(0, 0, 0, 1, colorMap.left, colorMap.left);
975
+ var rightFaceGradient = createFaceGradient(0, 0, 0, 1, colorMap.right, colorMap.right);
976
+ var topFaceGradient = createFaceGradient(0, 0, 1, 0, colorMap.top, colorMap.top);
977
+ if (seriesItem && seriesItem.isBackground === true) {
978
+ var coordSys = params.coordSys || {};
979
+ var clipX = coordSys.x || 0;
980
+ var _topY = coordSys.y || 0;
981
+ var width = coordSys.width || 0;
982
+ var _baseY = _topY + (coordSys.height || 0);
983
+ var _topSurfaceY = _topY + Math.abs(offsetY - 1);
984
+ return {
985
+ type: 'group',
986
+ clipPath: {
987
+ type: 'rect',
988
+ shape: {
989
+ x: clipX,
990
+ y: _topY,
991
+ width: width,
992
+ height: coordSys.height || 0
993
+ }
994
+ },
995
+ children: [{
996
+ type: 'polygon',
997
+ shape: {
998
+ points: [[centerX, _topSurfaceY + offsetY - 1], [centerX - halfWidth, _topSurfaceY], [centerX - halfWidth, _baseY - offsetY], [centerX, _baseY - 1]]
999
+ },
1000
+ style: {
1001
+ fill: leftFaceGradient
1002
+ }
1003
+ }, {
1004
+ type: 'polygon',
1005
+ shape: {
1006
+ points: [[centerX, _topSurfaceY + offsetY - 1], [centerX + halfWidth, _topSurfaceY], [centerX + halfWidth, _baseY - offsetY], [centerX, _baseY - 1]]
1007
+ },
1008
+ style: {
1009
+ fill: rightFaceGradient
1010
+ }
1011
+ }, {
1012
+ type: 'polygon',
1013
+ shape: {
1014
+ points: [[centerX, _topSurfaceY + offsetY - 1], [centerX + halfWidth, _topSurfaceY], [centerX, _topSurfaceY - offsetY + 1], [centerX - halfWidth, _topSurfaceY]]
1015
+ },
1016
+ style: {
1017
+ fill: topFaceGradient
1018
+ },
1019
+ z2: 2
1020
+ }]
1021
+ };
1022
+ }
833
1023
  var endValue = api.value(1);
834
1024
  var baseValue = api.value(2);
835
1025
  var rawValue = api.value(3);
@@ -840,20 +1030,13 @@ function createCubeRenderItem(layout, slotIndex, colorMap) {
840
1030
  }
841
1031
  var endPoint = api.coord([rowIndex, endValue]);
842
1032
  var basePoint = api.coord([rowIndex, baseValue]);
843
- var offsetX = getBarOffset(layout, slotIndex);
844
- var centerX = endPoint[0] + offsetX;
845
1033
  var topY = endPoint[1];
846
1034
  var baseY = basePoint[1];
847
- var halfWidth = layout.barWidth / 2;
848
- var offsetY = Math.tan(Math.PI / 9) * halfWidth;
849
1035
  var isPositive = rawValue >= 0;
850
1036
  var connectorOverlap = stackStart ? 0 : Math.max(2, Math.round(offsetY));
851
1037
  var connectorCapOffset = stackEnd ? 0 : Math.min(2, offsetY * 0.45);
852
1038
  var connectBaseY = isPositive ? baseY + connectorOverlap : baseY - connectorOverlap;
853
1039
  var topSurfaceY = topY + connectorCapOffset;
854
- var leftFaceGradient = createFaceGradient(0, 0, 0, 1, colorMap.left, colorMap.left);
855
- var rightFaceGradient = createFaceGradient(0, 0, 0, 1, colorMap.right, colorMap.right);
856
- var topFaceGradient = createFaceGradient(0, 0, 1, 0, colorMap.top, colorMap.top);
857
1040
  return {
858
1041
  type: 'group',
859
1042
  children: [{
@@ -899,6 +1082,15 @@ function createCubeRenderItem(layout, slotIndex, colorMap) {
899
1082
  function createCubeBarLineOption(normalizedInput) {
900
1083
  var flatOption = createFlatBarLineOption(normalizedInput);
901
1084
  var flatSeries = createFlatBarLineSeries(normalizedInput);
1085
+ var backgroundSeries = buildBackgroundCustomBarSeries({
1086
+ rawData: normalizedInput.rawData,
1087
+ normalizedSeries: normalizedInput.normalizedSeries,
1088
+ barWidth: normalizedInput.barWidth,
1089
+ barGap: normalizedInput.barGap,
1090
+ barBackground: normalizedInput.barBackground,
1091
+ createRenderItem: createCubeRenderItem,
1092
+ resolveColorMap: resolveCubeColors
1093
+ });
902
1094
  var customBarSeries = buildCustomBarSeries({
903
1095
  rawData: normalizedInput.rawData,
904
1096
  normalizedSeries: normalizedInput.normalizedSeries,
@@ -917,7 +1109,7 @@ function createCubeBarLineOption(normalizedInput) {
917
1109
  return flatSeries[index];
918
1110
  });
919
1111
  return _objectSpread2(_objectSpread2({}, flatOption), {}, {
920
- series: series
1112
+ series: [].concat(_toConsumableArray(series), _toConsumableArray(backgroundSeries))
921
1113
  });
922
1114
  }
923
1115
 
@@ -941,6 +1133,20 @@ function createEllipsePolygon(cx, cy, rx, ry) {
941
1133
  }
942
1134
  return polygonPoints;
943
1135
  }
1136
+ function createEllipseArcPoints(cx, cy, rx, ry, startAngle, endAngle) {
1137
+ var points = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 12;
1138
+ var arcPoints = [];
1139
+ for (var index = 0; index <= points; index += 1) {
1140
+ var angle = startAngle + (endAngle - startAngle) * index / points;
1141
+ arcPoints.push([cx + Math.cos(angle) * rx, cy + Math.sin(angle) * ry]);
1142
+ }
1143
+ return arcPoints;
1144
+ }
1145
+ function createCylinderSidePolygon(cx, topCy, bottomCy, rx, ry) {
1146
+ var topLowerArc = createEllipseArcPoints(cx, topCy, rx, ry, Math.PI, 0);
1147
+ var bottomUpperArc = createEllipseArcPoints(cx, bottomCy, rx, ry, 0, -Math.PI);
1148
+ return [].concat(_toConsumableArray(topLowerArc), _toConsumableArray(bottomUpperArc));
1149
+ }
944
1150
 
945
1151
  /**
946
1152
  * 创建圆柱渲染器。
@@ -949,9 +1155,76 @@ function createEllipsePolygon(cx, cy, rx, ry) {
949
1155
  * 2. 主体用纵向渐变矩形模拟曲面;
950
1156
  * 3. 堆叠连接处保留底片,但不绘制深色描边和弧线,避免形成脏色带。
951
1157
  */
952
- function createCylinderRenderItem(layout, slotIndex, colorMap) {
1158
+ function createCylinderRenderItem(layout, slotIndex, colorMap, seriesItem) {
953
1159
  return function renderItem(params, api) {
954
1160
  var rowIndex = api.value(0);
1161
+ var offsetX = getBarOffset(layout, slotIndex);
1162
+ var centerPoint = api.coord([rowIndex, 0]);
1163
+ var centerX = centerPoint[0] + offsetX;
1164
+ var radiusX = layout.barWidth / 2;
1165
+ var radiusY = radiusX * 0.4;
1166
+ var createSideGradient = function createSideGradient(topColor, middleColor, bottomColor) {
1167
+ var opacity = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : CYLINDER_SIDE_OPACITY;
1168
+ return new graphic.LinearGradient(0, 0, 0, 1, [{
1169
+ offset: 0,
1170
+ color: opacity === null ? topColor : applyAlphaToColor(topColor, opacity)
1171
+ }, {
1172
+ offset: 0.55,
1173
+ color: opacity === null ? middleColor : applyAlphaToColor(middleColor, opacity)
1174
+ }, {
1175
+ offset: 1,
1176
+ color: opacity === null ? bottomColor : applyAlphaToColor(bottomColor, opacity)
1177
+ }]);
1178
+ };
1179
+ if (seriesItem && seriesItem.isBackground === true) {
1180
+ var coordSys = params.coordSys || {};
1181
+ var clipX = coordSys.x || 0;
1182
+ var topY = coordSys.y || 0;
1183
+ var width = coordSys.width || 0;
1184
+ var height = coordSys.height || 0;
1185
+ var _topEllipseY = topY + radiusY;
1186
+ var bottomEllipseY = topY + height - radiusY;
1187
+ return {
1188
+ type: 'group',
1189
+ clipPath: {
1190
+ type: 'rect',
1191
+ shape: {
1192
+ x: clipX,
1193
+ y: topY,
1194
+ width: width,
1195
+ height: height
1196
+ }
1197
+ },
1198
+ children: [{
1199
+ type: 'polygon',
1200
+ shape: {
1201
+ points: createEllipsePolygon(centerX, bottomEllipseY, radiusX, radiusY)
1202
+ },
1203
+ style: {
1204
+ fill: colorMap.bottom
1205
+ },
1206
+ z: 0
1207
+ }, {
1208
+ type: 'polygon',
1209
+ shape: {
1210
+ points: createCylinderSidePolygon(centerX, _topEllipseY, bottomEllipseY, radiusX, radiusY)
1211
+ },
1212
+ style: {
1213
+ fill: createSideGradient(colorMap.middle, colorMap.middle, colorMap.bottom, null)
1214
+ },
1215
+ z: 1
1216
+ }, {
1217
+ type: 'polygon',
1218
+ shape: {
1219
+ points: createEllipsePolygon(centerX, _topEllipseY, radiusX, radiusY)
1220
+ },
1221
+ style: {
1222
+ fill: colorMap.top
1223
+ },
1224
+ z2: 2
1225
+ }]
1226
+ };
1227
+ }
955
1228
  var endValue = api.value(1);
956
1229
  var baseValue = api.value(2);
957
1230
  var rawValue = api.value(3);
@@ -962,10 +1235,6 @@ function createCylinderRenderItem(layout, slotIndex, colorMap) {
962
1235
  }
963
1236
  var endPoint = api.coord([rowIndex, endValue]);
964
1237
  var basePoint = api.coord([rowIndex, baseValue]);
965
- var offsetX = getBarOffset(layout, slotIndex);
966
- var centerX = endPoint[0] + offsetX;
967
- var radiusX = layout.barWidth / 2;
968
- var radiusY = radiusX * 0.4;
969
1238
  var isPositive = rawValue >= 0;
970
1239
  var barHeight = Math.abs(endPoint[1] - basePoint[1]);
971
1240
  var visibleEllipseY = endPoint[1];
@@ -980,16 +1249,7 @@ function createCylinderRenderItem(layout, slotIndex, colorMap) {
980
1249
  var gradientTopColor = isPositive ? colorMap.middle : darkenColor(colorMap.bottom, 0.05);
981
1250
  var gradientMiddleColor = colorMap.middle;
982
1251
  var gradientBottomColor = isPositive ? colorMap.bottom : colorMap.middle;
983
- var sideGradient = new graphic.LinearGradient(0, 0, 0, 1, [{
984
- offset: 0,
985
- color: applyAlphaToColor(gradientTopColor, CYLINDER_SIDE_OPACITY)
986
- }, {
987
- offset: 0.55,
988
- color: applyAlphaToColor(gradientMiddleColor, CYLINDER_SIDE_OPACITY)
989
- }, {
990
- offset: 1,
991
- color: applyAlphaToColor(gradientBottomColor, CYLINDER_SIDE_OPACITY)
992
- }]);
1252
+ var sideGradient = createSideGradient(gradientTopColor, gradientMiddleColor, gradientBottomColor);
993
1253
  return {
994
1254
  type: 'group',
995
1255
  children: [].concat(_toConsumableArray(showBottomPlate ? [{
@@ -1036,6 +1296,15 @@ function createCylinderRenderItem(layout, slotIndex, colorMap) {
1036
1296
  function createCylinderBarLineOption(normalizedInput) {
1037
1297
  var flatOption = createFlatBarLineOption(normalizedInput);
1038
1298
  var flatSeries = createFlatBarLineSeries(normalizedInput);
1299
+ var backgroundSeries = buildBackgroundCustomBarSeries({
1300
+ rawData: normalizedInput.rawData,
1301
+ normalizedSeries: normalizedInput.normalizedSeries,
1302
+ barWidth: normalizedInput.barWidth,
1303
+ barGap: normalizedInput.barGap,
1304
+ barBackground: normalizedInput.barBackground,
1305
+ createRenderItem: createCylinderRenderItem,
1306
+ resolveColorMap: resolveCylinderColors
1307
+ });
1039
1308
  var customBarSeries = buildCustomBarSeries({
1040
1309
  rawData: normalizedInput.rawData,
1041
1310
  normalizedSeries: normalizedInput.normalizedSeries,
@@ -1054,13 +1323,18 @@ function createCylinderBarLineOption(normalizedInput) {
1054
1323
  return flatSeries[index];
1055
1324
  });
1056
1325
  return _objectSpread2(_objectSpread2({}, flatOption), {}, {
1057
- series: series
1326
+ series: [].concat(_toConsumableArray(series), _toConsumableArray(backgroundSeries))
1058
1327
  });
1059
1328
  }
1060
1329
 
1061
1330
  var DEFAULT_VARIANT = 'flat';
1062
1331
  var DEFAULT_X_AXIS_SCROLL_VISIBLE_COUNT = 8;
1063
1332
  var DEFAULT_X_AXIS_SCROLL_GRID_BOTTOM = 56;
1333
+ var DEFAULT_BAR_BACKGROUND = {
1334
+ show: false,
1335
+ colors: [],
1336
+ opacity: 1
1337
+ };
1064
1338
  var BAR_LINE_PUBLIC_VARIANTS = ['flat', 'cylinder', 'cube'];
1065
1339
 
1066
1340
  // 公开 variant 能力在此处收口:只允许 flat / cylinder / cube。
@@ -1144,6 +1418,21 @@ function normalizeXAxisScrollConfig() {
1144
1418
  };
1145
1419
  }
1146
1420
 
1421
+ /**
1422
+ * 归一化柱形背景配置。
1423
+ * 这里统一收敛开关、颜色数量和透明度范围,避免变体层重复兜底。
1424
+ */
1425
+ function normalizeBarBackgroundConfig() {
1426
+ var barBackground = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1427
+ var config = barBackground && _typeof(barBackground) === 'object' ? barBackground : {};
1428
+ var opacity = Number(config.opacity);
1429
+ return _objectSpread2(_objectSpread2({}, DEFAULT_BAR_BACKGROUND), {}, {
1430
+ show: config.show === true,
1431
+ colors: Array.isArray(config.colors) ? config.colors.filter(Boolean).slice(0, 3) : [],
1432
+ opacity: Number.isFinite(opacity) ? Math.max(0, Math.min(1, opacity)) : 1
1433
+ });
1434
+ }
1435
+
1147
1436
  /**
1148
1437
  * 根据横轴类目数量生成 ECharts dataZoom。
1149
1438
  * 默认从末尾向前取 `visibleCount` 个类目,满足“最新数据优先展示”的看板诉求。
@@ -1214,6 +1503,7 @@ function buildBarLineOption() {
1214
1503
  variant = _ref$variant === void 0 ? 'flat' : _ref$variant,
1215
1504
  barWidth = _ref.barWidth,
1216
1505
  barGap = _ref.barGap,
1506
+ barBackground = _ref.barBackground,
1217
1507
  xAxisScroll = _ref.xAxisScroll,
1218
1508
  customOption = _ref.customOption;
1219
1509
  var normalizedInput = normalizeBarLineInput({
@@ -1225,10 +1515,12 @@ function buildBarLineOption() {
1225
1515
  var presetOption = getBarLinePreset(preset);
1226
1516
  var resolvedVariant = resolveVariantName(variant);
1227
1517
  var createVariantOption = variantFactory[resolvedVariant] || variantFactory[DEFAULT_VARIANT];
1518
+ var normalizedBarBackground = normalizeBarBackgroundConfig(barBackground);
1228
1519
  var variantOption = createVariantOption(_objectSpread2(_objectSpread2({}, normalizedInput), {}, {
1229
1520
  includeXAxis: false,
1230
1521
  barWidth: barWidth,
1231
- barGap: barGap
1522
+ barGap: barGap,
1523
+ barBackground: normalizedBarBackground
1232
1524
  }));
1233
1525
  var xAxisScrollOption = createXAxisScrollOption(normalizedInput.categories, xAxisScroll);
1234
1526
  return mergeChartOption(mergeChartOption(mergeChartOption(baseOption, presetOption, variantOption), xAxisScrollOption), customOption);
@@ -1330,6 +1622,17 @@ var script = {
1330
1622
  type: [Number, String],
1331
1623
  "default": 8
1332
1624
  },
1625
+ /**
1626
+ * 柱形背景配置。
1627
+ * 仅对支持背景柱的柱系列生效,builder 会负责归一化 `show/colors/opacity`
1628
+ * 并交由具体变体决定最终渲染策略。
1629
+ */
1630
+ barBackground: {
1631
+ type: Object,
1632
+ "default": function _default() {
1633
+ return {};
1634
+ }
1635
+ },
1333
1636
  /**
1334
1637
  * 额外透传给 ECharts option 的自定义配置。
1335
1638
  * 会在 base / preset / variant option 合并完成后再覆盖。
@@ -1404,6 +1707,7 @@ var script = {
1404
1707
  preset: this.preset,
1405
1708
  barWidth: this.barWidth,
1406
1709
  barGap: this.barGap,
1710
+ barBackground: this.barBackground,
1407
1711
  xAxisScroll: this.xAxisScroll,
1408
1712
  customOption: this.customOption
1409
1713
  });
@@ -1411,7 +1715,7 @@ var script = {
1411
1715
  }
1412
1716
  };
1413
1717
 
1414
- var css_248z = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
1718
+ var css_248z = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
1415
1719
  styleInject(css_248z);
1416
1720
 
1417
1721
  /* script */
@@ -1445,7 +1749,7 @@ __vue_render__._withStripped = true;
1445
1749
  /* style */
1446
1750
  var __vue_inject_styles__ = undefined;
1447
1751
  /* scoped */
1448
- var __vue_scope_id__ = "data-v-0c9a6292";
1752
+ var __vue_scope_id__ = "data-v-4e3be95d";
1449
1753
  /* module identifier */
1450
1754
  var __vue_module_identifier__ = undefined;
1451
1755
  /* functional template */
package/es/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import '../theme-chalk/index.css';
2
2
  import { w as withInstall, B as BaseChart } from './with-install-e405b463.js';
3
- import { B as BarLineChart } from './index-d01ce220.js';
3
+ import { B as BarLineChart } from './index-914fbae3.js';
4
4
  import { P as PieChart } from './index-78b6b881.js';
5
5
  import { R as RadarChart } from './index-788e473f.js';
6
6
  import 'echarts/core';
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  require('../../theme-chalk/index.css');
6
- var index = require('../index-cc49894a.js');
6
+ var index = require('../index-3d9f6fe7.js');
7
7
  var withInstall = require('../with-install-4304a8ea.js');
8
8
  require('echarts/core');
9
9
  require('echarts/charts');
@@ -149,6 +149,19 @@ function resolveSeriesColor$1(item, index) {
149
149
  }
150
150
  return colors.DEFAULT_COLORS[index % colors.DEFAULT_COLORS.length];
151
151
  }
152
+ function collectBarSeries(normalizedSeries) {
153
+ return normalizedSeries.map(function (item, originalIndex) {
154
+ return colors._objectSpread2(colors._objectSpread2({}, item), {}, {
155
+ originalIndex: originalIndex
156
+ });
157
+ }).filter(function (item) {
158
+ return item.kind === 'bar';
159
+ }).map(function (item, barSeriesIndex) {
160
+ return colors._objectSpread2(colors._objectSpread2({}, item), {}, {
161
+ barSeriesIndex: barSeriesIndex
162
+ });
163
+ });
164
+ }
152
165
 
153
166
  /**
154
167
  * 归一化颜色入参。
@@ -499,6 +512,53 @@ function createBarLayout(barSeries, barWidth, barGap) {
499
512
  barGap: resolvedBarGap
500
513
  };
501
514
  }
515
+ function pickBackgroundSlotSeries(barSeries) {
516
+ var renderedStacks = new Set();
517
+ return barSeries.filter(function (item) {
518
+ if (!item.stack) {
519
+ return true;
520
+ }
521
+ if (renderedStacks.has(item.stack)) {
522
+ return false;
523
+ }
524
+ renderedStacks.add(item.stack);
525
+ return true;
526
+ });
527
+ }
528
+ function createBackgroundSeriesData(rawData) {
529
+ return rawData.map(function (row, rowIndex) {
530
+ return {
531
+ value: [rowIndex]
532
+ };
533
+ });
534
+ }
535
+ function resolveBackgroundFaceAlpha(key, opacity) {
536
+ var alphaMap = {
537
+ left: 0.82,
538
+ right: 1,
539
+ top: 1.8,
540
+ middle: 0.82,
541
+ bottom: 1.28,
542
+ legend: 1
543
+ };
544
+ var ratio = alphaMap[key] || 1;
545
+ return Math.max(0, Math.min(1, opacity * ratio));
546
+ }
547
+ function applyBackgroundFaceAlphaToColorMap(colorMap, opacity) {
548
+ return Object.keys(colorMap || {}).reduce(function (result, key) {
549
+ result[key] = applyAlphaToColor(colorMap[key], resolveBackgroundFaceAlpha(key, opacity));
550
+ return result;
551
+ }, {});
552
+ }
553
+ function normalizeBackgroundColors(barBackground, item) {
554
+ if (Array.isArray(barBackground && barBackground.colors) && barBackground.colors.length > 0) {
555
+ return barBackground.colors;
556
+ }
557
+ if (Array.isArray(item && item.colors) && item.colors.length > 0) {
558
+ return item.colors;
559
+ }
560
+ return undefined;
561
+ }
502
562
 
503
563
  /**
504
564
  * 创建堆叠累加器。
@@ -627,13 +687,7 @@ function buildCustomBarSeries(_ref) {
627
687
  barGap = _ref.barGap,
628
688
  createRenderItem = _ref.createRenderItem,
629
689
  resolveColorMap = _ref.resolveColorMap;
630
- var barSeries = normalizedSeries.map(function (item, originalIndex) {
631
- return colors._objectSpread2(colors._objectSpread2({}, item), {}, {
632
- originalIndex: originalIndex
633
- });
634
- }).filter(function (item) {
635
- return item.kind === 'bar';
636
- });
690
+ var barSeries = collectBarSeries(normalizedSeries);
637
691
  var layout = createBarLayout(barSeries, barWidth, barGap);
638
692
  var barSeriesWithData = buildBarSeriesData(rawData, barSeries);
639
693
  return barSeriesWithData.map(function (item, index) {
@@ -662,6 +716,57 @@ function buildCustomBarSeries(_ref) {
662
716
  };
663
717
  });
664
718
  }
719
+ function buildBackgroundCustomBarSeries(_ref2) {
720
+ var rawData = _ref2.rawData,
721
+ normalizedSeries = _ref2.normalizedSeries,
722
+ barWidth = _ref2.barWidth,
723
+ barGap = _ref2.barGap,
724
+ _ref2$barBackground = _ref2.barBackground,
725
+ barBackground = _ref2$barBackground === void 0 ? {} : _ref2$barBackground,
726
+ createRenderItem = _ref2.createRenderItem,
727
+ resolveColorMap = _ref2.resolveColorMap;
728
+ if (!barBackground.show) {
729
+ return [];
730
+ }
731
+ var barSeries = collectBarSeries(normalizedSeries);
732
+ if (!barSeries.length) {
733
+ return [];
734
+ }
735
+ var layout = createBarLayout(barSeries, barWidth, barGap);
736
+ var backgroundSeriesData = createBackgroundSeriesData(rawData);
737
+ return pickBackgroundSlotSeries(barSeries).map(function (item) {
738
+ var slotKey = item.stack || "__slot_".concat(item.barSeriesIndex);
739
+ var slotIndex = layout.slotMap[slotKey];
740
+ var fallbackColor = resolveSeriesColor$1(item, item.originalIndex);
741
+ var palette = normalizeBackgroundColors(barBackground, item);
742
+ var baseColorMap = resolveColorMap ? resolveColorMap(palette, fallbackColor) : {
743
+ legend: fallbackColor
744
+ };
745
+ var backgroundColorMap = applyBackgroundFaceAlphaToColorMap(baseColorMap, barBackground.opacity);
746
+ return {
747
+ name: item.name,
748
+ type: 'custom',
749
+ stack: item.stack,
750
+ yAxisIndex: item.yAxisIndex || 0,
751
+ isBackground: true,
752
+ silent: true,
753
+ tooltip: {
754
+ show: false
755
+ },
756
+ renderItem: createRenderItem(layout, slotIndex, backgroundColorMap, colors._objectSpread2(colors._objectSpread2({}, item), {}, {
757
+ isBackground: true
758
+ })),
759
+ encode: {
760
+ x: 0
761
+ },
762
+ itemStyle: {
763
+ color: backgroundColorMap.legend || applyAlphaToColor(fallbackColor, barBackground.opacity)
764
+ },
765
+ data: backgroundSeriesData,
766
+ z: 0
767
+ };
768
+ });
769
+ }
665
770
 
666
771
  /**
667
772
  * 归一化 flat 模式下的 `barGap`。
@@ -725,6 +830,27 @@ function resolveFlatBarColors(item, index) {
725
830
  end: darkenColor(fallbackColor, 0.12)
726
831
  };
727
832
  }
833
+ function resolveFlatBackgroundColors(item, index, barBackground) {
834
+ var paletteSource = Array.isArray(barBackground.colors) && barBackground.colors.length > 0 ? {
835
+ colors: barBackground.colors
836
+ } : item;
837
+ var colorMap = resolveFlatBarColors(paletteSource, index);
838
+ return {
839
+ start: applyAlphaToColor(colorMap.start, barBackground.opacity),
840
+ middle: applyAlphaToColor(colorMap.middle, barBackground.opacity),
841
+ end: applyAlphaToColor(colorMap.end, barBackground.opacity)
842
+ };
843
+ }
844
+ function shouldEnableBackground(item, renderedStacks) {
845
+ if (!item.stack) {
846
+ return true;
847
+ }
848
+ if (renderedStacks.has(item.stack)) {
849
+ return false;
850
+ }
851
+ renderedStacks.add(item.stack);
852
+ return true;
853
+ }
728
854
 
729
855
  /**
730
856
  * 创建柱体纵向渐变。
@@ -756,9 +882,12 @@ function createFlatBarLineSeries(_ref) {
756
882
  var normalizedSeries = _ref.normalizedSeries,
757
883
  rawData = _ref.rawData,
758
884
  barWidth = _ref.barWidth,
759
- barGap = _ref.barGap;
885
+ barGap = _ref.barGap,
886
+ _ref$barBackground = _ref.barBackground,
887
+ barBackground = _ref$barBackground === void 0 ? {} : _ref$barBackground;
760
888
  var resolvedBarWidth = Number.isFinite(Number(barWidth)) ? Number(barWidth) : 18;
761
889
  var resolvedBarGap = toBarGapValue(barGap);
890
+ var renderedStacks = new Set();
762
891
  return normalizedSeries.map(function (item, index) {
763
892
  var isLine = item.kind === 'line';
764
893
  var color = resolveSeriesColor(item, index);
@@ -779,11 +908,18 @@ function createFlatBarLineSeries(_ref) {
779
908
  yAxisIndex: item.yAxisIndex
780
909
  });
781
910
  }
911
+ var showBackground = barBackground.show && shouldEnableBackground(item, renderedStacks);
912
+ var backgroundColors = resolveFlatBackgroundColors(item, index, barBackground);
782
913
  return colors._objectSpread2(colors._objectSpread2({}, baseSeries), {}, {
783
914
  stack: item.stack,
784
915
  barWidth: resolvedBarWidth,
785
- barGap: resolvedBarGap
786
- });
916
+ barGap: resolvedBarGap,
917
+ showBackground: showBackground
918
+ }, showBackground ? {
919
+ backgroundStyle: {
920
+ color: createBarGradient(backgroundColors)
921
+ }
922
+ } : {});
787
923
  });
788
924
  }
789
925
 
@@ -847,9 +983,63 @@ function createFaceGradient(x0, y0, x1, y1, startColor, endColor) {
847
983
  * 创建方柱渲染器。
848
984
  * 参考案例使用三块 polygon 拼接成立方体,而不是“正面 rect + 顶面/侧面”。
849
985
  */
850
- function createCubeRenderItem(layout, slotIndex, colorMap) {
986
+ function createCubeRenderItem(layout, slotIndex, colorMap, seriesItem) {
851
987
  return function renderItem(params, api) {
852
988
  var rowIndex = api.value(0);
989
+ var offsetX = getBarOffset(layout, slotIndex);
990
+ var centerPoint = api.coord([rowIndex, 0]);
991
+ var centerX = centerPoint[0] + offsetX;
992
+ var halfWidth = layout.barWidth / 2;
993
+ var offsetY = Math.tan(Math.PI / 9) * halfWidth;
994
+ var leftFaceGradient = createFaceGradient(0, 0, 0, 1, colorMap.left, colorMap.left);
995
+ var rightFaceGradient = createFaceGradient(0, 0, 0, 1, colorMap.right, colorMap.right);
996
+ var topFaceGradient = createFaceGradient(0, 0, 1, 0, colorMap.top, colorMap.top);
997
+ if (seriesItem && seriesItem.isBackground === true) {
998
+ var coordSys = params.coordSys || {};
999
+ var clipX = coordSys.x || 0;
1000
+ var _topY = coordSys.y || 0;
1001
+ var width = coordSys.width || 0;
1002
+ var _baseY = _topY + (coordSys.height || 0);
1003
+ var _topSurfaceY = _topY + Math.abs(offsetY - 1);
1004
+ return {
1005
+ type: 'group',
1006
+ clipPath: {
1007
+ type: 'rect',
1008
+ shape: {
1009
+ x: clipX,
1010
+ y: _topY,
1011
+ width: width,
1012
+ height: coordSys.height || 0
1013
+ }
1014
+ },
1015
+ children: [{
1016
+ type: 'polygon',
1017
+ shape: {
1018
+ points: [[centerX, _topSurfaceY + offsetY - 1], [centerX - halfWidth, _topSurfaceY], [centerX - halfWidth, _baseY - offsetY], [centerX, _baseY - 1]]
1019
+ },
1020
+ style: {
1021
+ fill: leftFaceGradient
1022
+ }
1023
+ }, {
1024
+ type: 'polygon',
1025
+ shape: {
1026
+ points: [[centerX, _topSurfaceY + offsetY - 1], [centerX + halfWidth, _topSurfaceY], [centerX + halfWidth, _baseY - offsetY], [centerX, _baseY - 1]]
1027
+ },
1028
+ style: {
1029
+ fill: rightFaceGradient
1030
+ }
1031
+ }, {
1032
+ type: 'polygon',
1033
+ shape: {
1034
+ points: [[centerX, _topSurfaceY + offsetY - 1], [centerX + halfWidth, _topSurfaceY], [centerX, _topSurfaceY - offsetY + 1], [centerX - halfWidth, _topSurfaceY]]
1035
+ },
1036
+ style: {
1037
+ fill: topFaceGradient
1038
+ },
1039
+ z2: 2
1040
+ }]
1041
+ };
1042
+ }
853
1043
  var endValue = api.value(1);
854
1044
  var baseValue = api.value(2);
855
1045
  var rawValue = api.value(3);
@@ -860,20 +1050,13 @@ function createCubeRenderItem(layout, slotIndex, colorMap) {
860
1050
  }
861
1051
  var endPoint = api.coord([rowIndex, endValue]);
862
1052
  var basePoint = api.coord([rowIndex, baseValue]);
863
- var offsetX = getBarOffset(layout, slotIndex);
864
- var centerX = endPoint[0] + offsetX;
865
1053
  var topY = endPoint[1];
866
1054
  var baseY = basePoint[1];
867
- var halfWidth = layout.barWidth / 2;
868
- var offsetY = Math.tan(Math.PI / 9) * halfWidth;
869
1055
  var isPositive = rawValue >= 0;
870
1056
  var connectorOverlap = stackStart ? 0 : Math.max(2, Math.round(offsetY));
871
1057
  var connectorCapOffset = stackEnd ? 0 : Math.min(2, offsetY * 0.45);
872
1058
  var connectBaseY = isPositive ? baseY + connectorOverlap : baseY - connectorOverlap;
873
1059
  var topSurfaceY = topY + connectorCapOffset;
874
- var leftFaceGradient = createFaceGradient(0, 0, 0, 1, colorMap.left, colorMap.left);
875
- var rightFaceGradient = createFaceGradient(0, 0, 0, 1, colorMap.right, colorMap.right);
876
- var topFaceGradient = createFaceGradient(0, 0, 1, 0, colorMap.top, colorMap.top);
877
1060
  return {
878
1061
  type: 'group',
879
1062
  children: [{
@@ -919,6 +1102,15 @@ function createCubeRenderItem(layout, slotIndex, colorMap) {
919
1102
  function createCubeBarLineOption(normalizedInput) {
920
1103
  var flatOption = createFlatBarLineOption(normalizedInput);
921
1104
  var flatSeries = createFlatBarLineSeries(normalizedInput);
1105
+ var backgroundSeries = buildBackgroundCustomBarSeries({
1106
+ rawData: normalizedInput.rawData,
1107
+ normalizedSeries: normalizedInput.normalizedSeries,
1108
+ barWidth: normalizedInput.barWidth,
1109
+ barGap: normalizedInput.barGap,
1110
+ barBackground: normalizedInput.barBackground,
1111
+ createRenderItem: createCubeRenderItem,
1112
+ resolveColorMap: resolveCubeColors
1113
+ });
922
1114
  var customBarSeries = buildCustomBarSeries({
923
1115
  rawData: normalizedInput.rawData,
924
1116
  normalizedSeries: normalizedInput.normalizedSeries,
@@ -937,7 +1129,7 @@ function createCubeBarLineOption(normalizedInput) {
937
1129
  return flatSeries[index];
938
1130
  });
939
1131
  return colors._objectSpread2(colors._objectSpread2({}, flatOption), {}, {
940
- series: series
1132
+ series: [].concat(colors._toConsumableArray(series), colors._toConsumableArray(backgroundSeries))
941
1133
  });
942
1134
  }
943
1135
 
@@ -961,6 +1153,20 @@ function createEllipsePolygon(cx, cy, rx, ry) {
961
1153
  }
962
1154
  return polygonPoints;
963
1155
  }
1156
+ function createEllipseArcPoints(cx, cy, rx, ry, startAngle, endAngle) {
1157
+ var points = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 12;
1158
+ var arcPoints = [];
1159
+ for (var index = 0; index <= points; index += 1) {
1160
+ var angle = startAngle + (endAngle - startAngle) * index / points;
1161
+ arcPoints.push([cx + Math.cos(angle) * rx, cy + Math.sin(angle) * ry]);
1162
+ }
1163
+ return arcPoints;
1164
+ }
1165
+ function createCylinderSidePolygon(cx, topCy, bottomCy, rx, ry) {
1166
+ var topLowerArc = createEllipseArcPoints(cx, topCy, rx, ry, Math.PI, 0);
1167
+ var bottomUpperArc = createEllipseArcPoints(cx, bottomCy, rx, ry, 0, -Math.PI);
1168
+ return [].concat(colors._toConsumableArray(topLowerArc), colors._toConsumableArray(bottomUpperArc));
1169
+ }
964
1170
 
965
1171
  /**
966
1172
  * 创建圆柱渲染器。
@@ -969,9 +1175,76 @@ function createEllipsePolygon(cx, cy, rx, ry) {
969
1175
  * 2. 主体用纵向渐变矩形模拟曲面;
970
1176
  * 3. 堆叠连接处保留底片,但不绘制深色描边和弧线,避免形成脏色带。
971
1177
  */
972
- function createCylinderRenderItem(layout, slotIndex, colorMap) {
1178
+ function createCylinderRenderItem(layout, slotIndex, colorMap, seriesItem) {
973
1179
  return function renderItem(params, api) {
974
1180
  var rowIndex = api.value(0);
1181
+ var offsetX = getBarOffset(layout, slotIndex);
1182
+ var centerPoint = api.coord([rowIndex, 0]);
1183
+ var centerX = centerPoint[0] + offsetX;
1184
+ var radiusX = layout.barWidth / 2;
1185
+ var radiusY = radiusX * 0.4;
1186
+ var createSideGradient = function createSideGradient(topColor, middleColor, bottomColor) {
1187
+ var opacity = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : CYLINDER_SIDE_OPACITY;
1188
+ return new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
1189
+ offset: 0,
1190
+ color: opacity === null ? topColor : applyAlphaToColor(topColor, opacity)
1191
+ }, {
1192
+ offset: 0.55,
1193
+ color: opacity === null ? middleColor : applyAlphaToColor(middleColor, opacity)
1194
+ }, {
1195
+ offset: 1,
1196
+ color: opacity === null ? bottomColor : applyAlphaToColor(bottomColor, opacity)
1197
+ }]);
1198
+ };
1199
+ if (seriesItem && seriesItem.isBackground === true) {
1200
+ var coordSys = params.coordSys || {};
1201
+ var clipX = coordSys.x || 0;
1202
+ var topY = coordSys.y || 0;
1203
+ var width = coordSys.width || 0;
1204
+ var height = coordSys.height || 0;
1205
+ var _topEllipseY = topY + radiusY;
1206
+ var bottomEllipseY = topY + height - radiusY;
1207
+ return {
1208
+ type: 'group',
1209
+ clipPath: {
1210
+ type: 'rect',
1211
+ shape: {
1212
+ x: clipX,
1213
+ y: topY,
1214
+ width: width,
1215
+ height: height
1216
+ }
1217
+ },
1218
+ children: [{
1219
+ type: 'polygon',
1220
+ shape: {
1221
+ points: createEllipsePolygon(centerX, bottomEllipseY, radiusX, radiusY)
1222
+ },
1223
+ style: {
1224
+ fill: colorMap.bottom
1225
+ },
1226
+ z: 0
1227
+ }, {
1228
+ type: 'polygon',
1229
+ shape: {
1230
+ points: createCylinderSidePolygon(centerX, _topEllipseY, bottomEllipseY, radiusX, radiusY)
1231
+ },
1232
+ style: {
1233
+ fill: createSideGradient(colorMap.middle, colorMap.middle, colorMap.bottom, null)
1234
+ },
1235
+ z: 1
1236
+ }, {
1237
+ type: 'polygon',
1238
+ shape: {
1239
+ points: createEllipsePolygon(centerX, _topEllipseY, radiusX, radiusY)
1240
+ },
1241
+ style: {
1242
+ fill: colorMap.top
1243
+ },
1244
+ z2: 2
1245
+ }]
1246
+ };
1247
+ }
975
1248
  var endValue = api.value(1);
976
1249
  var baseValue = api.value(2);
977
1250
  var rawValue = api.value(3);
@@ -982,10 +1255,6 @@ function createCylinderRenderItem(layout, slotIndex, colorMap) {
982
1255
  }
983
1256
  var endPoint = api.coord([rowIndex, endValue]);
984
1257
  var basePoint = api.coord([rowIndex, baseValue]);
985
- var offsetX = getBarOffset(layout, slotIndex);
986
- var centerX = endPoint[0] + offsetX;
987
- var radiusX = layout.barWidth / 2;
988
- var radiusY = radiusX * 0.4;
989
1258
  var isPositive = rawValue >= 0;
990
1259
  var barHeight = Math.abs(endPoint[1] - basePoint[1]);
991
1260
  var visibleEllipseY = endPoint[1];
@@ -1000,16 +1269,7 @@ function createCylinderRenderItem(layout, slotIndex, colorMap) {
1000
1269
  var gradientTopColor = isPositive ? colorMap.middle : darkenColor(colorMap.bottom, 0.05);
1001
1270
  var gradientMiddleColor = colorMap.middle;
1002
1271
  var gradientBottomColor = isPositive ? colorMap.bottom : colorMap.middle;
1003
- var sideGradient = new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
1004
- offset: 0,
1005
- color: applyAlphaToColor(gradientTopColor, CYLINDER_SIDE_OPACITY)
1006
- }, {
1007
- offset: 0.55,
1008
- color: applyAlphaToColor(gradientMiddleColor, CYLINDER_SIDE_OPACITY)
1009
- }, {
1010
- offset: 1,
1011
- color: applyAlphaToColor(gradientBottomColor, CYLINDER_SIDE_OPACITY)
1012
- }]);
1272
+ var sideGradient = createSideGradient(gradientTopColor, gradientMiddleColor, gradientBottomColor);
1013
1273
  return {
1014
1274
  type: 'group',
1015
1275
  children: [].concat(colors._toConsumableArray(showBottomPlate ? [{
@@ -1056,6 +1316,15 @@ function createCylinderRenderItem(layout, slotIndex, colorMap) {
1056
1316
  function createCylinderBarLineOption(normalizedInput) {
1057
1317
  var flatOption = createFlatBarLineOption(normalizedInput);
1058
1318
  var flatSeries = createFlatBarLineSeries(normalizedInput);
1319
+ var backgroundSeries = buildBackgroundCustomBarSeries({
1320
+ rawData: normalizedInput.rawData,
1321
+ normalizedSeries: normalizedInput.normalizedSeries,
1322
+ barWidth: normalizedInput.barWidth,
1323
+ barGap: normalizedInput.barGap,
1324
+ barBackground: normalizedInput.barBackground,
1325
+ createRenderItem: createCylinderRenderItem,
1326
+ resolveColorMap: resolveCylinderColors
1327
+ });
1059
1328
  var customBarSeries = buildCustomBarSeries({
1060
1329
  rawData: normalizedInput.rawData,
1061
1330
  normalizedSeries: normalizedInput.normalizedSeries,
@@ -1074,13 +1343,18 @@ function createCylinderBarLineOption(normalizedInput) {
1074
1343
  return flatSeries[index];
1075
1344
  });
1076
1345
  return colors._objectSpread2(colors._objectSpread2({}, flatOption), {}, {
1077
- series: series
1346
+ series: [].concat(colors._toConsumableArray(series), colors._toConsumableArray(backgroundSeries))
1078
1347
  });
1079
1348
  }
1080
1349
 
1081
1350
  var DEFAULT_VARIANT = 'flat';
1082
1351
  var DEFAULT_X_AXIS_SCROLL_VISIBLE_COUNT = 8;
1083
1352
  var DEFAULT_X_AXIS_SCROLL_GRID_BOTTOM = 56;
1353
+ var DEFAULT_BAR_BACKGROUND = {
1354
+ show: false,
1355
+ colors: [],
1356
+ opacity: 1
1357
+ };
1084
1358
  var BAR_LINE_PUBLIC_VARIANTS = ['flat', 'cylinder', 'cube'];
1085
1359
 
1086
1360
  // 公开 variant 能力在此处收口:只允许 flat / cylinder / cube。
@@ -1164,6 +1438,21 @@ function normalizeXAxisScrollConfig() {
1164
1438
  };
1165
1439
  }
1166
1440
 
1441
+ /**
1442
+ * 归一化柱形背景配置。
1443
+ * 这里统一收敛开关、颜色数量和透明度范围,避免变体层重复兜底。
1444
+ */
1445
+ function normalizeBarBackgroundConfig() {
1446
+ var barBackground = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1447
+ var config = barBackground && colors._typeof(barBackground) === 'object' ? barBackground : {};
1448
+ var opacity = Number(config.opacity);
1449
+ return colors._objectSpread2(colors._objectSpread2({}, DEFAULT_BAR_BACKGROUND), {}, {
1450
+ show: config.show === true,
1451
+ colors: Array.isArray(config.colors) ? config.colors.filter(Boolean).slice(0, 3) : [],
1452
+ opacity: Number.isFinite(opacity) ? Math.max(0, Math.min(1, opacity)) : 1
1453
+ });
1454
+ }
1455
+
1167
1456
  /**
1168
1457
  * 根据横轴类目数量生成 ECharts dataZoom。
1169
1458
  * 默认从末尾向前取 `visibleCount` 个类目,满足“最新数据优先展示”的看板诉求。
@@ -1234,6 +1523,7 @@ function buildBarLineOption() {
1234
1523
  variant = _ref$variant === void 0 ? 'flat' : _ref$variant,
1235
1524
  barWidth = _ref.barWidth,
1236
1525
  barGap = _ref.barGap,
1526
+ barBackground = _ref.barBackground,
1237
1527
  xAxisScroll = _ref.xAxisScroll,
1238
1528
  customOption = _ref.customOption;
1239
1529
  var normalizedInput = normalizeBarLineInput({
@@ -1245,10 +1535,12 @@ function buildBarLineOption() {
1245
1535
  var presetOption = getBarLinePreset(preset);
1246
1536
  var resolvedVariant = resolveVariantName(variant);
1247
1537
  var createVariantOption = variantFactory[resolvedVariant] || variantFactory[DEFAULT_VARIANT];
1538
+ var normalizedBarBackground = normalizeBarBackgroundConfig(barBackground);
1248
1539
  var variantOption = createVariantOption(colors._objectSpread2(colors._objectSpread2({}, normalizedInput), {}, {
1249
1540
  includeXAxis: false,
1250
1541
  barWidth: barWidth,
1251
- barGap: barGap
1542
+ barGap: barGap,
1543
+ barBackground: normalizedBarBackground
1252
1544
  }));
1253
1545
  var xAxisScrollOption = createXAxisScrollOption(normalizedInput.categories, xAxisScroll);
1254
1546
  return colors.mergeChartOption(colors.mergeChartOption(colors.mergeChartOption(baseOption, presetOption, variantOption), xAxisScrollOption), customOption);
@@ -1350,6 +1642,17 @@ var script = {
1350
1642
  type: [Number, String],
1351
1643
  "default": 8
1352
1644
  },
1645
+ /**
1646
+ * 柱形背景配置。
1647
+ * 仅对支持背景柱的柱系列生效,builder 会负责归一化 `show/colors/opacity`
1648
+ * 并交由具体变体决定最终渲染策略。
1649
+ */
1650
+ barBackground: {
1651
+ type: Object,
1652
+ "default": function _default() {
1653
+ return {};
1654
+ }
1655
+ },
1353
1656
  /**
1354
1657
  * 额外透传给 ECharts option 的自定义配置。
1355
1658
  * 会在 base / preset / variant option 合并完成后再覆盖。
@@ -1424,6 +1727,7 @@ var script = {
1424
1727
  preset: this.preset,
1425
1728
  barWidth: this.barWidth,
1426
1729
  barGap: this.barGap,
1730
+ barBackground: this.barBackground,
1427
1731
  xAxisScroll: this.xAxisScroll,
1428
1732
  customOption: this.customOption
1429
1733
  });
@@ -1431,7 +1735,7 @@ var script = {
1431
1735
  }
1432
1736
  };
1433
1737
 
1434
- var css_248z = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
1738
+ var css_248z = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
1435
1739
  withInstall.styleInject(css_248z);
1436
1740
 
1437
1741
  /* script */
@@ -1465,7 +1769,7 @@ __vue_render__._withStripped = true;
1465
1769
  /* style */
1466
1770
  var __vue_inject_styles__ = undefined;
1467
1771
  /* scoped */
1468
- var __vue_scope_id__ = "data-v-0c9a6292";
1772
+ var __vue_scope_id__ = "data-v-4e3be95d";
1469
1773
  /* module identifier */
1470
1774
  var __vue_module_identifier__ = undefined;
1471
1775
  /* functional template */
package/lib/index.js CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  require('../theme-chalk/index.css');
6
6
  var withInstall = require('./with-install-4304a8ea.js');
7
- var index$1 = require('./index-cc49894a.js');
7
+ var index$1 = require('./index-3d9f6fe7.js');
8
8
  var index$2 = require('./index-a0ecafa1.js');
9
9
  var index$3 = require('./index-6039f724.js');
10
10
  require('echarts/core');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xq-labs/data-ui-v2",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "main": "lib/index.js",
5
5
  "module": "es/index.js",
6
6
  "style": "theme-chalk/index.css",