@xq-labs/data-ui-v2 0.1.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.
@@ -0,0 +1,1364 @@
1
+ 'use strict';
2
+
3
+ var echarts = require('echarts/core');
4
+ var charts = require('echarts/charts');
5
+ var components = require('echarts/components');
6
+ var renderers = require('echarts/renderers');
7
+ var withInstall = require('./with-install-6ce12163.js');
8
+ var colors = require('./colors-55265c91.js');
9
+
10
+ function _interopNamespaceDefault(e) {
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var echarts__namespace = /*#__PURE__*/_interopNamespaceDefault(echarts);
28
+
29
+ var DEFAULT_SERIES = {
30
+ key: 'value',
31
+ name: '数值',
32
+ kind: 'bar',
33
+ stack: '',
34
+ yAxisIndex: 0,
35
+ colors: []
36
+ };
37
+
38
+ /**
39
+ * 归一化系列类型。
40
+ * 当前对外仅识别 `bar` / `line`,其他值全部回退为 `bar`。
41
+ */
42
+ function normalizeKind(kind) {
43
+ return kind === 'line' ? 'line' : 'bar';
44
+ }
45
+
46
+ /**
47
+ * 归一化系列所属的 Y 轴索引。
48
+ * 只接受大于等于 0 的整数,异常值统一回退到主轴。
49
+ */
50
+ function normalizeYAxisIndex(yAxisIndex) {
51
+ return Number.isInteger(yAxisIndex) && yAxisIndex >= 0 ? yAxisIndex : 0;
52
+ }
53
+
54
+ /**
55
+ * 归一化颜色配置。
56
+ * 保证后续构建层总能拿到数组结构,避免额外分支判断。
57
+ */
58
+ function normalizeColors(colors) {
59
+ return Array.isArray(colors) ? colors : [];
60
+ }
61
+
62
+ /**
63
+ * 统一归一化柱线图输入。
64
+ * 输出结果固定为:
65
+ * - categories:横轴类目数组
66
+ * - normalizedSeries:标准化后的系列定义
67
+ * - rawData:原始数据源
68
+ */
69
+ function normalizeBarLineInput(_ref) {
70
+ var data = _ref.data,
71
+ _ref$xAxisKey = _ref.xAxisKey,
72
+ xAxisKey = _ref$xAxisKey === void 0 ? 'name' : _ref$xAxisKey,
73
+ series = _ref.series;
74
+ // 对外输入在这里统一收口,后续 builder/variant 只处理这一种规范结构。
75
+ var rawData = Array.isArray(data) ? data : [];
76
+ var sourceSeries = Array.isArray(series) && series.length > 0 ? series : [DEFAULT_SERIES];
77
+ return {
78
+ categories: rawData.map(function (item) {
79
+ return item[xAxisKey];
80
+ }),
81
+ normalizedSeries: sourceSeries.map(function (item) {
82
+ return colors._objectSpread2(colors._objectSpread2(colors._objectSpread2({}, DEFAULT_SERIES), item), {}, {
83
+ kind: normalizeKind(item.kind),
84
+ stack: typeof item.stack === 'string' ? item.stack : '',
85
+ yAxisIndex: normalizeYAxisIndex(item.yAxisIndex),
86
+ colors: normalizeColors(item.colors)
87
+ });
88
+ }),
89
+ rawData: rawData
90
+ };
91
+ }
92
+
93
+ var BAR_LINE_PRESETS = {
94
+ trend: {
95
+ legend: {
96
+ show: false
97
+ },
98
+ tooltip: {
99
+ trigger: 'axis',
100
+ axisPointer: {
101
+ type: 'line'
102
+ }
103
+ }
104
+ },
105
+ compare: {
106
+ legend: {
107
+ show: true,
108
+ bottom: 0
109
+ }
110
+ },
111
+ rank: {
112
+ xAxis: {
113
+ axisLabel: {
114
+ interval: 0
115
+ }
116
+ }
117
+ }
118
+ };
119
+
120
+ /**
121
+ * 获取柱线图预设配置。
122
+ * 未命中时统一回退到 `compare`,保证预设读取稳定。
123
+ */
124
+ function getBarLinePreset() {
125
+ var preset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'compare';
126
+ return BAR_LINE_PRESETS[preset] || BAR_LINE_PRESETS.compare;
127
+ }
128
+
129
+ var CUBE_LEFT_FACE_OPACITY = 0.488;
130
+ var CUBE_RIGHT_FACE_OPACITY = 0.695;
131
+ var CYLINDER_TOP_HSL_SHIFT = {
132
+ h: 3.051375194602999,
133
+ s: -0.018373071528752,
134
+ l: 0.1235294117647059
135
+ };
136
+ var CYLINDER_BOTTOM_HSL_SHIFT = {
137
+ h: -33.97606382978725,
138
+ s: 0.0800133022946456,
139
+ l: -0.0764705882352941
140
+ };
141
+
142
+ /**
143
+ * 解析单个系列的主色。
144
+ * 自定义柱体默认只读取第一项颜色;未传时按原始系列顺序回退到组件色板。
145
+ */
146
+ function resolveSeriesColor$1(item, index) {
147
+ if (Array.isArray(item.colors) && item.colors.length > 0) {
148
+ return item.colors[0];
149
+ }
150
+ return colors.DEFAULT_COLORS[index % colors.DEFAULT_COLORS.length];
151
+ }
152
+
153
+ /**
154
+ * 归一化颜色入参。
155
+ * 对外约定支持 1~3 个颜色值,空值会被过滤。
156
+ */
157
+ function normalizeColorInput(colors, fallbackColor) {
158
+ var colorList = Array.isArray(colors) ? colors.filter(Boolean) : [];
159
+ if (!colorList.length) {
160
+ return [fallbackColor];
161
+ }
162
+ return colorList.slice(0, 3);
163
+ }
164
+
165
+ /**
166
+ * 将十六进制颜色统一转成 `#RRGGBB`。
167
+ */
168
+ function normalizeHex(color) {
169
+ if (typeof color !== 'string') {
170
+ return null;
171
+ }
172
+ var trimmedColor = color.trim();
173
+ if (!/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(trimmedColor)) {
174
+ return null;
175
+ }
176
+ if (trimmedColor.length === 4) {
177
+ return "#".concat(trimmedColor[1]).concat(trimmedColor[1]).concat(trimmedColor[2]).concat(trimmedColor[2]).concat(trimmedColor[3]).concat(trimmedColor[3]).toUpperCase();
178
+ }
179
+ return trimmedColor.toUpperCase();
180
+ }
181
+
182
+ /**
183
+ * 十六进制颜色转 RGB 对象。
184
+ */
185
+ function hexToRgb(color) {
186
+ var hexColor = normalizeHex(color);
187
+ if (!hexColor) {
188
+ return null;
189
+ }
190
+ return {
191
+ r: parseInt(hexColor.slice(1, 3), 16),
192
+ g: parseInt(hexColor.slice(3, 5), 16),
193
+ b: parseInt(hexColor.slice(5, 7), 16)
194
+ };
195
+ }
196
+
197
+ /**
198
+ * RGB 对象转十六进制颜色。
199
+ */
200
+ function rgbToHex(rgb) {
201
+ var toHex = function toHex(value) {
202
+ var nextValue = Math.max(0, Math.min(255, Math.round(value)));
203
+ return nextValue.toString(16).padStart(2, '0');
204
+ };
205
+ return "#".concat(toHex(rgb.r)).concat(toHex(rgb.g)).concat(toHex(rgb.b));
206
+ }
207
+
208
+ /**
209
+ * 为颜色补充透明度,统一转成 `rgba(...)`。
210
+ * 这样图形层只关心“用什么透明度”,不需要自己解析颜色格式。
211
+ */
212
+ function applyAlphaToColor(color) {
213
+ var alpha = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
214
+ var parsedAlpha = Number(alpha);
215
+ var normalizedAlpha = Number.isFinite(parsedAlpha) ? Math.max(0, Math.min(1, parsedAlpha)) : 1;
216
+ var rgb = hexToRgb(color);
217
+ if (rgb) {
218
+ return "rgba(".concat(rgb.r, ", ").concat(rgb.g, ", ").concat(rgb.b, ", ").concat(normalizedAlpha, ")");
219
+ }
220
+ if (typeof color !== 'string') {
221
+ return color;
222
+ }
223
+ var rgbMatch = color.trim().match(/^rgba?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)(?:\s*,\s*\d+(?:\.\d+)?)?\s*\)$/i);
224
+ if (!rgbMatch) {
225
+ return color;
226
+ }
227
+ return "rgba(".concat(Number(rgbMatch[1]), ", ").concat(Number(rgbMatch[2]), ", ").concat(Number(rgbMatch[3]), ", ").concat(normalizedAlpha, ")");
228
+ }
229
+
230
+ /**
231
+ * 将主色按透明度叠加到白色背景上。
232
+ * 方柱参考图中的侧面色不是单纯加深,而是顶面色以不同透明度叠白后的结果。
233
+ */
234
+ function blendColorWithWhite(color, opacity) {
235
+ var rgb = hexToRgb(color);
236
+ if (!rgb) {
237
+ return color;
238
+ }
239
+ var white = 255;
240
+ return rgbToHex({
241
+ r: rgb.r * opacity + white * (1 - opacity),
242
+ g: rgb.g * opacity + white * (1 - opacity),
243
+ b: rgb.b * opacity + white * (1 - opacity)
244
+ });
245
+ }
246
+
247
+ /**
248
+ * RGB 转 HSL。
249
+ * 用于圆柱单色输入时按参考色关系派生顶面和底部色。
250
+ */
251
+ function rgbToHsl(rgb) {
252
+ var red = rgb.r / 255;
253
+ var green = rgb.g / 255;
254
+ var blue = rgb.b / 255;
255
+ var max = Math.max(red, green, blue);
256
+ var min = Math.min(red, green, blue);
257
+ var lightness = (max + min) / 2;
258
+ var delta = max - min;
259
+ var hue = 0;
260
+ var saturation = 0;
261
+ if (delta !== 0) {
262
+ saturation = lightness > 0.5 ? delta / (2 - max - min) : delta / (max + min);
263
+ switch (max) {
264
+ case red:
265
+ hue = (green - blue) / delta + (green < blue ? 6 : 0);
266
+ break;
267
+ case green:
268
+ hue = (blue - red) / delta + 2;
269
+ break;
270
+ default:
271
+ hue = (red - green) / delta + 4;
272
+ break;
273
+ }
274
+ hue *= 60;
275
+ }
276
+ return {
277
+ h: hue,
278
+ s: saturation,
279
+ l: lightness
280
+ };
281
+ }
282
+
283
+ /**
284
+ * HSL 转 RGB。
285
+ */
286
+ function hslToRgb(hsl) {
287
+ var normalizedHue = (hsl.h % 360 + 360) % 360 / 360;
288
+ var saturation = Math.max(0, Math.min(1, hsl.s));
289
+ var lightness = Math.max(0, Math.min(1, hsl.l));
290
+ if (saturation === 0) {
291
+ var value = lightness * 255;
292
+ return {
293
+ r: value,
294
+ g: value,
295
+ b: value
296
+ };
297
+ }
298
+ var hueToRgb = function hueToRgb(p, q, t) {
299
+ var next = t;
300
+ if (next < 0) next += 1;
301
+ if (next > 1) next -= 1;
302
+ if (next < 1 / 6) return p + (q - p) * 6 * next;
303
+ if (next < 1 / 2) return q;
304
+ if (next < 2 / 3) return p + (q - p) * (2 / 3 - next) * 6;
305
+ return p;
306
+ };
307
+ var q = lightness < 0.5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation;
308
+ var p = 2 * lightness - q;
309
+ return {
310
+ r: hueToRgb(p, q, normalizedHue + 1 / 3) * 255,
311
+ g: hueToRgb(p, q, normalizedHue) * 255,
312
+ b: hueToRgb(p, q, normalizedHue - 1 / 3) * 255
313
+ };
314
+ }
315
+
316
+ /**
317
+ * 按 HSL 偏移规则生成派生色。
318
+ */
319
+ function shiftColorByHsl(color, shift) {
320
+ var rgb = hexToRgb(color);
321
+ if (!rgb) {
322
+ return color;
323
+ }
324
+ var hsl = rgbToHsl(rgb);
325
+ return rgbToHex(hslToRgb({
326
+ h: hsl.h + shift.h,
327
+ s: hsl.s + shift.s,
328
+ l: hsl.l + shift.l
329
+ }));
330
+ }
331
+
332
+ /**
333
+ * 按比例调整颜色亮度。
334
+ * `ratio > 0` 变亮,`ratio < 0` 变暗。
335
+ */
336
+ function adjustColor(color, ratio) {
337
+ var rgb = hexToRgb(color);
338
+ if (!rgb) {
339
+ return color;
340
+ }
341
+ var nextColor = colors._objectSpread2({}, rgb);
342
+ if (ratio >= 0) {
343
+ nextColor.r = rgb.r + (255 - rgb.r) * ratio;
344
+ nextColor.g = rgb.g + (255 - rgb.g) * ratio;
345
+ nextColor.b = rgb.b + (255 - rgb.b) * ratio;
346
+ } else {
347
+ nextColor.r = rgb.r * (1 + ratio);
348
+ nextColor.g = rgb.g * (1 + ratio);
349
+ nextColor.b = rgb.b * (1 + ratio);
350
+ }
351
+ return rgbToHex(nextColor);
352
+ }
353
+
354
+ /**
355
+ * 生成更亮的颜色。
356
+ */
357
+ function lightenColor(color) {
358
+ var ratio = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.2;
359
+ return adjustColor(color, ratio);
360
+ }
361
+
362
+ /**
363
+ * 生成更暗的颜色。
364
+ */
365
+ function darkenColor(color) {
366
+ var ratio = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.16;
367
+ return adjustColor(color, ratio * -1);
368
+ }
369
+
370
+ /**
371
+ * 解析圆柱视觉所需颜色。
372
+ * - `top`:顶部椭圆
373
+ * - `middle`:柱体主体
374
+ * - `bottom`:底部暗面
375
+ * - `legend`:图例/tooltip 颜色
376
+ */
377
+ function resolveCylinderColors(colors, fallbackColor) {
378
+ var palette = normalizeColorInput(colors, fallbackColor);
379
+ if (palette.length === 1) {
380
+ return {
381
+ top: shiftColorByHsl(palette[0], CYLINDER_TOP_HSL_SHIFT),
382
+ middle: palette[0],
383
+ bottom: shiftColorByHsl(palette[0], CYLINDER_BOTTOM_HSL_SHIFT),
384
+ legend: palette[0]
385
+ };
386
+ }
387
+ if (palette.length === 2) {
388
+ return {
389
+ top: palette[0],
390
+ middle: palette[1],
391
+ bottom: darkenColor(palette[1], 0.15),
392
+ legend: palette[1]
393
+ };
394
+ }
395
+ return {
396
+ top: palette[0],
397
+ middle: palette[1],
398
+ bottom: palette[2],
399
+ legend: palette[1]
400
+ };
401
+ }
402
+
403
+ /**
404
+ * 解析方柱视觉所需颜色。
405
+ * - `left`:左侧暗面
406
+ * - `right`:右侧主面
407
+ * - `top`:顶面高光
408
+ * - `legend`:图例/tooltip 颜色
409
+ */
410
+ function resolveCubeColors(colors, fallbackColor) {
411
+ var palette = normalizeColorInput(colors, fallbackColor);
412
+ if (palette.length === 1) {
413
+ return {
414
+ left: blendColorWithWhite(palette[0], CUBE_LEFT_FACE_OPACITY),
415
+ right: blendColorWithWhite(palette[0], CUBE_RIGHT_FACE_OPACITY),
416
+ top: palette[0],
417
+ legend: palette[0]
418
+ };
419
+ }
420
+ if (palette.length === 2) {
421
+ return {
422
+ left: palette[0],
423
+ right: palette[1],
424
+ top: lightenColor(palette[0], 0.4),
425
+ legend: palette[1]
426
+ };
427
+ }
428
+ return {
429
+ left: palette[0],
430
+ right: palette[1],
431
+ top: palette[2],
432
+ legend: palette[1]
433
+ };
434
+ }
435
+
436
+ /**
437
+ * 将输入值安全转成数字。
438
+ * 无法转换时返回 `null`,由上层决定默认值。
439
+ */
440
+ function toNumber(value) {
441
+ var numberValue = Number(value);
442
+ return Number.isFinite(numberValue) ? numberValue : null;
443
+ }
444
+
445
+ /**
446
+ * 解析柱体宽度。
447
+ */
448
+ function resolveBarWidth(barWidth) {
449
+ var resolvedBarWidth = toNumber(barWidth);
450
+ return resolvedBarWidth === null ? 18 : resolvedBarWidth;
451
+ }
452
+
453
+ /**
454
+ * 解析柱间距比例。
455
+ * 保持当前组件对外语义:数字或百分比字符串最终都按比例解释。
456
+ */
457
+ function resolveBarGapRatio(barGap) {
458
+ if (typeof barGap === 'string') {
459
+ var trimmedBarGap = barGap.trim();
460
+ if (trimmedBarGap.endsWith('%')) {
461
+ var percentValue = toNumber(trimmedBarGap.slice(0, -1));
462
+ if (percentValue !== null) {
463
+ return percentValue / 100;
464
+ }
465
+ }
466
+ var numericValue = toNumber(trimmedBarGap);
467
+ if (numericValue !== null) {
468
+ return numericValue / 100;
469
+ }
470
+ return 0.3;
471
+ }
472
+ var numericBarGap = toNumber(barGap);
473
+ if (numericBarGap !== null) {
474
+ return numericBarGap / 100;
475
+ }
476
+ return 0.3;
477
+ }
478
+
479
+ /**
480
+ * 计算自定义柱体布局。
481
+ * 同一 stack 共用一个槽位,保证堆叠段在水平方向严格对齐。
482
+ */
483
+ function createBarLayout(barSeries, barWidth, barGap) {
484
+ var resolvedBarWidth = resolveBarWidth(barWidth);
485
+ var resolvedBarGap = resolvedBarWidth * resolveBarGapRatio(barGap);
486
+ var slotMap = {};
487
+ var slotCount = 0;
488
+ barSeries.forEach(function (item, index) {
489
+ var slotKey = item.stack || "__slot_".concat(index);
490
+ if (slotMap[slotKey] === undefined) {
491
+ slotMap[slotKey] = slotCount;
492
+ slotCount += 1;
493
+ }
494
+ });
495
+ return {
496
+ slotMap: slotMap,
497
+ slotCount: slotCount || 1,
498
+ barWidth: resolvedBarWidth,
499
+ barGap: resolvedBarGap
500
+ };
501
+ }
502
+
503
+ /**
504
+ * 创建堆叠累加器。
505
+ * 正值和负值分别累加,避免双向数据互相污染基线。
506
+ */
507
+ function createStackAccumulator(dataLength) {
508
+ return {
509
+ positive: new Array(dataLength).fill(0),
510
+ negative: new Array(dataLength).fill(0)
511
+ };
512
+ }
513
+
514
+ /**
515
+ * 为每个 stack 构建边界映射。
516
+ * 该映射用于判断当前段是否是堆叠起点/终点。
517
+ */
518
+ function buildStackBoundaryMap(rawData, barSeries) {
519
+ var stackBoundaryMap = {};
520
+ barSeries.forEach(function (seriesItem, seriesIndex) {
521
+ if (!seriesItem.stack) {
522
+ return;
523
+ }
524
+ rawData.forEach(function (row, rowIndex) {
525
+ var rawValue = toNumber(row[seriesItem.key]) || 0;
526
+ if (!rawValue) {
527
+ return;
528
+ }
529
+ var stackKey = "".concat(seriesItem.stack, "__").concat(rowIndex);
530
+ var direction = rawValue > 0 ? 'positive' : 'negative';
531
+ if (!stackBoundaryMap[stackKey]) {
532
+ stackBoundaryMap[stackKey] = {
533
+ positive: [],
534
+ negative: []
535
+ };
536
+ }
537
+ stackBoundaryMap[stackKey][direction].push(seriesIndex);
538
+ });
539
+ });
540
+ return stackBoundaryMap;
541
+ }
542
+
543
+ /**
544
+ * 读取当前堆叠段元信息。
545
+ * `stackStart/stackEnd` 会直接透传给 `renderItem`,决定连接面与顶面绘制策略。
546
+ */
547
+ function getStackSegmentMeta(seriesItem, seriesIndex, rowIndex, rawValue, stackBoundaryMap) {
548
+ if (!seriesItem.stack || !rawValue) {
549
+ return {
550
+ isStacked: false,
551
+ stackStart: true,
552
+ stackEnd: true
553
+ };
554
+ }
555
+ var stackKey = "".concat(seriesItem.stack, "__").concat(rowIndex);
556
+ var direction = rawValue > 0 ? 'positive' : 'negative';
557
+ var stackIndexList = stackBoundaryMap[stackKey] && stackBoundaryMap[stackKey][direction] || [];
558
+ return {
559
+ isStacked: stackIndexList.length > 1,
560
+ stackStart: stackIndexList[0] === seriesIndex,
561
+ stackEnd: stackIndexList[stackIndexList.length - 1] === seriesIndex
562
+ };
563
+ }
564
+
565
+ /**
566
+ * 将 bar 系列转换为 custom series 需要的数据协议。
567
+ * `value` 结构:
568
+ * `[类目索引, 结束值, 起点值, 原始值, 是否起点, 是否终点]`
569
+ */
570
+ function buildBarSeriesData(rawData, barSeries) {
571
+ var stackAccumulatorMap = {};
572
+ var stackBoundaryMap = buildStackBoundaryMap(rawData, barSeries);
573
+ return barSeries.map(function (seriesItem, seriesIndex) {
574
+ return colors._objectSpread2(colors._objectSpread2({}, seriesItem), {}, {
575
+ data: rawData.map(function (row, rowIndex) {
576
+ var rawValue = toNumber(row[seriesItem.key]) || 0;
577
+ var stackMeta = getStackSegmentMeta(seriesItem, seriesIndex, rowIndex, rawValue, stackBoundaryMap);
578
+ var baseValue = 0;
579
+ var endValue = rawValue;
580
+ if (seriesItem.stack) {
581
+ if (!stackAccumulatorMap[seriesItem.stack]) {
582
+ stackAccumulatorMap[seriesItem.stack] = createStackAccumulator(rawData.length);
583
+ }
584
+ var accumulator = stackAccumulatorMap[seriesItem.stack];
585
+ if (rawValue >= 0) {
586
+ baseValue = accumulator.positive[rowIndex];
587
+ endValue = baseValue + rawValue;
588
+ accumulator.positive[rowIndex] = endValue;
589
+ } else {
590
+ baseValue = accumulator.negative[rowIndex];
591
+ endValue = baseValue + rawValue;
592
+ accumulator.negative[rowIndex] = endValue;
593
+ }
594
+ }
595
+ return {
596
+ value: [rowIndex, endValue, baseValue, rawValue, stackMeta.stackStart ? 1 : 0, stackMeta.stackEnd ? 1 : 0],
597
+ rawValue: rawValue,
598
+ baseValue: baseValue,
599
+ stackStart: stackMeta.stackStart,
600
+ stackEnd: stackMeta.stackEnd,
601
+ isStacked: stackMeta.isStacked
602
+ };
603
+ })
604
+ });
605
+ });
606
+ }
607
+
608
+ /**
609
+ * 计算槽位相对类目中心的偏移量。
610
+ */
611
+ function getBarOffset(layout, slotIndex) {
612
+ if (layout.slotCount <= 1) {
613
+ return 0;
614
+ }
615
+ var totalWidth = layout.slotCount * layout.barWidth + (layout.slotCount - 1) * layout.barGap;
616
+ return -totalWidth / 2 + slotIndex * (layout.barWidth + layout.barGap) + layout.barWidth / 2;
617
+ }
618
+
619
+ /**
620
+ * 统一构建自定义柱图系列。
621
+ * 颜色映射和 renderItem 细节由具体变体自行提供。
622
+ */
623
+ function buildCustomBarSeries(_ref) {
624
+ var rawData = _ref.rawData,
625
+ normalizedSeries = _ref.normalizedSeries,
626
+ barWidth = _ref.barWidth,
627
+ barGap = _ref.barGap,
628
+ createRenderItem = _ref.createRenderItem,
629
+ 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
+ });
637
+ var layout = createBarLayout(barSeries, barWidth, barGap);
638
+ var barSeriesWithData = buildBarSeriesData(rawData, barSeries);
639
+ return barSeriesWithData.map(function (item, index) {
640
+ var slotKey = item.stack || "__slot_".concat(index);
641
+ var slotIndex = layout.slotMap[slotKey];
642
+ var fallbackColor = resolveSeriesColor$1(item, item.originalIndex);
643
+ var colorMap = resolveColorMap ? resolveColorMap(item.colors, fallbackColor) : {
644
+ legend: fallbackColor
645
+ };
646
+ return {
647
+ name: item.name,
648
+ type: 'custom',
649
+ stack: item.stack,
650
+ yAxisIndex: item.yAxisIndex || 0,
651
+ renderItem: createRenderItem(layout, slotIndex, colorMap, item),
652
+ encode: {
653
+ x: 0,
654
+ y: 1,
655
+ tooltip: 3
656
+ },
657
+ itemStyle: {
658
+ color: colorMap.legend || fallbackColor
659
+ },
660
+ data: item.data,
661
+ z: index + 1
662
+ };
663
+ });
664
+ }
665
+
666
+ /**
667
+ * 归一化 flat 模式下的 `barGap`。
668
+ * 数字输入统一转换为 ECharts 百分比字符串,字符串则原样透传。
669
+ */
670
+ function toBarGapValue(barGap) {
671
+ // flat 模式下透传到 echarts barGap:数字按百分比解释,字符串原样保留。
672
+ if (typeof barGap === 'string') {
673
+ return barGap;
674
+ }
675
+ if (Number.isFinite(Number(barGap))) {
676
+ return "".concat(Number(barGap), "%");
677
+ }
678
+ return '30%';
679
+ }
680
+
681
+ /**
682
+ * 为 flat 变体解析系列主色。
683
+ * 优先使用系列自定义颜色,其次回退到组件默认色板。
684
+ */
685
+ function resolveSeriesColor(item, index) {
686
+ if (Array.isArray(item.colors) && item.colors.length > 0) {
687
+ return item.colors[0];
688
+ }
689
+ return colors.DEFAULT_COLORS[index % colors.DEFAULT_COLORS.length];
690
+ }
691
+
692
+ /**
693
+ * 解析平面柱图的渐变色。
694
+ * - 传 1 个色值:自动生成亮/中/暗三段
695
+ * - 传 2 个色值:首色作为顶部,次色作为主体,底部由主体自动加深
696
+ * - 传 3 个色值:分别映射为顶/中/底
697
+ */
698
+ function resolveFlatBarColors(item, index) {
699
+ var fallbackColor = colors.DEFAULT_COLORS[index % colors.DEFAULT_COLORS.length];
700
+ var palette = Array.isArray(item.colors) ? item.colors.filter(Boolean).slice(0, 3) : [];
701
+ if (palette.length === 1) {
702
+ return {
703
+ start: lightenColor(palette[0], 0.18),
704
+ middle: palette[0],
705
+ end: darkenColor(palette[0], 0.12)
706
+ };
707
+ }
708
+ if (palette.length === 2) {
709
+ return {
710
+ start: palette[0],
711
+ middle: palette[1],
712
+ end: darkenColor(palette[1], 0.12)
713
+ };
714
+ }
715
+ if (palette.length === 3) {
716
+ return {
717
+ start: palette[0],
718
+ middle: palette[1],
719
+ end: palette[2]
720
+ };
721
+ }
722
+ return {
723
+ start: lightenColor(fallbackColor, 0.18),
724
+ middle: fallbackColor,
725
+ end: darkenColor(fallbackColor, 0.12)
726
+ };
727
+ }
728
+
729
+ /**
730
+ * 创建柱体纵向渐变。
731
+ * 让 2D 柱图与 3D 变体保持一致的明暗层次。
732
+ */
733
+ function createBarGradient(colorMap) {
734
+ return new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
735
+ offset: 0,
736
+ color: colorMap.start
737
+ }, {
738
+ offset: 0.55,
739
+ color: colorMap.middle
740
+ }, {
741
+ offset: 1,
742
+ color: colorMap.end
743
+ }]);
744
+ }
745
+
746
+ /**
747
+ * 生成 flat 变体的 series。
748
+ * 同时兼容:
749
+ * - bar
750
+ * - line
751
+ * - stack
752
+ * - yAxisIndex
753
+ * - colors / barWidth / barGap
754
+ */
755
+ function createFlatBarLineSeries(_ref) {
756
+ var normalizedSeries = _ref.normalizedSeries,
757
+ rawData = _ref.rawData,
758
+ barWidth = _ref.barWidth,
759
+ barGap = _ref.barGap;
760
+ var resolvedBarWidth = Number.isFinite(Number(barWidth)) ? Number(barWidth) : 18;
761
+ var resolvedBarGap = toBarGapValue(barGap);
762
+ return normalizedSeries.map(function (item, index) {
763
+ var isLine = item.kind === 'line';
764
+ var color = resolveSeriesColor(item, index);
765
+ var barColorMap = resolveFlatBarColors(item, index);
766
+ var baseSeries = {
767
+ name: item.name,
768
+ type: isLine ? 'line' : 'bar',
769
+ data: rawData.map(function (row) {
770
+ return row[item.key];
771
+ }),
772
+ itemStyle: {
773
+ color: isLine ? color : createBarGradient(barColorMap)
774
+ }
775
+ };
776
+ if (isLine) {
777
+ return colors._objectSpread2(colors._objectSpread2({}, baseSeries), {}, {
778
+ smooth: true,
779
+ yAxisIndex: item.yAxisIndex
780
+ });
781
+ }
782
+ return colors._objectSpread2(colors._objectSpread2({}, baseSeries), {}, {
783
+ stack: item.stack,
784
+ barWidth: resolvedBarWidth,
785
+ barGap: resolvedBarGap
786
+ });
787
+ });
788
+ }
789
+
790
+ /**
791
+ * 根据系列定义决定是否需要双 Y 轴。
792
+ * 只有当 line 系列显式使用副轴时,才返回双轴结构。
793
+ */
794
+ function createFlatYAxis(normalizedSeries) {
795
+ var hasSecondaryAxis = normalizedSeries.some(function (item) {
796
+ return item.kind === 'line' && item.yAxisIndex > 0;
797
+ });
798
+ if (!hasSecondaryAxis) {
799
+ return {
800
+ type: 'value'
801
+ };
802
+ }
803
+ return [{
804
+ type: 'value'
805
+ }, {
806
+ type: 'value',
807
+ position: 'right',
808
+ splitLine: {
809
+ show: false
810
+ }
811
+ }];
812
+ }
813
+
814
+ /**
815
+ * 生成 flat 变体的 option 片段。
816
+ */
817
+ function createFlatBarLineOption(normalizedInput) {
818
+ var option = {
819
+ color: colors.DEFAULT_COLORS,
820
+ yAxis: createFlatYAxis(normalizedInput.normalizedSeries),
821
+ series: createFlatBarLineSeries(normalizedInput)
822
+ };
823
+ if (normalizedInput.includeXAxis !== false) {
824
+ option.xAxis = {
825
+ type: 'category',
826
+ data: normalizedInput.categories
827
+ };
828
+ }
829
+ return option;
830
+ }
831
+
832
+ /**
833
+ * 创建方柱单个面的渐变。
834
+ * 左右侧面使用纵向渐变,顶面使用横向渐变,增强立体面的层次感。
835
+ */
836
+ function createFaceGradient(x0, y0, x1, y1, startColor, endColor) {
837
+ return new echarts.graphic.LinearGradient(x0, y0, x1, y1, [{
838
+ offset: 0,
839
+ color: startColor
840
+ }, {
841
+ offset: 1,
842
+ color: endColor
843
+ }]);
844
+ }
845
+
846
+ /**
847
+ * 创建方柱渲染器。
848
+ * 参考案例使用三块 polygon 拼接成立方体,而不是“正面 rect + 顶面/侧面”。
849
+ */
850
+ function createCubeRenderItem(layout, slotIndex, colorMap) {
851
+ return function renderItem(params, api) {
852
+ var rowIndex = api.value(0);
853
+ var endValue = api.value(1);
854
+ var baseValue = api.value(2);
855
+ var rawValue = api.value(3);
856
+ var stackStart = api.value(4) === 1;
857
+ var stackEnd = api.value(5) === 1;
858
+ if (!rawValue) {
859
+ return null;
860
+ }
861
+ var endPoint = api.coord([rowIndex, endValue]);
862
+ var basePoint = api.coord([rowIndex, baseValue]);
863
+ var offsetX = getBarOffset(layout, slotIndex);
864
+ var centerX = endPoint[0] + offsetX;
865
+ var topY = endPoint[1];
866
+ var baseY = basePoint[1];
867
+ var halfWidth = layout.barWidth / 2;
868
+ var offsetY = Math.tan(Math.PI / 9) * halfWidth;
869
+ var isPositive = rawValue >= 0;
870
+ var connectorOverlap = stackStart ? 0 : Math.max(2, Math.round(offsetY));
871
+ var connectorCapOffset = stackEnd ? 0 : Math.min(2, offsetY * 0.45);
872
+ var connectBaseY = isPositive ? baseY + connectorOverlap : baseY - connectorOverlap;
873
+ 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
+ return {
878
+ type: 'group',
879
+ children: [{
880
+ type: 'polygon',
881
+ shape: {
882
+ points: [[centerX, topY + offsetY - 1], [centerX - halfWidth, topY], [centerX - halfWidth, connectBaseY - offsetY], [centerX, connectBaseY - 1]]
883
+ },
884
+ style: {
885
+ fill: leftFaceGradient,
886
+ stroke: colorMap.left,
887
+ lineWidth: 1
888
+ }
889
+ }, {
890
+ type: 'polygon',
891
+ shape: {
892
+ points: [[centerX, topY + offsetY - 1], [centerX + halfWidth, topY], [centerX + halfWidth, connectBaseY - offsetY], [centerX, connectBaseY - 1]]
893
+ },
894
+ style: {
895
+ fill: rightFaceGradient,
896
+ stroke: colorMap.right,
897
+ lineWidth: 1
898
+ }
899
+ }, {
900
+ type: 'polygon',
901
+ shape: {
902
+ points: [[centerX, topSurfaceY + offsetY - 1], [centerX + halfWidth, topSurfaceY], [centerX, topSurfaceY - offsetY + 1], [centerX - halfWidth, topSurfaceY]]
903
+ },
904
+ style: {
905
+ fill: topFaceGradient,
906
+ stroke: colorMap.top,
907
+ lineWidth: 1
908
+ },
909
+ z2: stackEnd ? 10 : 2
910
+ }]
911
+ };
912
+ };
913
+ }
914
+
915
+ /**
916
+ * 生成方柱变体 option。
917
+ * line 系列继续复用 flat 逻辑,只替换 bar 系列的 custom renderItem。
918
+ */
919
+ function createCubeBarLineOption(normalizedInput) {
920
+ var flatOption = createFlatBarLineOption(normalizedInput);
921
+ var flatSeries = createFlatBarLineSeries(normalizedInput);
922
+ var customBarSeries = buildCustomBarSeries({
923
+ rawData: normalizedInput.rawData,
924
+ normalizedSeries: normalizedInput.normalizedSeries,
925
+ barWidth: normalizedInput.barWidth,
926
+ barGap: normalizedInput.barGap,
927
+ createRenderItem: createCubeRenderItem,
928
+ resolveColorMap: resolveCubeColors
929
+ });
930
+ var barIndex = 0;
931
+ var series = normalizedInput.normalizedSeries.map(function (item, index) {
932
+ if (item.kind === 'bar') {
933
+ var nextSeries = customBarSeries[barIndex];
934
+ barIndex += 1;
935
+ return nextSeries;
936
+ }
937
+ return flatSeries[index];
938
+ });
939
+ return colors._objectSpread2(colors._objectSpread2({}, flatOption), {}, {
940
+ series: series
941
+ });
942
+ }
943
+
944
+ /**
945
+ * 圆柱柱身透明度:
946
+ * - 顶面保持实色,避免与柱身混在一起;
947
+ * - 柱身增加少量透明度,让渐变层次更轻一些。
948
+ */
949
+ var CYLINDER_SIDE_OPACITY = 0.82;
950
+
951
+ /**
952
+ * 生成完整椭圆面的多边形顶点。
953
+ * 由于 custom graphic 不直接支持椭圆面填充,这里用多边形近似。
954
+ */
955
+ function createEllipsePolygon(cx, cy, rx, ry) {
956
+ var points = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 24;
957
+ var polygonPoints = [];
958
+ for (var index = 0; index < points; index += 1) {
959
+ var angle = index / points * Math.PI * 2;
960
+ polygonPoints.push([cx + Math.cos(angle) * rx, cy + Math.sin(angle) * ry]);
961
+ }
962
+ return polygonPoints;
963
+ }
964
+
965
+ /**
966
+ * 创建圆柱渲染器。
967
+ * 关键点:
968
+ * 1. 顶部用椭圆多边形模拟高光面;
969
+ * 2. 主体用纵向渐变矩形模拟曲面;
970
+ * 3. 堆叠连接处保留底片,但不绘制深色描边和弧线,避免形成脏色带。
971
+ */
972
+ function createCylinderRenderItem(layout, slotIndex, colorMap) {
973
+ return function renderItem(params, api) {
974
+ var rowIndex = api.value(0);
975
+ var endValue = api.value(1);
976
+ var baseValue = api.value(2);
977
+ var rawValue = api.value(3);
978
+ var stackStart = api.value(4) === 1;
979
+ var stackEnd = api.value(5) === 1;
980
+ if (!rawValue) {
981
+ return null;
982
+ }
983
+ var endPoint = api.coord([rowIndex, endValue]);
984
+ 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
+ var isPositive = rawValue >= 0;
990
+ var barHeight = Math.abs(endPoint[1] - basePoint[1]);
991
+ var visibleEllipseY = endPoint[1];
992
+ var connectorOverlap = stackStart ? 0 : Math.max(2, Math.round(radiusY));
993
+ var connectorCapOffset = stackEnd ? 0 : Math.min(2, radiusY * 0.4);
994
+ var showBottomPlate = isPositive && !stackStart;
995
+ var bottomPlateOffset = showBottomPlate ? Math.min(1.6, Math.max(0.9, radiusY * 0.32)) : 0;
996
+ var sideY = isPositive ? visibleEllipseY : basePoint[1] - connectorOverlap;
997
+ var sideHeight = isPositive ? barHeight : barHeight + connectorOverlap;
998
+ var topEllipseY = visibleEllipseY + connectorCapOffset;
999
+ var bottomPlateY = basePoint[1] + bottomPlateOffset;
1000
+ var gradientTopColor = isPositive ? colorMap.middle : darkenColor(colorMap.bottom, 0.05);
1001
+ var gradientMiddleColor = colorMap.middle;
1002
+ 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
+ }]);
1013
+ return {
1014
+ type: 'group',
1015
+ children: [].concat(colors._toConsumableArray(showBottomPlate ? [{
1016
+ type: 'polygon',
1017
+ shape: {
1018
+ points: createEllipsePolygon(centerX, bottomPlateY, radiusX, radiusY)
1019
+ },
1020
+ style: {
1021
+ fill: colorMap.bottom,
1022
+ opacity: 0.9
1023
+ },
1024
+ z: 0
1025
+ }] : []), [{
1026
+ type: 'rect',
1027
+ shape: {
1028
+ x: centerX - radiusX,
1029
+ y: sideY,
1030
+ width: layout.barWidth,
1031
+ height: sideHeight,
1032
+ r: isPositive ? stackStart ? [0, 0, 6, 6] : [0, 0, 0, 0] : stackStart ? [6, 6, 0, 0] : [0, 0, 0, 0]
1033
+ },
1034
+ style: {
1035
+ fill: sideGradient
1036
+ },
1037
+ z: 1
1038
+ }, {
1039
+ type: 'polygon',
1040
+ shape: {
1041
+ points: createEllipsePolygon(centerX, topEllipseY, radiusX, radiusY)
1042
+ },
1043
+ style: {
1044
+ fill: isPositive ? colorMap.top : colorMap.bottom
1045
+ },
1046
+ z2: stackEnd ? 100 : 2
1047
+ }])
1048
+ };
1049
+ };
1050
+ }
1051
+
1052
+ /**
1053
+ * 生成圆柱变体 option。
1054
+ * 仅替换 bar 的渲染方式,line 系列继续复用 flat 变体逻辑。
1055
+ */
1056
+ function createCylinderBarLineOption(normalizedInput) {
1057
+ var flatOption = createFlatBarLineOption(normalizedInput);
1058
+ var flatSeries = createFlatBarLineSeries(normalizedInput);
1059
+ var customBarSeries = buildCustomBarSeries({
1060
+ rawData: normalizedInput.rawData,
1061
+ normalizedSeries: normalizedInput.normalizedSeries,
1062
+ barWidth: normalizedInput.barWidth,
1063
+ barGap: normalizedInput.barGap,
1064
+ createRenderItem: createCylinderRenderItem,
1065
+ resolveColorMap: resolveCylinderColors
1066
+ });
1067
+ var barIndex = 0;
1068
+ var series = normalizedInput.normalizedSeries.map(function (item, index) {
1069
+ if (item.kind === 'bar') {
1070
+ var nextSeries = customBarSeries[barIndex];
1071
+ barIndex += 1;
1072
+ return nextSeries;
1073
+ }
1074
+ return flatSeries[index];
1075
+ });
1076
+ return colors._objectSpread2(colors._objectSpread2({}, flatOption), {}, {
1077
+ series: series
1078
+ });
1079
+ }
1080
+
1081
+ var DEFAULT_VARIANT = 'flat';
1082
+ var BAR_LINE_PUBLIC_VARIANTS = ['flat', 'cylinder', 'cube'];
1083
+
1084
+ // 公开 variant 能力在此处收口:只允许 flat / cylinder / cube。
1085
+ // 注意:three-d、square 文件仍可作为内部实现存在,但绝不加入公开分发链。
1086
+ var variantFactory = {
1087
+ flat: createFlatBarLineOption,
1088
+ cylinder: createCylinderBarLineOption,
1089
+ cube: createCubeBarLineOption
1090
+ };
1091
+
1092
+ /**
1093
+ * 当前 builder 不再解析历史别名。
1094
+ * 组件 props 层已经通过 validator 保证只会传入公开类型。
1095
+ */
1096
+ function resolveVariantName(variant) {
1097
+ return variant;
1098
+ }
1099
+
1100
+ /**
1101
+ * 生成所有柱线图共用的基础 option。
1102
+ * 包括 tooltip、legend、grid、xAxis 等与具体视觉变体无关的公共结构。
1103
+ */
1104
+ function createBaseOption(normalizedInput) {
1105
+ return {
1106
+ tooltip: {
1107
+ trigger: 'axis'
1108
+ },
1109
+ legend: {
1110
+ data: normalizedInput.normalizedSeries.map(function (item) {
1111
+ return item.name;
1112
+ })
1113
+ },
1114
+ grid: {
1115
+ left: 16,
1116
+ right: 16,
1117
+ top: 24,
1118
+ bottom: 32,
1119
+ containLabel: true
1120
+ },
1121
+ xAxis: {
1122
+ type: 'category',
1123
+ data: normalizedInput.categories
1124
+ }
1125
+ };
1126
+ }
1127
+
1128
+ /**
1129
+ * 构建 `BarLineChart` 最终 option。
1130
+ * 这里会统一完成:
1131
+ * 1. 输入归一化
1132
+ * 2. preset 合并
1133
+ * 3. 变体分发
1134
+ * 4. customOption 覆盖
1135
+ */
1136
+ function buildBarLineOption() {
1137
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
1138
+ data = _ref.data,
1139
+ xAxisKey = _ref.xAxisKey,
1140
+ series = _ref.series,
1141
+ _ref$preset = _ref.preset,
1142
+ preset = _ref$preset === void 0 ? 'compare' : _ref$preset,
1143
+ _ref$variant = _ref.variant,
1144
+ variant = _ref$variant === void 0 ? 'flat' : _ref$variant,
1145
+ barWidth = _ref.barWidth,
1146
+ barGap = _ref.barGap,
1147
+ customOption = _ref.customOption;
1148
+ var normalizedInput = normalizeBarLineInput({
1149
+ data: data,
1150
+ xAxisKey: xAxisKey,
1151
+ series: series
1152
+ });
1153
+ var baseOption = createBaseOption(normalizedInput);
1154
+ var presetOption = getBarLinePreset(preset);
1155
+ var resolvedVariant = resolveVariantName(variant);
1156
+ var createVariantOption = variantFactory[resolvedVariant] || variantFactory[DEFAULT_VARIANT];
1157
+ var variantOption = createVariantOption(colors._objectSpread2(colors._objectSpread2({}, normalizedInput), {}, {
1158
+ includeXAxis: false,
1159
+ barWidth: barWidth,
1160
+ barGap: barGap
1161
+ }));
1162
+ return colors.mergeChartOption(colors.mergeChartOption(baseOption, presetOption, variantOption), customOption);
1163
+ }
1164
+
1165
+ //
1166
+ //
1167
+ //
1168
+ //
1169
+ //
1170
+ //
1171
+ //
1172
+ //
1173
+ //
1174
+ //
1175
+ //
1176
+
1177
+
1178
+ /**
1179
+ * BarLineChart 基于 `echarts/core` 的按需模式工作。
1180
+ * 这里显式注册柱图、折线图、自定义系列以及笛卡尔坐标系常用组件,
1181
+ * 否则运行时虽然能生成 option,但对应主类型不会真正参与渲染。
1182
+ */
1183
+ echarts__namespace.use([charts.BarChart, charts.LineChart, charts.CustomChart, components.TooltipComponent, components.LegendComponent, components.GridComponent, components.TitleComponent, renderers.CanvasRenderer]);
1184
+ var script = {
1185
+ name: 'BarLineChart',
1186
+ components: {
1187
+ BaseChart: withInstall.BaseChart
1188
+ },
1189
+ props: {
1190
+ /**
1191
+ * 图表原始数据源。
1192
+ * 每一项通常是一个类目对象,例如月份、地区等维度下的业务统计结果。
1193
+ */
1194
+ data: {
1195
+ type: Array,
1196
+ "default": function _default() {
1197
+ return [];
1198
+ }
1199
+ },
1200
+ /**
1201
+ * 类目轴字段名。
1202
+ * builder 会使用该字段从 `data` 中提取横轴类目文本。
1203
+ */
1204
+ xAxisKey: {
1205
+ type: String,
1206
+ "default": 'name'
1207
+ },
1208
+ /**
1209
+ * 系列定义数组。
1210
+ * 每项建议包含:
1211
+ * - key: 对应数据字段
1212
+ * - name: 系列名称
1213
+ * - kind: bar / line
1214
+ * - stack / yAxisIndex / colors: 可选增强配置
1215
+ */
1216
+ series: {
1217
+ type: Array,
1218
+ "default": function _default() {
1219
+ return [];
1220
+ }
1221
+ },
1222
+ /**
1223
+ * 公开柱体风格枚举。
1224
+ * 当前仅允许:
1225
+ * - flat:二维柱线图
1226
+ * - cylinder:圆柱视觉
1227
+ * - cube:方柱视觉
1228
+ */
1229
+ variant: {
1230
+ type: String,
1231
+ "default": 'flat',
1232
+ validator: function validator(value) {
1233
+ return BAR_LINE_PUBLIC_VARIANTS.includes(value);
1234
+ }
1235
+ },
1236
+ /**
1237
+ * 预设配置名称。
1238
+ * 用于切换 compare / trend / rank 等通用布局和展示细节。
1239
+ */
1240
+ preset: {
1241
+ type: String,
1242
+ "default": 'compare'
1243
+ },
1244
+ /**
1245
+ * 柱体宽度。
1246
+ * flat 模式直接透传给 ECharts;3D 变体会作为自定义图形布局宽度使用。
1247
+ */
1248
+ barWidth: {
1249
+ type: Number,
1250
+ "default": 18
1251
+ },
1252
+ /**
1253
+ * 柱间距。
1254
+ * 数字按百分比语义处理;字符串则按原样语义交给内部布局计算。
1255
+ */
1256
+ barGap: {
1257
+ type: [Number, String],
1258
+ "default": 8
1259
+ },
1260
+ /**
1261
+ * 额外透传给 ECharts option 的自定义配置。
1262
+ * 会在 base / preset / variant option 合并完成后再覆盖。
1263
+ */
1264
+ customOption: {
1265
+ type: Object,
1266
+ "default": function _default() {
1267
+ return {};
1268
+ }
1269
+ },
1270
+ /**
1271
+ * 图表 loading 状态。
1272
+ * 由 BaseChart 统一接管具体的 loading UI。
1273
+ */
1274
+ loading: {
1275
+ type: Boolean,
1276
+ "default": false
1277
+ },
1278
+ /**
1279
+ * 图表容器高度。
1280
+ * 支持数字像素值或原样透传的 CSS 高度字符串。
1281
+ */
1282
+ height: {
1283
+ type: [String, Number],
1284
+ "default": 320
1285
+ }
1286
+ },
1287
+ computed: {
1288
+ /**
1289
+ * 根据数据源判断是否进入空态。
1290
+ */
1291
+ isEmpty: function isEmpty() {
1292
+ return colors.isEmptyData(this.data);
1293
+ },
1294
+ /**
1295
+ * 将公开 props 汇总为 builder 所需输入。
1296
+ * 组件层不做类型分发,只负责把标准公开参数交给构建层。
1297
+ */
1298
+ chartOption: function chartOption() {
1299
+ // 组件层只负责组装公开参数,不承载变体分发策略。
1300
+ return buildBarLineOption({
1301
+ data: this.data,
1302
+ xAxisKey: this.xAxisKey,
1303
+ series: this.series,
1304
+ variant: this.variant,
1305
+ preset: this.preset,
1306
+ barWidth: this.barWidth,
1307
+ barGap: this.barGap,
1308
+ customOption: this.customOption
1309
+ });
1310
+ }
1311
+ }
1312
+ };
1313
+
1314
+ 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";
1315
+ withInstall.styleInject(css_248z);
1316
+
1317
+ /* script */
1318
+ var __vue_script__ = script;
1319
+ /* template */
1320
+ var __vue_render__ = function __vue_render__() {
1321
+ var _vm = this;
1322
+ var _h = _vm.$createElement;
1323
+ var _c = _vm._self._c || _h;
1324
+ return _c("BaseChart", {
1325
+ attrs: {
1326
+ option: _vm.chartOption,
1327
+ loading: _vm.loading,
1328
+ empty: _vm.isEmpty,
1329
+ height: _vm.height
1330
+ },
1331
+ on: {
1332
+ "chart-click": function chartClick($event) {
1333
+ return _vm.$emit("chart-click", $event);
1334
+ },
1335
+ ready: function ready($event) {
1336
+ return _vm.$emit("ready", $event);
1337
+ }
1338
+ }
1339
+ });
1340
+ };
1341
+ var __vue_staticRenderFns__ = [];
1342
+ __vue_render__._withStripped = true;
1343
+
1344
+ /* style */
1345
+ var __vue_inject_styles__ = undefined;
1346
+ /* scoped */
1347
+ var __vue_scope_id__ = "data-v-e33b855e";
1348
+ /* module identifier */
1349
+ var __vue_module_identifier__ = undefined;
1350
+ /* functional template */
1351
+ var __vue_is_functional_template__ = false;
1352
+ /* style inject */
1353
+
1354
+ /* style inject SSR */
1355
+
1356
+ /* style inject shadow dom */
1357
+
1358
+ var __vue_component__ = /*#__PURE__*/withInstall.normalizeComponent({
1359
+ render: __vue_render__,
1360
+ staticRenderFns: __vue_staticRenderFns__
1361
+ }, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, false, undefined, undefined, undefined);
1362
+ var BarLineChart = __vue_component__;
1363
+
1364
+ exports.BarLineChart = BarLineChart;