@publishfx/publish-chart 2.1.13 → 2.1.15
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/CHANGELOG.md +13 -0
- package/dist/adapters/DataAdapter.js +5 -13
- package/dist/components/base/BarChart.js +0 -2
- package/dist/components/composite/BarLineCompareWeekend.js +1 -3
- package/dist/components/composite/GroupCompare.js +0 -2
- package/dist/components/g2/base/G2BarChart.js +7 -12
- package/dist/components/g2/base/G2BarLegend.js +0 -1
- package/dist/components/g2/base/G2CombineChart.js +49 -24
- package/dist/components/g2/base/G2GaugeChart.js +1 -4
- package/dist/components/g2/base/G2GroupBarChart.js +0 -4
- package/dist/components/g2/base/G2IndicatorCardChart.js +3 -7
- package/dist/components/g2/base/G2LineChart.js +9 -14
- package/dist/components/g2/base/g2Helpers.d.ts +2 -0
- package/dist/components/g2/base/g2Helpers.js +70 -29
- package/dist/components/g2/base/g2bar.js +1 -5
- package/dist/components/g2/base/g2combine.d.ts +4 -0
- package/dist/components/g2/base/g2combine.js +131 -177
- package/dist/components/g2/base/g2groupbar.js +0 -3
- package/dist/components/g2/base/g2line.js +2 -8
- package/dist/components/g2/base/gaugePropsValidator.js +11 -60
- package/dist/components/g2/shared/G2CompareTooltip.d.ts +3 -4
- package/dist/components/g2/shared/G2CompareTooltip.js +7 -9
- package/dist/components/shared/NodeDetail.js +1 -4
- package/dist/components/shared/NodePopover.d.ts +1 -1
- package/dist/components/shared/NodePopover.js +9 -3
- package/dist/utils/chartHelpers.js +1 -3
- package/package.json +1 -1
|
@@ -61,7 +61,6 @@ function applyAxisX(mark, options = {}) {
|
|
|
61
61
|
const needSampling = dataCount > 0 && containerWidth > 0;
|
|
62
62
|
const interval = needSampling ? calcAxisInterval(dataCount, containerWidth, maxLabelChars, fontSize) : 1;
|
|
63
63
|
const axisFilter = needSampling && interval > 1 ? (type)=>createAxisFilter(type, interval, dataCount) : null;
|
|
64
|
-
console.log('axisFilter:', interval);
|
|
65
64
|
mark.axis('x', {
|
|
66
65
|
title,
|
|
67
66
|
grid,
|
|
@@ -82,6 +81,12 @@ function applyAxisX(mark, options = {}) {
|
|
|
82
81
|
},
|
|
83
82
|
labelAlign: 'horizontal',
|
|
84
83
|
labelDx: (_datum, _index, _data)=>0,
|
|
84
|
+
labelRender: (datum)=>{
|
|
85
|
+
let left = '0%';
|
|
86
|
+
if (datum.value > 0.9) left = '-13%';
|
|
87
|
+
else if (datum.value < 0.1) left = '10%';
|
|
88
|
+
return `<div style="transform: translateX(${left});">${datum.label}</div>`;
|
|
89
|
+
},
|
|
85
90
|
labelOpacity: 0.6,
|
|
86
91
|
...axisFilter && {
|
|
87
92
|
tickFilter: axisFilter('tick'),
|
|
@@ -148,22 +153,16 @@ function applyLegendColor(view, options = {}) {
|
|
|
148
153
|
}
|
|
149
154
|
function applyAuxiliaryLineY(view, lines, options = {}) {
|
|
150
155
|
if (!lines?.length) return;
|
|
151
|
-
console.log('applyAuxiliaryLineY:', lines);
|
|
152
156
|
const { stroke = '#F4664A', strokeOpacity = 1, labelMaxLength = 5 } = options;
|
|
153
157
|
lines.forEach((auxLine)=>{
|
|
154
|
-
|
|
155
|
-
view.lineY().encode('y', auxLine.value).style('stroke', stroke).style('strokeOpacity', strokeOpacity).style('lineWidth', 1).style('shadowColor', 'transparent').scale('y', {
|
|
158
|
+
view.lineY().encode('y', auxLine.value).style('stroke', stroke).style('strokeOpacity', strokeOpacity).style('lineWidth', 1).style('shadowColor', 'transparent').animate(false).scale('y', {
|
|
156
159
|
key: auxLine?.axis === 'right' ? 'line' : 'main'
|
|
157
160
|
}).axis('x', false).label({
|
|
158
161
|
dx: 0,
|
|
159
162
|
dy: 0,
|
|
160
|
-
text: splitTextToMultiline(auxLine.name, labelMaxLength, '
|
|
163
|
+
text: splitTextToMultiline(auxLine.name, labelMaxLength, '<br />'),
|
|
161
164
|
position: auxLine?.axis === 'right' ? 'bottom-right' : 'bottom-left',
|
|
162
|
-
style: {
|
|
163
|
-
fill: stroke,
|
|
164
|
-
shadowColor: 'transparent',
|
|
165
|
-
fillOpacity: 1
|
|
166
|
-
}
|
|
165
|
+
render: (text)=>`<div style="background-color: transparent; padding: 5px; border-radius: 5px;font-size: 14px;position: absolute;left: ${auxLine?.axis === 'right' ? '-105px' : '0px'}; top: -24px; width: 100px;color: ${stroke}; font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;">${text}</div>`
|
|
167
166
|
});
|
|
168
167
|
});
|
|
169
168
|
}
|
|
@@ -181,35 +180,23 @@ function applyHighlightDate(view, x, data, highlightDate, isHighlight) {
|
|
|
181
180
|
[x]: item,
|
|
182
181
|
['highlight']: highlightDate.includes(item) ? 100 : 0
|
|
183
182
|
}));
|
|
184
|
-
const highlightInterval = view.interval().data(highlightData).encode('x', x).encode('y', 'highlight').scale('y', {
|
|
183
|
+
const highlightInterval = view.interval().data(highlightData).encode('x', x).encode('y', 'highlight').animate(false).scale('y', {
|
|
185
184
|
type: 'linear',
|
|
186
185
|
domainMin: 0,
|
|
187
186
|
domainMax: 100,
|
|
188
187
|
independent: true
|
|
189
|
-
}).tooltip(false).axis('y',
|
|
190
|
-
position: 'top',
|
|
191
|
-
title: false,
|
|
192
|
-
grid: false,
|
|
193
|
-
label: false,
|
|
194
|
-
tick: false
|
|
195
|
-
});
|
|
188
|
+
}).tooltip(false).axis('y', false);
|
|
196
189
|
highlightInterval.style({
|
|
197
190
|
columnWidthRatio: 0.6,
|
|
198
191
|
fill: '#cccccc',
|
|
199
192
|
fillOpacity: isHighlight ? 0.3 : 0
|
|
200
193
|
});
|
|
201
|
-
view.line().data(highlightData).encode('x', x).encode('y', 'highlight').scale('y', {
|
|
194
|
+
view.line().data(highlightData).encode('x', x).encode('y', 'highlight').animate(false).scale('y', {
|
|
202
195
|
type: 'linear',
|
|
203
196
|
domainMin: 0,
|
|
204
197
|
domainMax: 100,
|
|
205
198
|
independent: true
|
|
206
|
-
}).tooltip(true).axis('y', {
|
|
207
|
-
position: 'top',
|
|
208
|
-
title: false,
|
|
209
|
-
grid: false,
|
|
210
|
-
label: false,
|
|
211
|
-
tick: false
|
|
212
|
-
}).style({
|
|
199
|
+
}).tooltip(true).axis('y', false).style({
|
|
213
200
|
stroke: 'transparent',
|
|
214
201
|
strokeOpacity: 1
|
|
215
202
|
});
|
|
@@ -242,7 +229,7 @@ function applyNodeData(view, nodeData, x, y) {
|
|
|
242
229
|
const c1 = document.createElement('circle', {
|
|
243
230
|
style: {
|
|
244
231
|
cx: px,
|
|
245
|
-
cy: py,
|
|
232
|
+
cy: py + 3,
|
|
246
233
|
r: 2,
|
|
247
234
|
fill: 'white'
|
|
248
235
|
}
|
|
@@ -250,7 +237,7 @@ function applyNodeData(view, nodeData, x, y) {
|
|
|
250
237
|
const c2 = document.createElement('circle', {
|
|
251
238
|
style: {
|
|
252
239
|
cx: px,
|
|
253
|
-
cy: py,
|
|
240
|
+
cy: py + 3,
|
|
254
241
|
r: 5,
|
|
255
242
|
fill: item.color
|
|
256
243
|
}
|
|
@@ -275,4 +262,58 @@ const sortByIndicators = (arr, indicators)=>arr.sort((a, b)=>{
|
|
|
275
262
|
if (-1 !== indexA && -1 !== indexB) return indexA - indexB;
|
|
276
263
|
return 0;
|
|
277
264
|
});
|
|
278
|
-
|
|
265
|
+
function intervalSort(a, b) {
|
|
266
|
+
const itemRank = (item)=>{
|
|
267
|
+
if (item.isChange) return 2;
|
|
268
|
+
if (item.name.includes('_compare')) return 1;
|
|
269
|
+
return 0;
|
|
270
|
+
};
|
|
271
|
+
return itemRank(a) - itemRank(b);
|
|
272
|
+
}
|
|
273
|
+
function fillMissingIndicator(baseItems, safeTitle, isCompare, isGroup = false) {
|
|
274
|
+
const indicatorIds = baseItems.filter((item)=>item.indicatorId).map((item)=>item.indicatorId);
|
|
275
|
+
const indicatorIdSet = new Map(indicatorIds.map((id)=>[
|
|
276
|
+
id,
|
|
277
|
+
0
|
|
278
|
+
]));
|
|
279
|
+
if (isCompare && !isGroup) {
|
|
280
|
+
baseItems.forEach((item)=>{
|
|
281
|
+
if (item.indicatorId) indicatorIdSet.set(item.indicatorId, (indicatorIdSet.get(item.indicatorId) ?? 0) + 1);
|
|
282
|
+
});
|
|
283
|
+
indicatorIdSet.forEach((count, indicatorId)=>{
|
|
284
|
+
if (3 !== count) {
|
|
285
|
+
const color = baseItems.filter((item)=>'transparent' !== item.color).map((item)=>item.color)[0];
|
|
286
|
+
if (!baseItems.find((item)=>item.indicatorId === indicatorId && item.name === indicatorId)) baseItems.push({
|
|
287
|
+
indicatorId: indicatorId,
|
|
288
|
+
name: indicatorId,
|
|
289
|
+
value: '-',
|
|
290
|
+
x: safeTitle,
|
|
291
|
+
color: color
|
|
292
|
+
});
|
|
293
|
+
if (!baseItems.find((item)=>item.indicatorId === indicatorId && item.name === indicatorId + '_compare')) baseItems.push({
|
|
294
|
+
indicatorId: indicatorId,
|
|
295
|
+
name: indicatorId + '_compare',
|
|
296
|
+
tipType: 'compareline',
|
|
297
|
+
value: '-',
|
|
298
|
+
x: safeTitle
|
|
299
|
+
});
|
|
300
|
+
if (!baseItems.find((item)=>item.indicatorId === indicatorId && item.name === indicatorId + '_change')) baseItems.push({
|
|
301
|
+
indicatorId: indicatorId,
|
|
302
|
+
name: indicatorId + '_change',
|
|
303
|
+
isChange: true,
|
|
304
|
+
value: '-',
|
|
305
|
+
x: safeTitle
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
const safeItems = baseItems.map((item)=>{
|
|
311
|
+
if (item.x !== safeTitle) return {
|
|
312
|
+
...item,
|
|
313
|
+
value: '-'
|
|
314
|
+
};
|
|
315
|
+
return item;
|
|
316
|
+
}).sort(intervalSort);
|
|
317
|
+
return safeItems;
|
|
318
|
+
}
|
|
319
|
+
export { adjustDomainMax, applyAuxiliaryLineY, applyAxisX, applyAxisY, applyHighlightDate, applyLegendColor, applyNodeData, applyScaleYLinear, createChart, fillMissingIndicator, getColorByGroupType, getMainView, intervalSort, sortByIndicators };
|
|
@@ -20,7 +20,6 @@ function renderG2BarChart(container, options) {
|
|
|
20
20
|
paddingBottom: 0,
|
|
21
21
|
insetBottom: 0
|
|
22
22
|
});
|
|
23
|
-
console.log('isLegend:', legend, isLegend);
|
|
24
23
|
const view = getMainView(chart);
|
|
25
24
|
view.attr('marginLeft', 0).attr('marginRight', 0).attr('marginBottom', isLegend ? 0 : 16);
|
|
26
25
|
if (isHorizontal) view.coordinate({
|
|
@@ -37,11 +36,10 @@ function renderG2BarChart(container, options) {
|
|
|
37
36
|
key: 'main'
|
|
38
37
|
});
|
|
39
38
|
if (!CLOSE_HIGHLIGHT_DEBUG) applyHighlightDate(view, x, data, highlightDate, isHighlight);
|
|
40
|
-
console.log('g2bar data:', data, y);
|
|
41
39
|
const interval = view.interval().encode('x', x).encode('y', y).encode('color', 'groupType').transform({
|
|
42
40
|
type: 'dodgeX',
|
|
43
41
|
padding: isHorizontal ? 0.2 : 0
|
|
44
|
-
});
|
|
42
|
+
}).animate(false);
|
|
45
43
|
interval.style({
|
|
46
44
|
columnWidthRatio: 0.6,
|
|
47
45
|
insetLeft: (_d, index, _data, _column)=>{
|
|
@@ -145,7 +143,6 @@ function renderG2BarChart(container, options) {
|
|
|
145
143
|
bounding: tooltipBounding
|
|
146
144
|
});
|
|
147
145
|
applyAuxiliaryLineY(view, auxiliaryLineData);
|
|
148
|
-
console.log('nodeList data:', data);
|
|
149
146
|
if (!CLOSE_NODE_DEBUG) {
|
|
150
147
|
const nodeList = applyNodeData(view, nodeData, x, y);
|
|
151
148
|
onNodeListChange?.(nodeList);
|
|
@@ -170,7 +167,6 @@ function renderG2BarChart(container, options) {
|
|
|
170
167
|
let hasEmittedNodeList = false;
|
|
171
168
|
chart.on('afterrender', (_e)=>{
|
|
172
169
|
if (hasEmittedNodeList) return;
|
|
173
|
-
console.log('chart.coordinateBBox:', chart.getContext(), view.getCoordinate());
|
|
174
170
|
const views = chart.getContext()?.views;
|
|
175
171
|
const viewCoordinate = views?.[0]?.layout;
|
|
176
172
|
if (onChartRender && viewCoordinate) onChartRender({
|
|
@@ -18,6 +18,10 @@ export interface RenderG2CombineChartOptions {
|
|
|
18
18
|
z: string;
|
|
19
19
|
/** 柱状图 Y 轴最大值 */
|
|
20
20
|
maxY: number;
|
|
21
|
+
/** 柱状图 Y 轴最大值 */
|
|
22
|
+
maxLeft: number;
|
|
23
|
+
/** 折线图 Y 轴最大值 */
|
|
24
|
+
maxRight: number;
|
|
21
25
|
/** 高亮日期,用于 x 轴 gridFilter */
|
|
22
26
|
highlightDate?: string[];
|
|
23
27
|
/** 主题色数组 */
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { lines } from "@antv/g-pattern";
|
|
2
|
-
import { applyAuxiliaryLineY, applyAxisX, applyHighlightDate, applyNodeData, applyScaleYLinear, createChart, getMainView } from "./g2Helpers.js";
|
|
2
|
+
import { applyAuxiliaryLineY, applyAxisX, applyHighlightDate, applyNodeData, applyScaleYLinear, createChart, fillMissingIndicator, getMainView } from "./g2Helpers.js";
|
|
3
3
|
import { getIndicatorCompareName } from "../../../utils/indicatorHelpers.js";
|
|
4
4
|
const Y_AXIS_FIELD = 'groupValue';
|
|
5
5
|
const BAR_Y_FIELD = 'barValue';
|
|
6
6
|
const LINE_Y_FIELD = 'lineValue';
|
|
7
7
|
function renderG2CombineChart(container, options) {
|
|
8
|
-
const { data, nodeData, x,
|
|
8
|
+
const { data, nodeData, x, z: _z, maxLeft, maxRight, themeColors, indicatorMap: _indicatorMap, formatAxis, formatLineAxis, isDataTag = true, isCombineDataTag = true, isLegend: _isLegend = false, isCompare = false, formatLabel, highlightDate = [], height = 300, isHighlight = true, isClickable = false, indicators = [], tooltipRender, auxiliaryLineData = [], onNodeListChange, lineColors, onChartRender, isGroup, legendItems = [], indicatorId, isTooltipContent = false } = options;
|
|
9
9
|
const chart = createChart({
|
|
10
10
|
container,
|
|
11
11
|
height,
|
|
@@ -14,11 +14,11 @@ function renderG2CombineChart(container, options) {
|
|
|
14
14
|
chart.options({
|
|
15
15
|
marginBottom: 0,
|
|
16
16
|
paddingBottom: 0,
|
|
17
|
-
insetBottom: 0
|
|
17
|
+
insetBottom: 0,
|
|
18
|
+
animate: null
|
|
18
19
|
});
|
|
19
20
|
const view = getMainView(chart);
|
|
20
|
-
view.attr('insetLeft', 0).attr('insetRight', 0).attr('marginLeft', 0).attr('marginRight', 0).attr('marginBottom', 0);
|
|
21
|
-
console.log('renderG2CombineChart data:', data, 'maxY:', maxY, x, y, 'indicators:', indicators);
|
|
21
|
+
view.attr('insetLeft', 0).attr('insetRight', 0).attr('marginLeft', 0).attr('marginRight', 0).attr('marginBottom', 0).attr('animate', false).animate(false);
|
|
22
22
|
view.data(data);
|
|
23
23
|
const xValueCount = new Set(data.map((d)=>d[x])).size;
|
|
24
24
|
applyAxisX(view, {
|
|
@@ -28,27 +28,17 @@ function renderG2CombineChart(container, options) {
|
|
|
28
28
|
containerWidth: container.clientWidth
|
|
29
29
|
});
|
|
30
30
|
const barColor = themeColors[0] ?? "#5B8FF9";
|
|
31
|
-
console.log('tooltip: themeColors:', themeColors[0], barColor, isGroup);
|
|
32
|
-
console.log('renderG2CombineChart highlightDate:', highlightDate, isHighlight);
|
|
33
31
|
applyHighlightDate(view, x, data, highlightDate, isHighlight);
|
|
34
32
|
const intervalData = data.filter((item)=>!item.isCombine).map((item)=>({
|
|
35
33
|
...item,
|
|
36
34
|
[BAR_Y_FIELD]: item[Y_AXIS_FIELD]
|
|
37
35
|
}));
|
|
38
|
-
console.log('renderG2CombineChart interval data:', intervalData);
|
|
39
|
-
const intervalMaxY = intervalData.reduce((max, item)=>{
|
|
40
|
-
const key = isGroup ? "total" : BAR_Y_FIELD;
|
|
41
|
-
console.log('tdv item:', key, item[key], intervalData);
|
|
42
|
-
if ('-' === item[key] || void 0 === item[key] || null === item[key] || '' === item[key]) return max;
|
|
43
|
-
return Math.max(max, item[key]);
|
|
44
|
-
}, 0);
|
|
45
|
-
console.log('tdv:', intervalMaxY);
|
|
46
36
|
const auxLeftValues = auxiliaryLineData?.length ? auxiliaryLineData.filter((item)=>'left' === item.axis).map((item)=>item.value) : [];
|
|
47
37
|
const maxAuxLeft = auxLeftValues.length ? Math.max(...auxLeftValues) : 0;
|
|
48
38
|
const auxRightValues = auxiliaryLineData?.length ? auxiliaryLineData.filter((item)=>'right' === item.axis).map((item)=>item.value) : [];
|
|
49
39
|
const maxAuxRight = auxRightValues.length ? Math.max(...auxRightValues) : 0;
|
|
50
|
-
const finalIntervalMax = Math.max(
|
|
51
|
-
const interval = view.interval().data(intervalData).encode("x", x).encode("y", BAR_Y_FIELD).encode("color", "groupType").transform(isGroup ? {
|
|
40
|
+
const finalIntervalMax = Math.max(maxLeft, maxAuxLeft);
|
|
41
|
+
const interval = view.interval().data(intervalData).encode("x", x).encode("y", BAR_Y_FIELD).encode("color", "groupType").animate(false).transform(isGroup ? {
|
|
52
42
|
type: 'stackY',
|
|
53
43
|
reverse: true
|
|
54
44
|
} : {
|
|
@@ -57,7 +47,6 @@ function renderG2CombineChart(container, options) {
|
|
|
57
47
|
}).style({
|
|
58
48
|
columnWidthRatio: 0.6,
|
|
59
49
|
insetLeft: (_d, index, _data, _column)=>{
|
|
60
|
-
console.log('insetLeft:', index, isCompare);
|
|
61
50
|
if (isGroup) return 0;
|
|
62
51
|
if (isCompare) return index % 2 === 0 ? 0 : 0;
|
|
63
52
|
return 0;
|
|
@@ -110,13 +99,11 @@ function renderG2CombineChart(container, options) {
|
|
|
110
99
|
labelFormatter: formatAxis,
|
|
111
100
|
labelOpacity: 0.6
|
|
112
101
|
});
|
|
113
|
-
console.log('tooltip:', barColor, isCompare);
|
|
114
102
|
interval.tooltip({
|
|
115
103
|
items: isGroup ? [
|
|
116
104
|
(datum)=>{
|
|
117
105
|
const groupType = String(datum.groupType ?? '');
|
|
118
106
|
const index = legendItems.findIndex((item)=>item.id === `${groupType}_${datum.isCombine}`);
|
|
119
|
-
console.log(datum);
|
|
120
107
|
return {
|
|
121
108
|
value: datum[Y_AXIS_FIELD],
|
|
122
109
|
name: datum['groupType'],
|
|
@@ -163,24 +150,12 @@ function renderG2CombineChart(container, options) {
|
|
|
163
150
|
...item,
|
|
164
151
|
[LINE_Y_FIELD]: item[Y_AXIS_FIELD]
|
|
165
152
|
}));
|
|
166
|
-
console.log('renderG2CombineChart: line data:', data);
|
|
167
153
|
const compareLineData = data.filter((item)=>item.isCombine && item.groupType.includes('_compare')).filter((item)=>'' !== item[Y_AXIS_FIELD]).map((item)=>({
|
|
168
154
|
...item,
|
|
169
155
|
[LINE_Y_FIELD]: item[Y_AXIS_FIELD]
|
|
170
156
|
}));
|
|
171
|
-
|
|
172
|
-
const
|
|
173
|
-
if ('-' === item[LINE_Y_FIELD] || void 0 === item[LINE_Y_FIELD] || null === item[LINE_Y_FIELD] || '' === item[LINE_Y_FIELD]) return max;
|
|
174
|
-
return Math.max(max, item[LINE_Y_FIELD]);
|
|
175
|
-
}, 0);
|
|
176
|
-
const compareLineMaxY = compareLineData.reduce((max, item)=>{
|
|
177
|
-
if ('-' === item[LINE_Y_FIELD] || void 0 === item[LINE_Y_FIELD] || null === item[LINE_Y_FIELD] || '' === item[LINE_Y_FIELD]) return max;
|
|
178
|
-
return Math.max(max, item[LINE_Y_FIELD]);
|
|
179
|
-
}, 0);
|
|
180
|
-
const lineFinalMaxY = Math.max(lineMaxY, compareLineMaxY) || 1;
|
|
181
|
-
const finalLineMax = Math.max(lineFinalMaxY, maxAuxRight);
|
|
182
|
-
console.log('lineData:', lineData);
|
|
183
|
-
const line = view.line().data(lineData).encode("x", x).encode("y", LINE_Y_FIELD).encode('color', 'groupType').style({
|
|
157
|
+
const finalLineMax = Math.max(maxRight, maxAuxRight);
|
|
158
|
+
const line = view.line().data(lineData).encode("x", x).encode("y", LINE_Y_FIELD).encode('color', 'groupType').animate(false).style({
|
|
184
159
|
lineWidth: 2,
|
|
185
160
|
stroke: (datum)=>{
|
|
186
161
|
const currentDatum = datum[0];
|
|
@@ -218,7 +193,7 @@ function renderG2CombineChart(container, options) {
|
|
|
218
193
|
position: 'right',
|
|
219
194
|
title: false,
|
|
220
195
|
grid: true,
|
|
221
|
-
gridStrokeOpacity: 0 ===
|
|
196
|
+
gridStrokeOpacity: 0 === maxAuxLeft ? 0.2 : 0,
|
|
222
197
|
gridLineWidth: 1,
|
|
223
198
|
gridLineDash: [
|
|
224
199
|
0,
|
|
@@ -228,8 +203,7 @@ function renderG2CombineChart(container, options) {
|
|
|
228
203
|
labelFormatter: formatLineAxis,
|
|
229
204
|
labelOpacity: 0.6
|
|
230
205
|
});
|
|
231
|
-
|
|
232
|
-
const compareLine = view.line().data(compareLineData).encode('x', x).encode('y', LINE_Y_FIELD).encode('color', 'groupType').style({
|
|
206
|
+
const compareLine = view.line().data(compareLineData).encode('x', x).encode('y', LINE_Y_FIELD).encode('color', 'groupType').animate(false).style({
|
|
233
207
|
lineDash: [
|
|
234
208
|
4,
|
|
235
209
|
4
|
|
@@ -255,7 +229,6 @@ function renderG2CombineChart(container, options) {
|
|
|
255
229
|
});
|
|
256
230
|
compareLine.axis('y', false);
|
|
257
231
|
const hasCompareData = data.some((item)=>item.groupType.includes('_compare'));
|
|
258
|
-
console.log('hasCompareData:', hasCompareData, data);
|
|
259
232
|
if (hasCompareData) compareLine.tooltip({
|
|
260
233
|
items: [
|
|
261
234
|
(datum)=>datum.groupType.includes('_compare') ? {
|
|
@@ -264,7 +237,7 @@ function renderG2CombineChart(container, options) {
|
|
|
264
237
|
name: datum['groupType'],
|
|
265
238
|
indicatorId: datum['groupType'].replace('_compare', ''),
|
|
266
239
|
channel: Y_AXIS_FIELD,
|
|
267
|
-
color: lineColors[indicators.slice(1).indexOf(String(datum['groupType'])) ?? 0] || '
|
|
240
|
+
color: lineColors[indicators.slice(1).indexOf(String(datum['groupType']).replace('_compare', '')) ?? 0] || 'trans1parent',
|
|
268
241
|
isCombine: true,
|
|
269
242
|
tipType: 'compareline',
|
|
270
243
|
x: datum[x]
|
|
@@ -281,149 +254,130 @@ function renderG2CombineChart(container, options) {
|
|
|
281
254
|
} : false
|
|
282
255
|
].filter(Boolean)
|
|
283
256
|
});
|
|
284
|
-
if (tooltipRender) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
if (item.
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
...safeItems,
|
|
335
|
-
...sortedCombineItems
|
|
336
|
-
]) ?? null;
|
|
337
|
-
if (content && isTooltipContent) {
|
|
338
|
-
const domEvent = event?.event ?? event;
|
|
339
|
-
const canvas = container.querySelector('canvas');
|
|
340
|
-
const canvasRect = canvas ? canvas.getBoundingClientRect() : container.getBoundingClientRect();
|
|
341
|
-
const canvasX = domEvent?.canvasX ?? domEvent?.x ?? 0;
|
|
342
|
-
const canvasY = domEvent?.canvasY ?? domEvent?.y ?? 0;
|
|
343
|
-
const clientX = canvasRect.left + canvasX;
|
|
344
|
-
const clientY = canvasRect.top + canvasY;
|
|
345
|
-
const offsetX = 12;
|
|
346
|
-
const offsetY = 12;
|
|
347
|
-
const applyPosition = ()=>{
|
|
348
|
-
let el = content;
|
|
349
|
-
while(el && el.parentElement){
|
|
350
|
-
const p = el.parentElement;
|
|
351
|
-
if (p.classList?.contains('g2-tooltip')) {
|
|
352
|
-
el = p;
|
|
353
|
-
break;
|
|
354
|
-
}
|
|
257
|
+
if (tooltipRender) view.interaction('tooltip', {
|
|
258
|
+
shared: true,
|
|
259
|
+
crosshairsY: true,
|
|
260
|
+
marker: false,
|
|
261
|
+
...isTooltipContent ? {
|
|
262
|
+
mount: 'body'
|
|
263
|
+
} : {},
|
|
264
|
+
render: (event, payload)=>{
|
|
265
|
+
const { title, items } = payload;
|
|
266
|
+
let safeTitle = title.replace(/,.*$/, '');
|
|
267
|
+
const baseItems = items.filter((item)=>item.hasOwnProperty('isCombine') && !item.isCombine);
|
|
268
|
+
const safeItems = fillMissingIndicator(baseItems, safeTitle, isCompare, isGroup);
|
|
269
|
+
const combineItems = items.filter((item)=>item.hasOwnProperty('isCombine') && item.isCombine);
|
|
270
|
+
const safeCombineItems = fillMissingIndicator(combineItems, safeTitle, isCompare, isGroup);
|
|
271
|
+
const indicatorOrder = new Map(indicators.map((id, i)=>[
|
|
272
|
+
id,
|
|
273
|
+
i
|
|
274
|
+
]));
|
|
275
|
+
const sortedCombineItems = [
|
|
276
|
+
...safeCombineItems
|
|
277
|
+
].sort((a, b)=>{
|
|
278
|
+
const orderA = indicatorOrder.get(a.indicatorId) ?? 1 / 0;
|
|
279
|
+
const orderB = indicatorOrder.get(b.indicatorId) ?? 1 / 0;
|
|
280
|
+
if (orderA !== orderB) return orderA - orderB;
|
|
281
|
+
const typeRank = (item)=>{
|
|
282
|
+
if (item.isChange) return 2;
|
|
283
|
+
if ('compareline' === item.tipType) return 1;
|
|
284
|
+
return 0;
|
|
285
|
+
};
|
|
286
|
+
return typeRank(a) - typeRank(b);
|
|
287
|
+
});
|
|
288
|
+
const content = tooltipRender(safeTitle, [
|
|
289
|
+
...safeItems,
|
|
290
|
+
...sortedCombineItems
|
|
291
|
+
]) ?? null;
|
|
292
|
+
if (content && isTooltipContent) {
|
|
293
|
+
const domEvent = event?.event ?? event;
|
|
294
|
+
const canvas = container.querySelector('canvas');
|
|
295
|
+
const canvasRect = canvas ? canvas.getBoundingClientRect() : container.getBoundingClientRect();
|
|
296
|
+
const canvasX = domEvent?.canvasX ?? domEvent?.x ?? 0;
|
|
297
|
+
const canvasY = domEvent?.canvasY ?? domEvent?.y ?? 0;
|
|
298
|
+
const clientX = canvasRect.left + canvasX;
|
|
299
|
+
const clientY = canvasRect.top + canvasY;
|
|
300
|
+
const offsetX = 12;
|
|
301
|
+
const offsetY = 12;
|
|
302
|
+
const applyPosition = ()=>{
|
|
303
|
+
let el = content;
|
|
304
|
+
while(el && el.parentElement){
|
|
305
|
+
const p = el.parentElement;
|
|
306
|
+
if (p.classList?.contains('g2-tooltip')) {
|
|
355
307
|
el = p;
|
|
308
|
+
break;
|
|
356
309
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
310
|
+
el = p;
|
|
311
|
+
}
|
|
312
|
+
const wrapper = el && el.classList?.contains('g2-tooltip') ? el : null;
|
|
313
|
+
if (!wrapper) return;
|
|
314
|
+
const wRect = wrapper.getBoundingClientRect();
|
|
315
|
+
const tooltipW = wRect.width || 260;
|
|
316
|
+
const tooltipH = wRect.height || 300;
|
|
317
|
+
const viewportWidth = window.innerWidth;
|
|
318
|
+
const viewportHeight = window.innerHeight;
|
|
319
|
+
let left = clientX + offsetX;
|
|
320
|
+
let top = clientY + offsetY;
|
|
321
|
+
if (left + tooltipW > viewportWidth - 10) left = clientX - tooltipW - offsetX;
|
|
322
|
+
if (top + tooltipH > viewportHeight - 10) top = clientY - tooltipH - offsetY;
|
|
323
|
+
if (left < 10) left = 10;
|
|
324
|
+
if (top < 10) top = 10;
|
|
325
|
+
wrapper.style.position = 'fixed';
|
|
326
|
+
wrapper.style.left = `${left}px`;
|
|
327
|
+
wrapper.style.top = `${top}px`;
|
|
328
|
+
wrapper.style.transform = 'none';
|
|
329
|
+
wrapper.style.pointerEvents = 'none';
|
|
330
|
+
wrapper.style.zIndex = '99999';
|
|
331
|
+
};
|
|
332
|
+
try {
|
|
333
|
+
applyPosition();
|
|
334
|
+
requestAnimationFrame(applyPosition);
|
|
335
|
+
} catch {}
|
|
336
|
+
} else if (content && !isTooltipContent) {
|
|
337
|
+
const domEvent = event?.event ?? event;
|
|
338
|
+
const clientX = domEvent?.clientX ?? domEvent?.x ?? 0;
|
|
339
|
+
const clientY = domEvent?.clientY ?? domEvent?.y ?? 0;
|
|
340
|
+
const rect = container.getBoundingClientRect();
|
|
341
|
+
const offsetX = 12;
|
|
342
|
+
const offsetY = 12;
|
|
343
|
+
const applyClamp = ()=>{
|
|
344
|
+
let el = content;
|
|
345
|
+
while(el && el.parentElement){
|
|
346
|
+
const p = el.parentElement;
|
|
347
|
+
if (p.classList?.contains('g2-tooltip')) {
|
|
396
348
|
el = p;
|
|
349
|
+
break;
|
|
397
350
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
351
|
+
el = p;
|
|
352
|
+
}
|
|
353
|
+
const wrapper = el && el.classList?.contains('g2-tooltip') ? el : null;
|
|
354
|
+
if (!wrapper) return;
|
|
355
|
+
const wRect = wrapper.getBoundingClientRect();
|
|
356
|
+
const tooltipW = wRect.width || 260;
|
|
357
|
+
const tooltipH = wRect.height || 300;
|
|
358
|
+
const minLeft = rect.left;
|
|
359
|
+
const maxLeft = rect.right - tooltipW;
|
|
360
|
+
const minTop = rect.top;
|
|
361
|
+
const maxTop = rect.bottom - tooltipH;
|
|
362
|
+
const desiredLeft = clientX + offsetX;
|
|
363
|
+
const desiredTop = clientY + offsetY;
|
|
364
|
+
const left = Math.min(Math.max(desiredLeft, minLeft), Math.max(maxLeft, minLeft));
|
|
365
|
+
const top = Math.min(Math.max(desiredTop, minTop), Math.max(maxTop, minTop));
|
|
366
|
+
wrapper.style.position = 'fixed';
|
|
367
|
+
wrapper.style.left = `${left}px`;
|
|
368
|
+
wrapper.style.top = `${top}px`;
|
|
369
|
+
wrapper.style.transform = 'translate(0px, 0px)';
|
|
370
|
+
wrapper.style.pointerEvents = 'none';
|
|
371
|
+
wrapper.style.zIndex = '9999';
|
|
372
|
+
};
|
|
373
|
+
try {
|
|
374
|
+
applyClamp();
|
|
375
|
+
requestAnimationFrame(applyClamp);
|
|
376
|
+
} catch {}
|
|
424
377
|
}
|
|
425
|
-
|
|
426
|
-
|
|
378
|
+
return content;
|
|
379
|
+
}
|
|
380
|
+
});
|
|
427
381
|
view.legend(false);
|
|
428
382
|
view.interaction('poptip', {
|
|
429
383
|
offsetY: -20,
|