onesight-charts 1.4.2 → 1.4.3

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.
@@ -1,13 +1,13 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
3
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
4
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
9
5
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
10
6
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
8
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
9
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
10
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
11
11
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
12
12
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
13
13
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -15,7 +15,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
15
15
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
16
16
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
17
17
  import * as echarts from 'echarts';
18
- import React, { useEffect, useRef, useState, useCallback } from 'react';
18
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
19
19
  import { changeDataTypeEn, computeFloat, dealBarPath, numberFormatNull } from "../../utils/chartUtils";
20
20
  import Pagination from "../pagination";
21
21
  import "./style.scss";
@@ -43,67 +43,28 @@ function CommonBar(props) {
43
43
  callbackGetPage = _props$callbackGetPag === void 0 ? function () {} : _props$callbackGetPag,
44
44
  _props$handleClick = props.handleClick,
45
45
  handleClick = _props$handleClick === void 0 ? function () {} : _props$handleClick;
46
- // 总数页码数
47
46
  var _useState = useState(0),
48
47
  _useState2 = _slicedToArray(_useState, 2),
49
48
  total = _useState2[0],
50
49
  setTotal = _useState2[1];
51
50
  var chart = useRef(null);
52
- // 当前页下标
53
51
  var _useState3 = useState(1),
54
52
  _useState4 = _slicedToArray(_useState3, 2),
55
53
  currentPage = _useState4[0],
56
54
  setCurrentPage = _useState4[1];
57
55
  var chartRef = useRef(null);
58
- // 存储上一次的依赖项值,用于深度比较
59
56
  var prevDepsRef = useRef(null);
60
- // 为每个组件实例生成唯一的 tooltip 类名,避免多实例冲突
61
57
  var tooltipClassNameRef = useRef("onesight-chart-common-bar-tooltip-".concat(Date.now(), "-").concat(Math.random().toString(36).substr(2, 9)));
62
- useEffect(function () {
63
- // 深度比较依赖项,只有当内容真正改变时才执行
64
- var currentDeps = JSON.stringify({
65
- currentPage: currentPage,
66
- data: data
67
- });
68
- var prevDeps = prevDepsRef.current;
69
-
70
- // 如果内容没有改变,不执行
71
- if (prevDeps !== null && currentDeps === prevDeps) {
72
- return;
73
- }
74
-
75
- // 更新存储的值
76
- prevDepsRef.current = currentDeps;
77
- var copyData = JSON.parse(JSON.stringify(data));
78
- var splice_data = copyData.slice((currentPage - 1) * number, currentPage * number);
79
- if (data.length) {
80
- setTotal(Math.ceil(data.length / number));
81
- }
82
- init(splice_data);
83
- callbackGetPage(currentPage);
84
- // 使用 setTimeout 确保 DOM 已经更新后再绑定事件
85
- setTimeout(function () {
86
- bindClickEvents();
87
- }, 0);
88
- return function () {
89
- unbindClickEvents();
90
- };
91
- }, [currentPage, data, bindClickEvents, unbindClickEvents]);
92
58
  var paginationCb = function paginationCb(currData, page) {
93
59
  setCurrentPage(page);
94
60
  };
95
61
  var onChartClick = useCallback(function (event) {
96
- // 确保只处理当前组件实例的 tooltip
97
62
  var tooltipElement = event.target.closest(".".concat(tooltipClassNameRef.current));
98
- if (!tooltipElement) {
99
- return;
100
- }
63
+ if (!tooltipElement) return;
101
64
  var seriesNameElement = event.target.closest('.item');
102
65
  if (seriesNameElement) {
103
66
  var seriesItem = seriesNameElement.getAttribute('data-series-item');
104
- if (!seriesItem) {
105
- return;
106
- }
67
+ if (!seriesItem) return;
107
68
  var seriesData = JSON.parse(seriesItem);
108
69
  handleClick && handleClick('tooltipType', seriesData);
109
70
  }
@@ -120,6 +81,26 @@ function CommonBar(props) {
120
81
  chartElement.removeEventListener('click', onChartClick);
121
82
  }
122
83
  }, [onChartClick]);
84
+ useEffect(function () {
85
+ var currentDeps = JSON.stringify({
86
+ currentPage: currentPage,
87
+ data: data
88
+ });
89
+ var prevDeps = prevDepsRef.current;
90
+ if (prevDeps !== null && currentDeps === prevDeps) return;
91
+ prevDepsRef.current = currentDeps;
92
+ var copyData = JSON.parse(JSON.stringify(data));
93
+ var splice_data = copyData.slice((currentPage - 1) * number, currentPage * number);
94
+ if (data.length) setTotal(Math.ceil(data.length / number));
95
+ init(splice_data);
96
+ callbackGetPage(currentPage);
97
+ setTimeout(function () {
98
+ bindClickEvents();
99
+ }, 0);
100
+ return function () {
101
+ unbindClickEvents();
102
+ };
103
+ }, [currentPage, data, bindClickEvents, unbindClickEvents, number, callbackGetPage]);
123
104
  function toggleAxisPointer(myChart, show) {
124
105
  myChart.setOption({
125
106
  tooltip: {
@@ -131,49 +112,32 @@ function CommonBar(props) {
131
112
  }
132
113
  });
133
114
  }
134
-
135
- // 将 JSON 字符串转义为安全的 HTML 属性值
136
115
  function escapeHtmlAttribute(jsonString) {
137
116
  return String(jsonString).replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
138
117
  }
139
118
  var calculateWidth = function calculateWidth(len) {
140
- if (len === 1 || len === 2 || len === 3) {
141
- return 42;
142
- } else if (len === 4) {
143
- return 40;
144
- } else if (len === 5) {
145
- return 32;
146
- } else if (len === 6) {
147
- return 26;
148
- } else if (len === 7) {
149
- return 24;
150
- } else if (len === 8) {
151
- return 20;
152
- } else if (len === 9) {
153
- return 18;
154
- } else if (len === 10) {
155
- return 16;
156
- }
119
+ if (len === 1 || len === 2 || len === 3) return 42;
120
+ if (len === 4) return 40;
121
+ if (len === 5) return 32;
122
+ if (len === 6) return 26;
123
+ if (len === 7) return 24;
124
+ if (len === 8) return 20;
125
+ if (len === 9) return 18;
126
+ if (len === 10) return 16;
127
+ return 16;
157
128
  };
158
129
  function setBarData(myChart, newData) {
159
130
  if (!myChart) return;
160
131
  myChart.setOption({
161
- series: [
162
- // 背景柱(seriesIndex 0)保持不变
163
- {},
164
- // 前景柱(seriesIndex 1)换成新数组
165
- {
132
+ series: [{}, {
166
133
  data: newData
167
134
  }]
168
- }, false); // 第二个参数 false → 不合并全量 option
135
+ }, false);
169
136
  }
170
137
  var ICON_SIZE = 18;
171
138
  var ICON_GAP = 0;
172
-
173
- // 生成 y 轴富文本样式:为每一行创建 iconN,并且给 label 做截断
174
139
  function makeYAxisRich(rows) {
175
140
  var maxLabelWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 188;
176
- // 检查是否有任何行包含 platformIcon
177
141
  var hasAnyIcon = rows.some(function (row) {
178
142
  return row.platformIcon;
179
143
  });
@@ -184,14 +148,10 @@ function CommonBar(props) {
184
148
  fontWeight: 500,
185
149
  lineHeight: 20,
186
150
  align: 'right',
187
- // 文本宽度 = 总宽 - 图标宽度 - 间距
188
- // width: Math.max(0, maxLabelWidth - ICON_SIZE - ICON_GAP),
189
151
  overflow: 'truncate',
190
152
  ellipsis: '...',
191
- // 如果没有任何图标,则不需要左边距
192
153
  padding: hasAnyIcon ? [0, 0, 0, ICON_GAP] : [0, 0, 0, 0]
193
154
  },
194
- // 为没有图标的项目创建一个空的样式
195
155
  noIcon: {
196
156
  width: 0,
197
157
  height: 0
@@ -204,13 +164,11 @@ function CommonBar(props) {
204
164
  height: ICON_SIZE,
205
165
  align: 'right',
206
166
  borderRadius: 4,
207
- // 这里用图片作为文本块的背景
208
167
  backgroundColor: {
209
168
  image: row.platformIcon
210
- } // 建议传绝对路径或 public 下的路径
169
+ }
211
170
  };
212
171
  } else {
213
- // 为没有图标的项目创建空样式
214
172
  rich["icon".concat(i)] = {
215
173
  width: 0,
216
174
  height: 0
@@ -219,36 +177,20 @@ function CommonBar(props) {
219
177
  });
220
178
  return rich;
221
179
  }
222
-
223
- // 单行 label 的最大显示区域(和 axisLabel.width 一致)
224
180
  var MAX_LABEL_WIDTH = 188;
225
-
226
- // 如果该条有平台 icon,就要扣掉 icon 宽度+间距;否则直接用全部
227
181
  function getMaxTextWidthForRow(hasIcon) {
228
182
  return hasIcon ? MAX_LABEL_WIDTH - ICON_SIZE - ICON_GAP : MAX_LABEL_WIDTH;
229
183
  }
230
-
231
- // 返回一个“中间省略”的文本,尽量贴近 maxWidthPx 宽度
232
184
  function middleEllipsis(labelText, maxWidthPx) {
233
185
  var font = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '14px sans-serif';
234
186
  if (!labelText) return '';
235
-
236
- // 先测整段的宽度
237
187
  var fullRect = echarts.format.getTextRect(labelText, font);
238
- if (fullRect.width <= maxWidthPx) {
239
- // 不超宽,直接用原文
240
- return labelText;
241
- }
242
-
243
- // 需要省略 -> 我们要找到前半段+后半段的长度
244
- // 方案:从头和尾慢慢加字符,直到超过 maxWidthPx
188
+ if (fullRect.width <= maxWidthPx) return labelText;
245
189
  var DOT = '...';
246
190
  var dotW = echarts.format.getTextRect(DOT, font).width;
247
-
248
- // 我们会不断尝试 prefixLen / suffixLen 的组合
249
191
  var prefixLen = 1;
250
192
  var suffixLen = 1;
251
- var best = DOT; // 兜底
193
+ var best = DOT;
252
194
  var bestW = dotW;
253
195
  while (prefixLen < labelText.length && suffixLen < labelText.length) {
254
196
  var head = labelText.slice(0, prefixLen);
@@ -256,16 +198,11 @@ function CommonBar(props) {
256
198
  var candidate = head + DOT + tail;
257
199
  var w = echarts.format.getTextRect(candidate, font).width;
258
200
  if (w <= maxWidthPx) {
259
- // 还能放得下 => 记录成当前最佳,然后再尝试加长
260
201
  best = candidate;
261
202
  bestW = w;
262
- // 优先多给前缀,视觉更贴设计稿(你可以反过来)
263
203
  prefixLen++;
264
- if (prefixLen % 2 === 0) {
265
- suffixLen++;
266
- }
204
+ if (prefixLen % 2 === 0) suffixLen++;
267
205
  } else {
268
- // 超了,就停。这个 best 就是我们要的
269
206
  break;
270
207
  }
271
208
  }
@@ -282,92 +219,51 @@ function CommonBar(props) {
282
219
  renderer: 'svg'
283
220
  });
284
221
  }
285
- var fadedData = null; // 缓存上一帧,避免重复 setOption
222
+ var fadedData = null;
286
223
  var lastIndex = null;
287
224
  var axisData = currentData.map(function (item) {
288
225
  return item.format || item.name || '-';
289
226
  });
290
- var seriesData = currentData.map(function (item) {
291
- // 优先使用每项自己的颜色,如果没有则使用默认的 barColor
292
- var itemColor = item.color || barColor;
293
- if (showProportion) {
294
- return {
295
- name: item.name || '-',
296
- value: (item === null || item === void 0 ? void 0 : item.proportion) || 0,
297
- label: {
298
- // 负数就把文字放左边,正数/0 放右边
299
- position: (item === null || item === void 0 ? void 0 : item.proportion) < 0 ? 'left' : 'right'
300
- },
301
- itemStyle: item !== null && item !== void 0 && item.proportion ? {
302
- color: itemColor
303
- } : {
304
- color: 'rgba(29, 169, 160, 0)'
305
- }
306
- };
307
- } else {
308
- return {
309
- name: item.name || '-',
310
- value: item.value || 0,
311
- label: {
312
- // 负数就把文字放左边,正数/0 放右边
313
- position: item.value < 0 ? 'left' : 'right'
314
- },
315
- itemStyle: item.value ? {
316
- color: itemColor
317
- } : {
318
- color: 'rgba(29, 169, 160, 0)'
319
- }
320
- };
321
- }
322
- });
323
- var originalData = seriesData.map(function (d) {
324
- return _objectSpread(_objectSpread({}, d), {}, {
325
- itemStyle: _objectSpread(_objectSpread({}, d.itemStyle || {}), {}, {
326
- opacity: 1
327
- })
328
- });
329
- });
330
- var maxDataValue = Math.max.apply(Math, _toConsumableArray(currentData.map(function (item) {
331
- return showProportion ? item === null || item === void 0 ? void 0 : item.proportion : item.value;
332
- })));
333
- // ① 先测出 Y 轴中最长的类目文本宽度
227
+ var yIconFlag = data === null || data === void 0 || (_data$ = data[0]) === null || _data$ === void 0 ? void 0 : _data$.platformIcon;
228
+ var valueAccessor = function valueAccessor(item) {
229
+ return showProportion ? (item === null || item === void 0 ? void 0 : item.proportion) || 0 : item.value || 0;
230
+ };
231
+ var maxDataValue = Math.max.apply(Math, _toConsumableArray(currentData.map(valueAccessor)));
232
+ var minDataValue = Math.min.apply(Math, _toConsumableArray(currentData.map(valueAccessor)));
233
+ var hasNegative = minDataValue < 0;
234
+ var allNegative = maxDataValue < 0;
235
+
236
+ // === 计算 barAreaWidth(用于换算像素)===
334
237
  var ySample = axisData.reduce(function (a, b) {
335
238
  return a.length > b.length ? a : b;
336
239
  }, '');
337
240
  var yLabelWidth = echarts.format.getTextRect(ySample, '14px sans-serif').width;
338
- // 你在 axisLabel 里写了 margin: 10
339
241
  var axisLabelGap = 10;
340
242
  var chartWidth = myChart.getWidth();
341
243
  var leftPadding = 12;
342
244
  var rightPadding = 0;
343
245
  var gridWidth = chartWidth - leftPadding - rightPadding;
344
246
  var dealYLabelWidth = yLabelWidth > 188 ? 188 : yLabelWidth;
345
- // ③ 真正柱子可用的像素宽度
346
247
  var barAreaWidth = gridWidth - dealYLabelWidth - axisLabelGap;
248
+
249
+ // 正数端 bgValue(你的原逻辑保留)
347
250
  var sampleText = showProportion ? computeFloat(maxDataValue) : numberFormatNull(maxDataValue);
348
251
  var labelWidth = echarts.format.getTextRect(sampleText, '14px sans-serif').width;
349
- var extra = 15;
350
- var yIconFlag = (_data$ = data[0]) === null || _data$ === void 0 ? void 0 : _data$.platformIcon;
351
- var valueAccessor = function valueAccessor(item) {
352
- return showProportion ? (item === null || item === void 0 ? void 0 : item.proportion) || 0 : item.value || 0;
353
- };
354
- var minDataValue = Math.min.apply(Math, _toConsumableArray(currentData.map(valueAccessor)));
355
- var hasNegative = minDataValue < 0;
356
- var allNegative = maxDataValue < 0; // 检查是否所有数据都是负数
357
-
252
+ var LABEL_DISTANCE = 5; // 要和 series.label.distance 保持一致
253
+ var SAFE_PX = 12; // 额外保险像素,避免误差导致溢出
254
+ var extra = 15 + LABEL_DISTANCE + SAFE_PX;
358
255
  var bgValue;
359
- // 如果所有数据都是负数,bgValue 应该设置为 0,让 xAxis.max 至少是 0
360
256
  if (allNegative) {
361
257
  bgValue = 0;
362
258
  } else if (barAreaWidth > labelWidth + extra) {
363
259
  bgValue = maxDataValue * barAreaWidth / (barAreaWidth - labelWidth - extra);
364
260
  } else {
365
- var overflowPx = labelWidth + extra - barAreaWidth; // 还差多少像素
366
- var unitPerPx = maxDataValue / barAreaWidth; // 1 像素 ≈ 多少数据值
367
- bgValue = maxDataValue + overflowPx * unitPerPx; // 把缺的像素折算到数据值
261
+ var overflowPx = labelWidth + extra - barAreaWidth;
262
+ var unitPerPx = maxDataValue / Math.max(barAreaWidth, 1);
263
+ bgValue = maxDataValue + overflowPx * unitPerPx;
368
264
  }
369
265
 
370
- // 计算负数的最小背景值(类似正数的 bgValue)
266
+ // 负数端 minBgValue(你的原逻辑保留)
371
267
  var minBgValue = 0;
372
268
  if (hasNegative) {
373
269
  var absMinDataValue = Math.abs(minDataValue);
@@ -375,21 +271,14 @@ function CommonBar(props) {
375
271
  var minLabelSample = showProportion ? computeFloat(absMinDataValue) : numberFormatNull(absMinDataValue);
376
272
  var minLabelWidth = echarts.format.getTextRect(minLabelSample, '14px sans-serif').width;
377
273
  var minExtra = 15;
378
-
379
- // 计算整个x轴的数据范围(从最小负数到最大正数)
380
274
  var totalDataRange = absMinDataValue + absMaxDataValue;
381
-
382
- // 计算负数部分应该占用的像素宽度
383
275
  var negativeBarAreaWidth;
384
- // 如果所有数据都是负数,使用整个 barAreaWidth 来显示负数
385
276
  if (allNegative) {
386
277
  negativeBarAreaWidth = barAreaWidth;
387
278
  } else if (totalDataRange > 0) {
388
279
  if (absMinDataValue < absMaxDataValue * 0.3) {
389
- // 负数很小,只给必要的空间(标签宽度 + 一些余量)
390
280
  negativeBarAreaWidth = Math.min(minLabelWidth + minExtra + 30, barAreaWidth * 0.25);
391
281
  } else {
392
- // 按比例分配,但确保至少能显示标签
393
282
  var ratio = absMinDataValue / totalDataRange;
394
283
  negativeBarAreaWidth = barAreaWidth * ratio;
395
284
  negativeBarAreaWidth = Math.max(negativeBarAreaWidth, minLabelWidth + minExtra + 20);
@@ -397,18 +286,10 @@ function CommonBar(props) {
397
286
  } else {
398
287
  negativeBarAreaWidth = barAreaWidth * 0.5;
399
288
  }
400
-
401
- // 计算 minBgValue:让负数柱子尽可能紧凑,只留出标签空间
402
- // 负数柱子占用的像素 = negativeBarAreaWidth - minLabelWidth - minExtra
403
289
  var availableBarWidth = Math.max(1, negativeBarAreaWidth - minLabelWidth - minExtra);
404
- // 计算每像素对应的数据值
405
290
  var dataPerPixel = absMinDataValue / availableBarWidth;
406
- // minBgValue 需要比 minDataValue 更小,以容纳左边的标签
407
- var labelSpaceInData = (minLabelWidth + minExtra) * dataPerPixel;
291
+ var labelSpaceInData = (minLabelWidth + minExtra) * dataPerPixel * 1.3;
408
292
  minBgValue = -(absMinDataValue + labelSpaceInData);
409
-
410
- // 如果同时有正数,重新计算正数的 bgValue,使用剩余空间
411
- // 如果所有数据都是负数,bgValue 保持为 0
412
293
  if (maxDataValue > 0 && !allNegative) {
413
294
  var positiveBarAreaWidth = barAreaWidth - negativeBarAreaWidth;
414
295
  if (positiveBarAreaWidth > labelWidth + extra) {
@@ -420,14 +301,53 @@ function CommonBar(props) {
420
301
  }
421
302
  }
422
303
  }
304
+
305
+ // ====== 方案B:把“小值”钳到至少 4px,但展示仍用真实值 ======
306
+ var MIN_BAR_PX = 4;
307
+ var safeBarAreaWidth = Math.max(1, barAreaWidth);
308
+ var axisSpan = bgValue - minBgValue;
309
+ axisSpan = Math.max(axisSpan, 1);
310
+ var minVisibleValue = axisSpan * (MIN_BAR_PX / safeBarAreaWidth);
311
+ minVisibleValue = Math.max(minVisibleValue, 1);
312
+
313
+ // 确保 xAxis.min 能容纳钳制后的负值长度,否则仍会被裁剪
314
+ if (hasNegative) {
315
+ minBgValue = Math.min(minBgValue, -minVisibleValue * 1.1);
316
+ axisSpan = Math.max(bgValue - minBgValue, 1);
317
+ minVisibleValue = Math.max(axisSpan * (MIN_BAR_PX / safeBarAreaWidth), 1);
318
+ }
319
+
320
+ // 前景 seriesData:保存 rawValue(真实值),value 用于绘制(钳制)
321
+ var seriesData = currentData.map(function (item) {
322
+ var itemColor = item.color || barColor;
323
+ var raw = valueAccessor(item);
324
+ var displayValue = raw === 0 ? 0 : Math.sign(raw) * Math.max(Math.abs(raw), minVisibleValue);
325
+ return {
326
+ name: item.name || '-',
327
+ rawValue: raw,
328
+ value: displayValue,
329
+ label: {
330
+ position: raw < 0 ? 'left' : 'right'
331
+ },
332
+ itemStyle: raw ? {
333
+ color: itemColor
334
+ } : {
335
+ color: 'rgba(29, 169, 160, 0)'
336
+ }
337
+ };
338
+ });
339
+ var originalData = seriesData.map(function (d) {
340
+ return _objectSpread(_objectSpread({}, d), {}, {
341
+ itemStyle: _objectSpread(_objectSpread({}, d.itemStyle || {}), {}, {
342
+ opacity: 1
343
+ })
344
+ });
345
+ });
423
346
  var option = {
424
347
  tooltip: {
425
348
  className: "onesight-chart-common-bar-tooltip ".concat(tooltipClassNameRef.current),
426
349
  trigger: 'axis',
427
350
  enterable: true,
428
- // showContent: true,
429
- // alwaysShowContent: true,
430
- // hideDelay: 1000000000,
431
351
  padding: 0,
432
352
  position: function position(point, params, dom) {
433
353
  var tooltipHeight = (dom === null || dom === void 0 ? void 0 : dom.offsetHeight) || 0;
@@ -452,26 +372,24 @@ function CommonBar(props) {
452
372
  var _res$, _res$2;
453
373
  if (!res.some(function (i) {
454
374
  return i.value !== undefined && i.value !== null;
455
- })) {
456
- return '';
457
- }
375
+ })) return '';
458
376
  var dataArr = [res[1]];
459
377
  var currentColor = ((_res$ = res[1]) === null || _res$ === void 0 ? void 0 : _res$.color) || '#1DA9A0';
460
378
  var triangleWidth = 280;
461
- // 获取当前数据项的索引,以便从 currentData 中获取 alias
462
379
  var dataIndex = (_res$2 = res[1]) === null || _res$2 === void 0 ? void 0 : _res$2.dataIndex;
463
380
  var originalItem = currentData[dataIndex];
464
- return "<div class='onesight-chart-common-bar-tooltip-box' style=\"width:278px;position: relative;\">\n ".concat(isTooltipTitleShow ? "<div class=\"tooltip-head\">\n ".concat(res[0].format || res[0].name, "\n </div>") : '', "\n <div class='tooltip-body'>\n ").concat(dataArr.map(function (item) {
465
- // 合并原始数据的 alias、alias2 和 aliasArray 字段到 item 中
381
+ return "<div class='onesight-chart-common-bar-tooltip-box' style=\"width:278px;position: relative;\">\n ".concat(isTooltipTitleShow ? "<div class=\"tooltip-head\">".concat(res[0].format || res[0].name, "</div>") : '', "\n <div class='tooltip-body'>\n ").concat(dataArr.map(function (item) {
382
+ var _item$data;
383
+ var raw = (item === null || item === void 0 || (_item$data = item.data) === null || _item$data === void 0 ? void 0 : _item$data.rawValue) !== undefined ? item.data.rawValue : item.value;
466
384
  var itemWithAlias = _objectSpread(_objectSpread({}, item), {}, {
467
385
  alias: originalItem === null || originalItem === void 0 ? void 0 : originalItem.alias,
468
386
  alias2: originalItem === null || originalItem === void 0 ? void 0 : originalItem.alias2,
469
- aliasArray: originalItem === null || originalItem === void 0 ? void 0 : originalItem.aliasArray
387
+ aliasArray: originalItem === null || originalItem === void 0 ? void 0 : originalItem.aliasArray,
388
+ rawValue: raw
470
389
  });
471
- // 将 JSON 字符串转义为安全的 HTML 属性值
472
390
  var escapedJson = escapeHtmlAttribute(JSON.stringify(itemWithAlias));
473
- return "<div class='item' data-series-item=\"".concat(escapedJson, "\" key='").concat(item.seriesName, "'>\n <div class='l'>\n <span style=\"display:inline-block;width: 14px;vertical-align: middle;height: 14px;background-color:").concat(currentColor, ";border-radius: 4px;margin-bottom: 2px;margin-right:6px\"></span>\n <span>").concat(tooltipItemName ? res[0].format || res[0].name : tipName, "\n </span>\n </div>\n <div class='r' style=\"padding-left:6px;\">\n <span class='num'>\n ").concat(showProportion ? computeFloat(item.value) : changeDataTypeEn(item.value), "\n </span>\n </div>\n </div>");
474
- }).join(''), "\n </div>\n <div class='triangle-down' style='width:").concat(triangleWidth, "px'></div>\n </div>");
391
+ return "<div class='item' data-series-item=\"".concat(escapedJson, "\" key='").concat(item.seriesName, "'>\n <div class='l'>\n <span style=\"display:inline-block;width: 14px;vertical-align: middle;height: 14px;background-color:").concat(currentColor, ";border-radius: 4px;margin-bottom: 2px;margin-right:6px\"></span>\n <span>").concat(tooltipItemName ? res[0].format || res[0].name : tipName, "</span>\n </div>\n <div class='r' style=\"padding-left:6px;\">\n <span class='num'>").concat(showProportion ? computeFloat(raw) : changeDataTypeEn(raw), "</span>\n </div>\n </div>");
392
+ }).join(''), "\n </div>\n <div class='triangle-down' style='width:").concat(triangleWidth, "px'></div>\n </div>");
475
393
  }
476
394
  },
477
395
  animation: true,
@@ -482,16 +400,15 @@ function CommonBar(props) {
482
400
  },
483
401
  grid: {
484
402
  top: 0,
485
- // bottom: 30,
486
403
  bottom: 0,
487
404
  left: 12,
488
- right: hasNegative ? 30 : 0,
405
+ right: 0,
489
406
  containLabel: true
490
407
  },
491
408
  xAxis: {
492
409
  type: 'value',
493
410
  max: bgValue,
494
- min: hasNegative ? minBgValue : undefined,
411
+ min: minBgValue,
495
412
  show: false,
496
413
  axisLine: {
497
414
  show: false
@@ -516,30 +433,13 @@ function CommonBar(props) {
516
433
  show: true,
517
434
  interval: 0,
518
435
  rotate: 0,
519
- // width: 188,
520
436
  overflow: 'truncate',
521
437
  ellipsis: '...',
522
- // formatter: function (value, index) {
523
- // // 检查当前项是否有 platformIcon
524
- // if (yIconFlag) {
525
- // return `{icon${index}|} {label|${value}}`;
526
- // } else {
527
- // return value;
528
- // }
529
- // },
530
438
  formatter: function formatter(value, index) {
531
439
  var _currentData$index;
532
- // 这一行有没有图标?
533
440
  var rowHasIcon = !!(yIconFlag && (_currentData$index = currentData[index]) !== null && _currentData$index !== void 0 && _currentData$index.platformIcon);
534
-
535
- // 这一行文本可用的最大宽度(扣除图标)
536
441
  var maxPx = getMaxTextWidthForRow(rowHasIcon);
537
-
538
- // 得到“中间省略版”文本
539
- var finalText = middleEllipsis(value, maxPx, '14px sans-serif' // 跟 axisLabel 字体保持一致
540
- );
541
-
542
- // 按是否有 icon,返回富文本还是普通文本
442
+ var finalText = middleEllipsis(value, maxPx, '14px sans-serif');
543
443
  if (yIconFlag) {
544
444
  return "{icon".concat(index, "|} {label|").concat(finalText, "}");
545
445
  } else {
@@ -559,52 +459,40 @@ function CommonBar(props) {
559
459
  data: axisData
560
460
  },
561
461
  series: [{
562
- // === 背景柱系列 ===
563
- // 需要背景柱的原因是让柱状条加上后面的数字标签的和不超过悬浮上去的阴影的长度
564
462
  name: '背景条',
565
463
  type: 'bar',
566
- // 让它在最底层
567
464
  z: 1,
568
- // 不需要点击/hover 交互
569
465
  silent: true,
570
- // 让柱子和后面的柱子重叠在同一个类目位置
571
466
  barGap: '-100%',
572
467
  emphasis: {
573
468
  disabled: true
574
469
  },
575
- // 柱子的样式
576
470
  itemStyle: {
577
- color: 'rgba(0, 0, 0, 0)' // 背景色可自定义
471
+ color: 'rgba(0, 0, 0, 0)'
578
472
  },
579
- // 这里的 data 根据正负数使用不同的背景值
580
473
  data: currentData.map(function (item) {
581
- var value = valueAccessor(item);
582
- return value < 0 ? minBgValue : bgValue;
474
+ var v = valueAccessor(item);
475
+ return v < 0 ? minBgValue : bgValue;
583
476
  }),
584
- // 根据你需要的柱宽
585
- // barMaxWidth: 42,
586
- // barMinWidth: 16,
587
477
  barWidth: calculateWidth(seriesData.length),
478
+ // 这里留着也无所谓,但“最小可见长度”由方案B控制
588
479
  barMinHeight: 4,
480
+ barMinWidth: 4,
589
481
  cursor: 'pointer',
590
482
  animation: false,
591
- showBackground: false // 这层本身不再需要 showBackground
483
+ showBackground: false
592
484
  }, {
593
485
  type: 'bar',
594
- // showBackground: true,
595
486
  label: {
596
487
  show: true,
597
- // position: 'right',
598
488
  fontWeight: 400,
599
489
  fontSize: 14,
600
490
  color: '#515E5F',
601
491
  distance: 5,
602
492
  formatter: function formatter(params) {
603
- if (showProportion) {
604
- return computeFloat(params.value);
605
- } else {
606
- return numberFormatNull(params.value);
607
- }
493
+ var _params$data$rawValue, _params$data;
494
+ var raw = (_params$data$rawValue = params === null || params === void 0 || (_params$data = params.data) === null || _params$data === void 0 ? void 0 : _params$data.rawValue) !== null && _params$data$rawValue !== void 0 ? _params$data$rawValue : params.value;
495
+ return showProportion ? computeFloat(raw) : numberFormatNull(raw);
608
496
  }
609
497
  },
610
498
  emphasis: {
@@ -615,10 +503,9 @@ function CommonBar(props) {
615
503
  borderWidth: 0,
616
504
  borderType: 'solid'
617
505
  },
618
- // barMaxWidth: 42,
619
- // barMinWidth: 16,
620
506
  barWidth: calculateWidth(seriesData.length),
621
507
  barMinHeight: 4,
508
+ barMinWidth: 4,
622
509
  cursor: 'pointer',
623
510
  animation: false,
624
511
  data: seriesData
@@ -661,9 +548,7 @@ function CommonBar(props) {
661
548
  });
662
549
  myChart.on('showTip', function (_ref) {
663
550
  var dataIndex = _ref.dataIndex;
664
- // 鼠标微移时不重复更新
665
551
  if (dataIndex === lastIndex) return;
666
- // 生成淡化后的数组(只改非当前柱)
667
552
  fadedData = originalData.map(function (d, i) {
668
553
  return _objectSpread(_objectSpread({}, d), {}, {
669
554
  itemStyle: _objectSpread(_objectSpread({}, d.itemStyle || {}), {}, {
@@ -677,7 +562,6 @@ function CommonBar(props) {
677
562
  });
678
563
  myChart.on('hideTip', function () {
679
564
  if (lastIndex === null) return;
680
- // 恢复全部不透明
681
565
  setBarData(myChart, originalData);
682
566
  toggleAxisPointer(myChart, false);
683
567
  lastIndex = null;
@@ -692,7 +576,6 @@ function CommonBar(props) {
692
576
  element.addEventListener('mouseleave', function (event) {
693
577
  if (event && element.offsetHeight && event.offsetY < element.offsetHeight - 2) {
694
578
  if (lastIndex === null) return;
695
- // 恢复全部不透明
696
579
  setBarData(myChart, originalData);
697
580
  myChart.dispatchAction({
698
581
  type: 'hideTip'