onesight-charts 1.4.2 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/onesight-charts.min.css +1 -1
- package/dist/onesight-charts.min.js +1 -1
- package/es/components/common-bar/demo/base.js +50 -50
- package/es/components/common-bar/demo/diverging.js +48 -76
- package/es/components/common-bar/demo/yIcon.js +24 -12
- package/es/components/common-bar/index.js +253 -298
- package/es/components/common-bar/style.scss +13 -2
- package/es/components/pie/demo/demo.js +18 -9
- package/es/components/pie/style.scss +15 -1
- package/es/components/pie/tooltipConfig.js +1 -1
- package/es/components/stacked-bar/demo/base.js +56 -28
- package/es/components/stacked-bar/index.js +5 -1
- package/es/components/stacked-bar/style.scss +14 -1
- package/lib/components/common-bar/demo/base.js +50 -52
- package/lib/components/common-bar/demo/diverging.js +48 -80
- package/lib/components/common-bar/demo/yIcon.js +24 -12
- package/lib/components/common-bar/index.js +242 -291
- package/lib/components/common-bar/style.scss +13 -2
- package/lib/components/pie/demo/demo.js +18 -9
- package/lib/components/pie/style.scss +15 -1
- package/lib/components/pie/tooltipConfig.js +1 -0
- package/lib/components/stacked-bar/demo/base.js +56 -28
- package/lib/components/stacked-bar/index.js +7 -3
- package/lib/components/stacked-bar/style.scss +14 -1
- package/package.json +1 -1
|
@@ -55,37 +55,13 @@ function CommonBar(props) {
|
|
|
55
55
|
}
|
|
56
56
|
} = props;
|
|
57
57
|
const [total, setTotal] = (0, import_react.useState)(0);
|
|
58
|
-
|
|
58
|
+
const chart = (0, import_react.useRef)(null);
|
|
59
59
|
const [currentPage, setCurrentPage] = (0, import_react.useState)(1);
|
|
60
60
|
const chartRef = (0, import_react.useRef)(null);
|
|
61
61
|
const prevDepsRef = (0, import_react.useRef)(null);
|
|
62
62
|
const tooltipClassNameRef = (0, import_react.useRef)(
|
|
63
63
|
`onesight-chart-common-bar-tooltip-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
|
|
64
64
|
);
|
|
65
|
-
(0, import_react.useEffect)(() => {
|
|
66
|
-
const currentDeps = JSON.stringify({ currentPage, data });
|
|
67
|
-
const prevDeps = prevDepsRef.current;
|
|
68
|
-
if (prevDeps !== null && currentDeps === prevDeps) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
prevDepsRef.current = currentDeps;
|
|
72
|
-
let copyData = JSON.parse(JSON.stringify(data));
|
|
73
|
-
let splice_data = copyData.slice(
|
|
74
|
-
(currentPage - 1) * number,
|
|
75
|
-
currentPage * number
|
|
76
|
-
);
|
|
77
|
-
if (data.length) {
|
|
78
|
-
setTotal(Math.ceil(data.length / number));
|
|
79
|
-
}
|
|
80
|
-
init2(splice_data);
|
|
81
|
-
callbackGetPage(currentPage);
|
|
82
|
-
setTimeout(() => {
|
|
83
|
-
bindClickEvents();
|
|
84
|
-
}, 0);
|
|
85
|
-
return () => {
|
|
86
|
-
unbindClickEvents();
|
|
87
|
-
};
|
|
88
|
-
}, [currentPage, data, bindClickEvents, unbindClickEvents]);
|
|
89
65
|
const paginationCb = (currData, page) => {
|
|
90
66
|
setCurrentPage(page);
|
|
91
67
|
};
|
|
@@ -94,15 +70,13 @@ function CommonBar(props) {
|
|
|
94
70
|
const tooltipElement = event.target.closest(
|
|
95
71
|
`.${tooltipClassNameRef.current}`
|
|
96
72
|
);
|
|
97
|
-
if (!tooltipElement)
|
|
73
|
+
if (!tooltipElement)
|
|
98
74
|
return;
|
|
99
|
-
}
|
|
100
75
|
const seriesNameElement = event.target.closest(".item");
|
|
101
76
|
if (seriesNameElement) {
|
|
102
77
|
const seriesItem = seriesNameElement.getAttribute("data-series-item");
|
|
103
|
-
if (!seriesItem)
|
|
78
|
+
if (!seriesItem)
|
|
104
79
|
return;
|
|
105
|
-
}
|
|
106
80
|
const seriesData = JSON.parse(seriesItem);
|
|
107
81
|
handleClick && handleClick("tooltipType", seriesData);
|
|
108
82
|
}
|
|
@@ -121,6 +95,35 @@ function CommonBar(props) {
|
|
|
121
95
|
chartElement.removeEventListener("click", onChartClick);
|
|
122
96
|
}
|
|
123
97
|
}, [onChartClick]);
|
|
98
|
+
(0, import_react.useEffect)(() => {
|
|
99
|
+
const currentDeps = JSON.stringify({ currentPage, data });
|
|
100
|
+
const prevDeps = prevDepsRef.current;
|
|
101
|
+
if (prevDeps !== null && currentDeps === prevDeps)
|
|
102
|
+
return;
|
|
103
|
+
prevDepsRef.current = currentDeps;
|
|
104
|
+
const copyData = JSON.parse(JSON.stringify(data));
|
|
105
|
+
const splice_data = copyData.slice(
|
|
106
|
+
(currentPage - 1) * number,
|
|
107
|
+
currentPage * number
|
|
108
|
+
);
|
|
109
|
+
if (data.length)
|
|
110
|
+
setTotal(Math.ceil(data.length / number));
|
|
111
|
+
init2(splice_data);
|
|
112
|
+
callbackGetPage(currentPage);
|
|
113
|
+
setTimeout(() => {
|
|
114
|
+
bindClickEvents();
|
|
115
|
+
}, 0);
|
|
116
|
+
return () => {
|
|
117
|
+
unbindClickEvents();
|
|
118
|
+
};
|
|
119
|
+
}, [
|
|
120
|
+
currentPage,
|
|
121
|
+
data,
|
|
122
|
+
bindClickEvents,
|
|
123
|
+
unbindClickEvents,
|
|
124
|
+
number,
|
|
125
|
+
callbackGetPage
|
|
126
|
+
]);
|
|
124
127
|
function toggleAxisPointer(myChart, show) {
|
|
125
128
|
myChart.setOption({
|
|
126
129
|
tooltip: {
|
|
@@ -136,35 +139,30 @@ function CommonBar(props) {
|
|
|
136
139
|
return String(jsonString).replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
137
140
|
}
|
|
138
141
|
const calculateWidth = (len) => {
|
|
139
|
-
if (len === 1 || len === 2 || len === 3)
|
|
142
|
+
if (len === 1 || len === 2 || len === 3)
|
|
140
143
|
return 42;
|
|
141
|
-
|
|
144
|
+
if (len === 4)
|
|
142
145
|
return 40;
|
|
143
|
-
|
|
146
|
+
if (len === 5)
|
|
144
147
|
return 32;
|
|
145
|
-
|
|
148
|
+
if (len === 6)
|
|
146
149
|
return 26;
|
|
147
|
-
|
|
150
|
+
if (len === 7)
|
|
148
151
|
return 24;
|
|
149
|
-
|
|
152
|
+
if (len === 8)
|
|
150
153
|
return 20;
|
|
151
|
-
|
|
154
|
+
if (len === 9)
|
|
152
155
|
return 18;
|
|
153
|
-
|
|
156
|
+
if (len === 10)
|
|
154
157
|
return 16;
|
|
155
|
-
|
|
158
|
+
return 16;
|
|
156
159
|
};
|
|
157
160
|
function setBarData(myChart, newData) {
|
|
158
161
|
if (!myChart)
|
|
159
162
|
return;
|
|
160
163
|
myChart.setOption(
|
|
161
164
|
{
|
|
162
|
-
series: [
|
|
163
|
-
// 背景柱(seriesIndex 0)保持不变
|
|
164
|
-
{},
|
|
165
|
-
// 前景柱(seriesIndex 1)换成新数组
|
|
166
|
-
{ data: newData }
|
|
167
|
-
]
|
|
165
|
+
series: [{}, { data: newData }]
|
|
168
166
|
},
|
|
169
167
|
false
|
|
170
168
|
);
|
|
@@ -180,14 +178,10 @@ function CommonBar(props) {
|
|
|
180
178
|
fontWeight: 500,
|
|
181
179
|
lineHeight: 20,
|
|
182
180
|
align: "right",
|
|
183
|
-
// 文本宽度 = 总宽 - 图标宽度 - 间距
|
|
184
|
-
// width: Math.max(0, maxLabelWidth - ICON_SIZE - ICON_GAP),
|
|
185
181
|
overflow: "truncate",
|
|
186
182
|
ellipsis: "...",
|
|
187
|
-
// 如果没有任何图标,则不需要左边距
|
|
188
183
|
padding: hasAnyIcon ? [0, 0, 0, ICON_GAP] : [0, 0, 0, 0]
|
|
189
184
|
},
|
|
190
|
-
// 为没有图标的项目创建一个空的样式
|
|
191
185
|
noIcon: {
|
|
192
186
|
width: 0,
|
|
193
187
|
height: 0
|
|
@@ -200,15 +194,10 @@ function CommonBar(props) {
|
|
|
200
194
|
height: ICON_SIZE,
|
|
201
195
|
align: "right",
|
|
202
196
|
borderRadius: 4,
|
|
203
|
-
// 这里用图片作为文本块的背景
|
|
204
197
|
backgroundColor: { image: row.platformIcon }
|
|
205
|
-
// 建议传绝对路径或 public 下的路径
|
|
206
198
|
};
|
|
207
199
|
} else {
|
|
208
|
-
rich[`icon${i}`] = {
|
|
209
|
-
width: 0,
|
|
210
|
-
height: 0
|
|
211
|
-
};
|
|
200
|
+
rich[`icon${i}`] = { width: 0, height: 0 };
|
|
212
201
|
}
|
|
213
202
|
});
|
|
214
203
|
return rich;
|
|
@@ -221,9 +210,8 @@ function CommonBar(props) {
|
|
|
221
210
|
if (!labelText)
|
|
222
211
|
return "";
|
|
223
212
|
const fullRect = echarts.format.getTextRect(labelText, font);
|
|
224
|
-
if (fullRect.width <= maxWidthPx)
|
|
213
|
+
if (fullRect.width <= maxWidthPx)
|
|
225
214
|
return labelText;
|
|
226
|
-
}
|
|
227
215
|
const DOT = "...";
|
|
228
216
|
const dotW = echarts.format.getTextRect(DOT, font).width;
|
|
229
217
|
let prefixLen = 1;
|
|
@@ -239,17 +227,26 @@ function CommonBar(props) {
|
|
|
239
227
|
best = candidate;
|
|
240
228
|
bestW = w;
|
|
241
229
|
prefixLen++;
|
|
242
|
-
if (prefixLen % 2 === 0)
|
|
230
|
+
if (prefixLen % 2 === 0)
|
|
243
231
|
suffixLen++;
|
|
244
|
-
}
|
|
245
232
|
} else {
|
|
246
233
|
break;
|
|
247
234
|
}
|
|
248
235
|
}
|
|
249
236
|
return best;
|
|
250
237
|
}
|
|
238
|
+
function getGridPlotWidth(myChart) {
|
|
239
|
+
var _a, _b, _c, _d;
|
|
240
|
+
try {
|
|
241
|
+
const grid = (_b = (_a = myChart.getModel()) == null ? void 0 : _a.getComponent) == null ? void 0 : _b.call(_a, "grid");
|
|
242
|
+
const rect = (_d = (_c = grid == null ? void 0 : grid.coordinateSystem) == null ? void 0 : _c.getRect) == null ? void 0 : _d.call(_c);
|
|
243
|
+
if (rect == null ? void 0 : rect.width)
|
|
244
|
+
return rect.width;
|
|
245
|
+
} catch (e) {
|
|
246
|
+
}
|
|
247
|
+
return myChart.getWidth();
|
|
248
|
+
}
|
|
251
249
|
const init2 = (currentData) => {
|
|
252
|
-
var _a;
|
|
253
250
|
let myChart = null;
|
|
254
251
|
const myDom = chartRef.current;
|
|
255
252
|
myChart = echarts.getInstanceByDom(myDom);
|
|
@@ -257,143 +254,154 @@ function CommonBar(props) {
|
|
|
257
254
|
if (!myChart) {
|
|
258
255
|
myChart = echarts.init(myDom, null, { renderer: "svg" });
|
|
259
256
|
}
|
|
257
|
+
myChart.off("showTip");
|
|
258
|
+
myChart.off("hideTip");
|
|
259
|
+
myChart.off("finished");
|
|
260
|
+
myChart.getZr().off("click");
|
|
260
261
|
let fadedData = null;
|
|
261
262
|
let lastIndex = null;
|
|
262
263
|
const axisData = currentData.map((item) => item.format || item.name || "-");
|
|
263
|
-
|
|
264
|
+
const yIconFlag = currentData == null ? void 0 : currentData.some((d) => d == null ? void 0 : d.platformIcon);
|
|
265
|
+
const valueAccessor = (item) => showProportion ? (item == null ? void 0 : item.proportion) || 0 : item.value || 0;
|
|
266
|
+
const rawVals = currentData.map(valueAccessor);
|
|
267
|
+
const rawMax = Math.max(0, ...rawVals);
|
|
268
|
+
const rawMin = Math.min(0, ...rawVals);
|
|
269
|
+
const FONT = "14px sans-serif";
|
|
270
|
+
const formatLabel = (v) => showProportion ? (0, import_chartUtils.computeFloat)(v) : (0, import_chartUtils.numberFormatNull)(v);
|
|
271
|
+
const rightLabelText = rawMax > 0 ? formatLabel(rawMax) : "";
|
|
272
|
+
const rightLabelW = rightLabelText ? echarts.format.getTextRect(rightLabelText, FONT).width : 0;
|
|
273
|
+
const leftLabelText = rawMin < 0 ? formatLabel(rawMin) : "";
|
|
274
|
+
const leftLabelW = leftLabelText ? echarts.format.getTextRect(leftLabelText, FONT).width : 0;
|
|
275
|
+
const LABEL_DISTANCE = 5;
|
|
276
|
+
const SAFE_PX = 24;
|
|
277
|
+
const rightSpacePx = rawMax > 0 ? rightLabelW + LABEL_DISTANCE + SAFE_PX : 0;
|
|
278
|
+
const leftSpacePx = rawMin < 0 ? leftLabelW + LABEL_DISTANCE + SAFE_PX : 0;
|
|
279
|
+
const baseOption = {
|
|
280
|
+
tooltip: { show: false },
|
|
281
|
+
animation: false,
|
|
282
|
+
legend: { show: false },
|
|
283
|
+
grid: {
|
|
284
|
+
top: 0,
|
|
285
|
+
bottom: 0,
|
|
286
|
+
left: 12,
|
|
287
|
+
right: 0,
|
|
288
|
+
containLabel: true
|
|
289
|
+
},
|
|
290
|
+
xAxis: {
|
|
291
|
+
type: "value",
|
|
292
|
+
min: rawMin,
|
|
293
|
+
max: rawMax,
|
|
294
|
+
show: false,
|
|
295
|
+
axisLine: { show: false },
|
|
296
|
+
axisLabel: { show: false },
|
|
297
|
+
splitLine: { show: false },
|
|
298
|
+
boundaryGap: false
|
|
299
|
+
},
|
|
300
|
+
yAxis: {
|
|
301
|
+
type: "category",
|
|
302
|
+
inverse: true,
|
|
303
|
+
axisLabel: {
|
|
304
|
+
margin: rawMin < 0 ? 40 : 10,
|
|
305
|
+
color: "#273333",
|
|
306
|
+
fontSize: 14,
|
|
307
|
+
fontWeight: 500,
|
|
308
|
+
lineHeight: 20,
|
|
309
|
+
show: true,
|
|
310
|
+
interval: 0,
|
|
311
|
+
rotate: 0,
|
|
312
|
+
overflow: "truncate",
|
|
313
|
+
ellipsis: "...",
|
|
314
|
+
formatter: function(value, index) {
|
|
315
|
+
var _a;
|
|
316
|
+
const rowHasIcon = !!(yIconFlag && ((_a = currentData[index]) == null ? void 0 : _a.platformIcon));
|
|
317
|
+
const maxPx = getMaxTextWidthForRow(rowHasIcon);
|
|
318
|
+
const finalText = middleEllipsis(value, maxPx, FONT);
|
|
319
|
+
if (yIconFlag)
|
|
320
|
+
return `{icon${index}|} {label|${finalText}}`;
|
|
321
|
+
return finalText;
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
axisTick: { show: false },
|
|
325
|
+
axisLine: { show: false },
|
|
326
|
+
splitLine: { show: false },
|
|
327
|
+
data: axisData
|
|
328
|
+
},
|
|
329
|
+
series: [
|
|
330
|
+
{
|
|
331
|
+
type: "bar",
|
|
332
|
+
data: rawVals
|
|
333
|
+
}
|
|
334
|
+
]
|
|
335
|
+
};
|
|
336
|
+
if (yIconFlag) {
|
|
337
|
+
baseOption.yAxis.axisLabel.rich = makeYAxisRich(currentData);
|
|
338
|
+
}
|
|
339
|
+
myChart.setOption(baseOption, true);
|
|
340
|
+
const plotW = Math.max(1, getGridPlotWidth(myChart));
|
|
341
|
+
const calcAxisRange = (baseMin2, baseMax2) => {
|
|
342
|
+
const rL = Math.min(0.45, Math.max(0, leftSpacePx / plotW));
|
|
343
|
+
const rR = Math.min(0.45, Math.max(0, rightSpacePx / plotW));
|
|
344
|
+
const denom = Math.max(0.1, 1 - rL - rR);
|
|
345
|
+
let baseSpan = baseMax2 - baseMin2;
|
|
346
|
+
if (!isFinite(baseSpan) || baseSpan === 0)
|
|
347
|
+
baseSpan = 1;
|
|
348
|
+
const span = baseSpan / denom;
|
|
349
|
+
const xMin = baseMin2 - rL * span;
|
|
350
|
+
const xMax = baseMax2 + rR * span;
|
|
351
|
+
return { xMin, xMax, span };
|
|
352
|
+
};
|
|
353
|
+
const MIN_BAR_PX = 4;
|
|
354
|
+
const minVisibleAbsFloor = showProportion ? 0 : 1;
|
|
355
|
+
let baseMin = rawMin;
|
|
356
|
+
let baseMax = rawMax;
|
|
357
|
+
let axis = calcAxisRange(baseMin, baseMax);
|
|
358
|
+
let minVisibleValue = axis.span * (MIN_BAR_PX / plotW) || minVisibleAbsFloor;
|
|
359
|
+
minVisibleValue = Math.max(minVisibleValue, minVisibleAbsFloor);
|
|
360
|
+
const hasPos = rawMax > 0;
|
|
361
|
+
const hasNeg = rawMin < 0;
|
|
362
|
+
const effectiveMax = hasPos ? Math.max(rawMax, minVisibleValue) : 0;
|
|
363
|
+
const effectiveMin = hasNeg ? Math.min(rawMin, -minVisibleValue) : 0;
|
|
364
|
+
if (effectiveMax !== baseMax || effectiveMin !== baseMin) {
|
|
365
|
+
baseMax = effectiveMax;
|
|
366
|
+
baseMin = effectiveMin;
|
|
367
|
+
axis = calcAxisRange(baseMin, baseMax);
|
|
368
|
+
minVisibleValue = axis.span * (MIN_BAR_PX / plotW) || minVisibleAbsFloor;
|
|
369
|
+
minVisibleValue = Math.max(minVisibleValue, minVisibleAbsFloor);
|
|
370
|
+
}
|
|
371
|
+
const xAxisMin = axis.xMin;
|
|
372
|
+
const xAxisMax = axis.xMax;
|
|
373
|
+
const seriesData = currentData.map((item) => {
|
|
264
374
|
const itemColor = item.color || barColor;
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
};
|
|
275
|
-
} else {
|
|
276
|
-
return {
|
|
277
|
-
name: item.name || "-",
|
|
278
|
-
value: item.value || 0,
|
|
279
|
-
label: {
|
|
280
|
-
// 负数就把文字放左边,正数/0 放右边
|
|
281
|
-
position: item.value < 0 ? "left" : "right"
|
|
282
|
-
},
|
|
283
|
-
itemStyle: item.value ? { color: itemColor } : { color: "rgba(29, 169, 160, 0)" }
|
|
284
|
-
};
|
|
285
|
-
}
|
|
375
|
+
const raw = valueAccessor(item);
|
|
376
|
+
const displayValue = raw === 0 ? 0 : Math.sign(raw) * Math.max(Math.abs(raw), minVisibleValue);
|
|
377
|
+
return {
|
|
378
|
+
name: item.name || "-",
|
|
379
|
+
rawValue: raw,
|
|
380
|
+
value: displayValue,
|
|
381
|
+
label: { position: raw < 0 ? "left" : "right" },
|
|
382
|
+
itemStyle: raw ? { color: itemColor } : { color: "rgba(29, 169, 160, 0)" }
|
|
383
|
+
};
|
|
286
384
|
});
|
|
287
385
|
const originalData = seriesData.map((d) => ({
|
|
288
386
|
...d,
|
|
289
387
|
itemStyle: { ...d.itemStyle || {}, opacity: 1 }
|
|
290
388
|
}));
|
|
291
|
-
|
|
292
|
-
...currentData.map(
|
|
293
|
-
(item) => showProportion ? item == null ? void 0 : item.proportion : item.value
|
|
294
|
-
)
|
|
295
|
-
);
|
|
296
|
-
const ySample = axisData.reduce(
|
|
297
|
-
(a, b) => a.length > b.length ? a : b,
|
|
298
|
-
""
|
|
299
|
-
);
|
|
300
|
-
const yLabelWidth = echarts.format.getTextRect(
|
|
301
|
-
ySample,
|
|
302
|
-
"14px sans-serif"
|
|
303
|
-
).width;
|
|
304
|
-
const axisLabelGap = 10;
|
|
305
|
-
const chartWidth = myChart.getWidth();
|
|
306
|
-
const leftPadding = 12;
|
|
307
|
-
const rightPadding = 0;
|
|
308
|
-
const gridWidth = chartWidth - leftPadding - rightPadding;
|
|
309
|
-
const dealYLabelWidth = yLabelWidth > 188 ? 188 : yLabelWidth;
|
|
310
|
-
const barAreaWidth = gridWidth - dealYLabelWidth - axisLabelGap;
|
|
311
|
-
const sampleText = showProportion ? (0, import_chartUtils.computeFloat)(maxDataValue) : (0, import_chartUtils.numberFormatNull)(maxDataValue);
|
|
312
|
-
const labelWidth = echarts.format.getTextRect(
|
|
313
|
-
sampleText,
|
|
314
|
-
"14px sans-serif"
|
|
315
|
-
).width;
|
|
316
|
-
const extra = 15;
|
|
317
|
-
const yIconFlag = (_a = data[0]) == null ? void 0 : _a.platformIcon;
|
|
318
|
-
const valueAccessor = (item) => showProportion ? (item == null ? void 0 : item.proportion) || 0 : item.value || 0;
|
|
319
|
-
const minDataValue = Math.min(...currentData.map(valueAccessor));
|
|
320
|
-
const hasNegative = minDataValue < 0;
|
|
321
|
-
const allNegative = maxDataValue < 0;
|
|
322
|
-
let bgValue;
|
|
323
|
-
if (allNegative) {
|
|
324
|
-
bgValue = 0;
|
|
325
|
-
} else if (barAreaWidth > labelWidth + extra) {
|
|
326
|
-
bgValue = maxDataValue * barAreaWidth / (barAreaWidth - labelWidth - extra);
|
|
327
|
-
} else {
|
|
328
|
-
const overflowPx = labelWidth + extra - barAreaWidth;
|
|
329
|
-
const unitPerPx = maxDataValue / barAreaWidth;
|
|
330
|
-
bgValue = maxDataValue + overflowPx * unitPerPx;
|
|
331
|
-
}
|
|
332
|
-
let minBgValue = 0;
|
|
333
|
-
if (hasNegative) {
|
|
334
|
-
const absMinDataValue = Math.abs(minDataValue);
|
|
335
|
-
const absMaxDataValue = Math.abs(maxDataValue);
|
|
336
|
-
const minLabelSample = showProportion ? (0, import_chartUtils.computeFloat)(absMinDataValue) : (0, import_chartUtils.numberFormatNull)(absMinDataValue);
|
|
337
|
-
const minLabelWidth = echarts.format.getTextRect(
|
|
338
|
-
minLabelSample,
|
|
339
|
-
"14px sans-serif"
|
|
340
|
-
).width;
|
|
341
|
-
const minExtra = 15;
|
|
342
|
-
const totalDataRange = absMinDataValue + absMaxDataValue;
|
|
343
|
-
let negativeBarAreaWidth;
|
|
344
|
-
if (allNegative) {
|
|
345
|
-
negativeBarAreaWidth = barAreaWidth;
|
|
346
|
-
} else if (totalDataRange > 0) {
|
|
347
|
-
if (absMinDataValue < absMaxDataValue * 0.3) {
|
|
348
|
-
negativeBarAreaWidth = Math.min(
|
|
349
|
-
minLabelWidth + minExtra + 30,
|
|
350
|
-
barAreaWidth * 0.25
|
|
351
|
-
);
|
|
352
|
-
} else {
|
|
353
|
-
const ratio = absMinDataValue / totalDataRange;
|
|
354
|
-
negativeBarAreaWidth = barAreaWidth * ratio;
|
|
355
|
-
negativeBarAreaWidth = Math.max(
|
|
356
|
-
negativeBarAreaWidth,
|
|
357
|
-
minLabelWidth + minExtra + 20
|
|
358
|
-
);
|
|
359
|
-
}
|
|
360
|
-
} else {
|
|
361
|
-
negativeBarAreaWidth = barAreaWidth * 0.5;
|
|
362
|
-
}
|
|
363
|
-
const availableBarWidth = Math.max(
|
|
364
|
-
1,
|
|
365
|
-
negativeBarAreaWidth - minLabelWidth - minExtra
|
|
366
|
-
);
|
|
367
|
-
const dataPerPixel = absMinDataValue / availableBarWidth;
|
|
368
|
-
const labelSpaceInData = (minLabelWidth + minExtra) * dataPerPixel;
|
|
369
|
-
minBgValue = -(absMinDataValue + labelSpaceInData);
|
|
370
|
-
if (maxDataValue > 0 && !allNegative) {
|
|
371
|
-
const positiveBarAreaWidth = barAreaWidth - negativeBarAreaWidth;
|
|
372
|
-
if (positiveBarAreaWidth > labelWidth + extra) {
|
|
373
|
-
bgValue = maxDataValue * positiveBarAreaWidth / (positiveBarAreaWidth - labelWidth - extra);
|
|
374
|
-
} else {
|
|
375
|
-
const overflowPx = labelWidth + extra - positiveBarAreaWidth;
|
|
376
|
-
const unitPerPx = maxDataValue / Math.max(positiveBarAreaWidth, 1);
|
|
377
|
-
bgValue = maxDataValue + overflowPx * unitPerPx;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
let option = {
|
|
389
|
+
const option = {
|
|
382
390
|
tooltip: {
|
|
383
391
|
className: `onesight-chart-common-bar-tooltip ${tooltipClassNameRef.current}`,
|
|
384
392
|
trigger: "axis",
|
|
385
393
|
enterable: true,
|
|
394
|
+
padding: 0,
|
|
386
395
|
// showContent: true,
|
|
387
396
|
// alwaysShowContent: true,
|
|
388
397
|
// hideDelay: 1000000000,
|
|
389
|
-
padding: 0,
|
|
390
398
|
position: (point, params, dom) => {
|
|
391
399
|
const tooltipHeight = (dom == null ? void 0 : dom.offsetHeight) || 0;
|
|
392
400
|
const currentHeight = myDom.offsetHeight;
|
|
393
|
-
|
|
401
|
+
const len = axisData.length > 10 ? 10 : axisData.length;
|
|
394
402
|
let yValue = 0;
|
|
395
403
|
if (tooltipHeight) {
|
|
396
|
-
|
|
404
|
+
const dataIndex = params[0].dataIndex;
|
|
397
405
|
yValue = currentHeight / len * dataIndex - tooltipHeight - 12;
|
|
398
406
|
}
|
|
399
407
|
return [290 - (278 + 2) / 2, yValue];
|
|
@@ -401,89 +409,76 @@ function CommonBar(props) {
|
|
|
401
409
|
axisPointer: {
|
|
402
410
|
type: "shadow",
|
|
403
411
|
z: 1,
|
|
404
|
-
shadowStyle: {
|
|
405
|
-
color: "rgba(243,244,244,1)"
|
|
406
|
-
},
|
|
412
|
+
shadowStyle: { color: "rgba(243,244,244,1)" },
|
|
407
413
|
clickable: true
|
|
408
414
|
},
|
|
409
415
|
formatter: (res) => {
|
|
410
|
-
var
|
|
411
|
-
if (!res.some((i) => i.value !== void 0 && i.value !== null))
|
|
416
|
+
var _a, _b;
|
|
417
|
+
if (!res.some((i) => i.value !== void 0 && i.value !== null))
|
|
412
418
|
return "";
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
let triangleWidth = 280;
|
|
419
|
+
const dataArr = [res[1]];
|
|
420
|
+
const currentColor = ((_a = res[1]) == null ? void 0 : _a.color) || "#1DA9A0";
|
|
421
|
+
const triangleWidth = 280;
|
|
417
422
|
const dataIndex = (_b = res[1]) == null ? void 0 : _b.dataIndex;
|
|
418
423
|
const originalItem = currentData[dataIndex];
|
|
419
424
|
return `<div class='onesight-chart-common-bar-tooltip-box' style="width:278px;position: relative;">
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
+
${isTooltipTitleShow ? `<div class="tooltip-head">${res[0].format || res[0].name}</div>` : ""}
|
|
426
|
+
${(originalItem == null ? void 0 : originalItem.currentTime) ? `<div class="tooltip-time">${originalItem == null ? void 0 : originalItem.currentTime}</div>` : ""}
|
|
427
|
+
<div class='tooltip-body'>
|
|
428
|
+
${dataArr.map((item) => {
|
|
429
|
+
var _a2;
|
|
430
|
+
const raw = ((_a2 = item == null ? void 0 : item.data) == null ? void 0 : _a2.rawValue) !== void 0 ? item.data.rawValue : item.value;
|
|
425
431
|
const itemWithAlias = {
|
|
426
432
|
...item,
|
|
427
433
|
alias: originalItem == null ? void 0 : originalItem.alias,
|
|
428
434
|
alias2: originalItem == null ? void 0 : originalItem.alias2,
|
|
429
|
-
aliasArray: originalItem == null ? void 0 : originalItem.aliasArray
|
|
435
|
+
aliasArray: originalItem == null ? void 0 : originalItem.aliasArray,
|
|
436
|
+
rawValue: raw
|
|
430
437
|
};
|
|
431
438
|
const escapedJson = escapeHtmlAttribute(
|
|
432
439
|
JSON.stringify(itemWithAlias)
|
|
433
440
|
);
|
|
434
441
|
return `<div class='item' data-series-item="${escapedJson}" key='${item.seriesName}'>
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
</span>
|
|
444
|
-
</div>
|
|
445
|
-
</div>`;
|
|
442
|
+
<div class='l'>
|
|
443
|
+
<span style="display:inline-block;width: 14px;vertical-align: middle;height: 14px;background-color:${currentColor};border-radius: 4px;margin-bottom: 2px;margin-right:6px"></span>
|
|
444
|
+
<span>${tooltipItemName ? res[0].format || res[0].name : tipName}</span>
|
|
445
|
+
</div>
|
|
446
|
+
<div class='r' style="padding-left:6px;">
|
|
447
|
+
<span class='num'>${showProportion ? (0, import_chartUtils.computeFloat)(raw) : (0, import_chartUtils.changeDataTypeEn)(raw)}</span>
|
|
448
|
+
</div>
|
|
449
|
+
</div>`;
|
|
446
450
|
}).join("")}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
451
|
+
</div>
|
|
452
|
+
<div class='triangle-down' style='width:${triangleWidth}px'></div>
|
|
453
|
+
</div>`;
|
|
450
454
|
}
|
|
451
455
|
},
|
|
452
456
|
animation: true,
|
|
453
457
|
animationEasing: "cubicInOut",
|
|
454
458
|
animationEasingUpdate: "cubicInOut",
|
|
455
|
-
legend: {
|
|
456
|
-
show: false
|
|
457
|
-
},
|
|
459
|
+
legend: { show: false },
|
|
458
460
|
grid: {
|
|
459
461
|
top: 0,
|
|
460
|
-
// bottom: 30,
|
|
461
462
|
bottom: 0,
|
|
462
463
|
left: 12,
|
|
463
|
-
right:
|
|
464
|
+
right: 0,
|
|
464
465
|
containLabel: true
|
|
465
466
|
},
|
|
466
467
|
xAxis: {
|
|
467
468
|
type: "value",
|
|
468
|
-
|
|
469
|
-
|
|
469
|
+
min: xAxisMin,
|
|
470
|
+
max: xAxisMax,
|
|
470
471
|
show: false,
|
|
471
|
-
axisLine: {
|
|
472
|
-
|
|
473
|
-
},
|
|
474
|
-
axisLabel: {
|
|
475
|
-
show: false
|
|
476
|
-
},
|
|
477
|
-
splitLine: {
|
|
478
|
-
show: false
|
|
479
|
-
},
|
|
472
|
+
axisLine: { show: false },
|
|
473
|
+
axisLabel: { show: false },
|
|
474
|
+
splitLine: { show: false },
|
|
480
475
|
boundaryGap: false
|
|
481
476
|
},
|
|
482
477
|
yAxis: {
|
|
483
478
|
type: "category",
|
|
484
479
|
inverse: true,
|
|
485
480
|
axisLabel: {
|
|
486
|
-
margin:
|
|
481
|
+
margin: rawMin < 0 ? 40 : 10,
|
|
487
482
|
color: "#273333",
|
|
488
483
|
fontSize: 14,
|
|
489
484
|
fontWeight: 500,
|
|
@@ -491,110 +486,69 @@ function CommonBar(props) {
|
|
|
491
486
|
show: true,
|
|
492
487
|
interval: 0,
|
|
493
488
|
rotate: 0,
|
|
494
|
-
// width: 188,
|
|
495
489
|
overflow: "truncate",
|
|
496
490
|
ellipsis: "...",
|
|
497
|
-
// formatter: function (value, index) {
|
|
498
|
-
// // 检查当前项是否有 platformIcon
|
|
499
|
-
// if (yIconFlag) {
|
|
500
|
-
// return `{icon${index}|} {label|${value}}`;
|
|
501
|
-
// } else {
|
|
502
|
-
// return value;
|
|
503
|
-
// }
|
|
504
|
-
// },
|
|
505
491
|
formatter: function(value, index) {
|
|
506
|
-
var
|
|
507
|
-
const rowHasIcon = !!(yIconFlag && ((
|
|
492
|
+
var _a;
|
|
493
|
+
const rowHasIcon = !!(yIconFlag && ((_a = currentData[index]) == null ? void 0 : _a.platformIcon));
|
|
508
494
|
const maxPx = getMaxTextWidthForRow(rowHasIcon);
|
|
509
|
-
const finalText = middleEllipsis(
|
|
510
|
-
|
|
511
|
-
maxPx,
|
|
512
|
-
"14px sans-serif"
|
|
513
|
-
// 跟 axisLabel 字体保持一致
|
|
514
|
-
);
|
|
515
|
-
if (yIconFlag) {
|
|
495
|
+
const finalText = middleEllipsis(value, maxPx, FONT);
|
|
496
|
+
if (yIconFlag)
|
|
516
497
|
return `{icon${index}|} {label|${finalText}}`;
|
|
517
|
-
|
|
518
|
-
return finalText;
|
|
519
|
-
}
|
|
498
|
+
return finalText;
|
|
520
499
|
}
|
|
521
500
|
},
|
|
522
|
-
axisTick: {
|
|
523
|
-
|
|
524
|
-
},
|
|
525
|
-
axisLine: {
|
|
526
|
-
show: false
|
|
527
|
-
},
|
|
528
|
-
splitLine: {
|
|
529
|
-
show: false
|
|
530
|
-
},
|
|
501
|
+
axisTick: { show: false },
|
|
502
|
+
axisLine: { show: false },
|
|
503
|
+
splitLine: { show: false },
|
|
531
504
|
data: axisData
|
|
532
505
|
},
|
|
533
506
|
series: [
|
|
534
507
|
{
|
|
535
|
-
// === 背景柱系列 ===
|
|
536
|
-
// 需要背景柱的原因是让柱状条加上后面的数字标签的和不超过悬浮上去的阴影的长度
|
|
537
508
|
name: "背景条",
|
|
538
509
|
type: "bar",
|
|
539
|
-
// 让它在最底层
|
|
540
510
|
z: 1,
|
|
541
|
-
// 不需要点击/hover 交互
|
|
542
511
|
silent: true,
|
|
543
|
-
// 让柱子和后面的柱子重叠在同一个类目位置
|
|
544
512
|
barGap: "-100%",
|
|
545
|
-
emphasis: {
|
|
546
|
-
|
|
547
|
-
},
|
|
548
|
-
// 柱子的样式
|
|
549
|
-
itemStyle: {
|
|
550
|
-
color: "rgba(0, 0, 0, 0)"
|
|
551
|
-
// 背景色可自定义
|
|
552
|
-
},
|
|
553
|
-
// 这里的 data 根据正负数使用不同的背景值
|
|
513
|
+
emphasis: { disabled: true },
|
|
514
|
+
itemStyle: { color: "rgba(0, 0, 0, 0)" },
|
|
554
515
|
data: currentData.map((item) => {
|
|
555
|
-
const
|
|
556
|
-
return
|
|
516
|
+
const v = valueAccessor(item);
|
|
517
|
+
return v < 0 ? xAxisMin : xAxisMax;
|
|
557
518
|
}),
|
|
558
|
-
// 根据你需要的柱宽
|
|
559
|
-
// barMaxWidth: 42,
|
|
560
|
-
// barMinWidth: 16,
|
|
561
519
|
barWidth: calculateWidth(seriesData.length),
|
|
562
520
|
barMinHeight: 4,
|
|
521
|
+
barMinWidth: 4,
|
|
563
522
|
cursor: "pointer",
|
|
564
523
|
animation: false,
|
|
565
|
-
showBackground: false
|
|
566
|
-
|
|
524
|
+
showBackground: false,
|
|
525
|
+
clip: true
|
|
567
526
|
},
|
|
568
527
|
{
|
|
569
528
|
type: "bar",
|
|
570
|
-
|
|
529
|
+
clip: false,
|
|
530
|
+
// ✅ 关键:label 即使贴边也不要被裁剪
|
|
571
531
|
label: {
|
|
572
532
|
show: true,
|
|
573
|
-
// position: 'right',
|
|
574
533
|
fontWeight: 400,
|
|
575
534
|
fontSize: 14,
|
|
576
535
|
color: "#515E5F",
|
|
577
|
-
distance:
|
|
536
|
+
distance: LABEL_DISTANCE,
|
|
578
537
|
formatter: (params) => {
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
return (0, import_chartUtils.numberFormatNull)(params.value);
|
|
583
|
-
}
|
|
538
|
+
var _a;
|
|
539
|
+
const raw = ((_a = params == null ? void 0 : params.data) == null ? void 0 : _a.rawValue) ?? params.value;
|
|
540
|
+
return showProportion ? (0, import_chartUtils.computeFloat)(raw) : (0, import_chartUtils.numberFormatNull)(raw);
|
|
584
541
|
}
|
|
585
542
|
},
|
|
586
|
-
emphasis: {
|
|
587
|
-
disabled: true
|
|
588
|
-
},
|
|
543
|
+
emphasis: { disabled: true },
|
|
589
544
|
itemStyle: {
|
|
590
545
|
borderColor: "rgba(0,0,0,0)",
|
|
591
546
|
borderWidth: 0,
|
|
592
547
|
borderType: "solid"
|
|
593
548
|
},
|
|
594
|
-
// barMaxWidth: 42,
|
|
595
|
-
// barMinWidth: 16,
|
|
596
549
|
barWidth: calculateWidth(seriesData.length),
|
|
597
550
|
barMinHeight: 4,
|
|
551
|
+
barMinWidth: 4,
|
|
598
552
|
cursor: "pointer",
|
|
599
553
|
animation: false,
|
|
600
554
|
data: seriesData
|
|
@@ -605,8 +559,8 @@ function CommonBar(props) {
|
|
|
605
559
|
option.yAxis.axisLabel.rich = makeYAxisRich(currentData);
|
|
606
560
|
}
|
|
607
561
|
myChart.getZr().on("click", function(params) {
|
|
608
|
-
|
|
609
|
-
|
|
562
|
+
const pointInPixel = [params.offsetX, params.offsetY];
|
|
563
|
+
const dataCoord = myChart.convertFromPixel(
|
|
610
564
|
{ seriesIndex: 0 },
|
|
611
565
|
pointInPixel
|
|
612
566
|
);
|
|
@@ -658,14 +612,11 @@ function CommonBar(props) {
|
|
|
658
612
|
toggleAxisPointer(myChart, false);
|
|
659
613
|
lastIndex = null;
|
|
660
614
|
});
|
|
661
|
-
myChart.off("finished");
|
|
662
615
|
myChart.on("finished", () => {
|
|
663
616
|
(0, import_chartUtils.dealBarPath)(myDom, true);
|
|
664
617
|
});
|
|
665
618
|
myChart.setOption(option, true);
|
|
666
|
-
const element = document.querySelector(
|
|
667
|
-
`.${tooltipClassNameRef.current}`
|
|
668
|
-
);
|
|
619
|
+
const element = document.querySelector(`.${tooltipClassNameRef.current}`);
|
|
669
620
|
if (element) {
|
|
670
621
|
element.addEventListener("mouseleave", function(event) {
|
|
671
622
|
if (event && element.offsetHeight && event.offsetY < element.offsetHeight - 2) {
|