@publishfx/publish-chart 2.1.12 → 2.1.14
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 +6 -0
- package/dist/components/g2/base/G2CombineChart.js +4 -3
- package/dist/components/g2/base/G2LineChart.js +18 -12
- package/dist/components/g2/base/g2Helpers.d.ts +2 -0
- package/dist/components/g2/base/g2Helpers.js +63 -24
- package/dist/components/g2/base/g2combine.d.ts +2 -0
- package/dist/components/g2/base/g2combine.js +126 -100
- package/dist/components/g2/base/g2line.js +1 -1
- package/dist/components/shared/NodePopover.d.ts +1 -1
- package/dist/components/shared/NodePopover.js +9 -3
- package/dist/core/ChartTypes.d.ts +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
**2.1.14** fix(chart): 修复组合图折线指标传空判断
|
|
2
|
+
- 2026-03-05T02:35:21+08:00 [fix(chart): 修复组合图折线指标传空判断](http://lf.git.oa.mt/publish_platform/web/publish/commit/abad3dc8688a3a06d57e2ef1c3884593f5bba88e)
|
|
3
|
+
- 2026-03-05T02:30:07+08:00 [fix(chart): 副轴和非副轴分别定义偏移](http://lf.git.oa.mt/publish_platform/web/publish/commit/6390674b94bcffb02e2145ecc51927a20d89d4a0)
|
|
4
|
+
- 2026-03-05T02:28:42+08:00 [fix(chart): 为了规避辅助线文本避让的问题仍然使用render渲染辅助线](http://lf.git.oa.mt/publish_platform/web/publish/commit/a005f7455772ee64b3e1b951de6eec7fc1529bc5)
|
|
5
|
+
- 2026-03-05T02:19:27+08:00 [fix(chart): 分组时不进行补充处理](http://lf.git.oa.mt/publish_platform/web/publish/commit/0dcc076cf441b16cb6a7a02aee5f6736c1574bc0)
|
|
6
|
+
- 2026-03-05T02:15:09+08:00 [fix(chart): 处理缺失数据导致的tooltip文本缺失问题](http://lf.git.oa.mt/publish_platform/web/publish/commit/ab1c7394ed7b80b5ed17237f59d6c222ad6f253b)
|
|
7
|
+
- 2026-03-05T01:16:46+08:00 [fix(chart): 着重函数axis调整减少顶部空白](http://lf.git.oa.mt/publish_platform/web/publish/commit/6100c4c96a98aa690a61783a64ae4cc3e1c3309f)
|
|
8
|
+
- 2026-03-05T01:03:57+08:00 [feat(chart): 处理图表tooltip和节点tooltip的冲突问题](http://lf.git.oa.mt/publish_platform/web/publish/commit/b502392f558e0d8fdec18c551f52c6f3dc6f9eb2)
|
|
9
|
+
- 2026-03-04T22:36:24+08:00 [fix(chart): 组合图数据处理](http://lf.git.oa.mt/publish_platform/web/publish/commit/6622bc898bdd8feed1655b1573545299164af09c)
|
|
10
|
+
- 2026-03-04T22:18:28+08:00 [fix(chart): 组合图tooltip滚动显示问题](http://lf.git.oa.mt/publish_platform/web/publish/commit/6180fdf4417da43bef0800b450f4d739ca1ab6ee)
|
|
11
|
+
- 2026-03-04T21:28:25+08:00 [fix(chart): 可视化看板、编辑看板tooltip位置问题](http://lf.git.oa.mt/publish_platform/web/publish/commit/c58e1851d1286fcf4290ede2435603e378a747ba)
|
|
12
|
+
- 2026-03-04T21:17:52+08:00 [fix(chart): 组合图total计算更新](http://lf.git.oa.mt/publish_platform/web/publish/commit/937597110cc96672a2f7fda5899cd6df660bd251)
|
|
13
|
+
|
|
1
14
|
**2.1.11** fix(chart): 组合图去掉主轴过滤逻辑,以支持tooltip展示
|
|
2
15
|
- 2026-03-04T20:56:34+08:00 [fix(chart): 组合图去掉主轴过滤逻辑,以支持tooltip展示](http://lf.git.oa.mt/publish_platform/web/publish/commit/215222fb1ae535a52aea475d3a8447cdc61dfa19)
|
|
3
16
|
- 2026-03-04T20:30:34+08:00 [fix(chart): 组合图数据处理逻辑优化](http://lf.git.oa.mt/publish_platform/web/publish/commit/bab29eb2897d1b7b60877c234d8cc14b4d79b9a9)
|
|
@@ -145,6 +145,12 @@ class DataAdapter {
|
|
|
145
145
|
}
|
|
146
146
|
});
|
|
147
147
|
console.log('tdv:', tdv.rows);
|
|
148
|
+
tdv.transform({
|
|
149
|
+
type: 'filter',
|
|
150
|
+
callback (row) {
|
|
151
|
+
return !row[config.y] || '-' !== row[config.y];
|
|
152
|
+
}
|
|
153
|
+
});
|
|
148
154
|
console.log('tdv:', tdv.rows);
|
|
149
155
|
if (config.isDescend) tdv.transform({
|
|
150
156
|
type: 'sort',
|
|
@@ -61,7 +61,7 @@ const lineColors = [
|
|
|
61
61
|
const G2CombineChart = ({ height = 300, data, x = "", y = "", z = "", indicatorMap, onChartClick, legend = "", config, nodeSetting = {
|
|
62
62
|
showType: 0,
|
|
63
63
|
type: []
|
|
64
|
-
}, indicators = [], auxiliaryLineData, highlightDate, timeRange, isGroup })=>{
|
|
64
|
+
}, indicators = [], auxiliaryLineData, highlightDate, timeRange, isGroup, isTooltipContent = false })=>{
|
|
65
65
|
const { formatter, dataTransform, config: contextConfig } = useChartContext();
|
|
66
66
|
const tooltipContainerRef = useG2TooltipContainer();
|
|
67
67
|
const isGroupRef = useRef(isGroup);
|
|
@@ -129,7 +129,7 @@ const G2CombineChart = ({ height = 300, data, x = "", y = "", z = "", indicatorM
|
|
|
129
129
|
y
|
|
130
130
|
]);
|
|
131
131
|
const formatLineAxis = useCallback((val)=>{
|
|
132
|
-
const indicatorId = indicators?.length >
|
|
132
|
+
const indicatorId = indicators?.length > 2 ? '' : safeZ;
|
|
133
133
|
return getAxisFormat(val, safeIndicatorMap, indicatorId);
|
|
134
134
|
}, [
|
|
135
135
|
safeIndicatorMap,
|
|
@@ -272,7 +272,8 @@ const G2CombineChart = ({ height = 300, data, x = "", y = "", z = "", indicatorM
|
|
|
272
272
|
lineColors,
|
|
273
273
|
legendItems,
|
|
274
274
|
indicatorId: y,
|
|
275
|
-
isGroup: isGroupRef.current
|
|
275
|
+
isGroup: isGroupRef.current,
|
|
276
|
+
isTooltipContent
|
|
276
277
|
});
|
|
277
278
|
chartRef.current = chart;
|
|
278
279
|
if (onChartClick) chart.on("plot:click", (_e)=>{
|
|
@@ -54,7 +54,7 @@ const G2LineChart = ({ height = 300, data, x = "", y = "", z = "", indicatorMap,
|
|
|
54
54
|
contextConfig.nodeMap
|
|
55
55
|
]);
|
|
56
56
|
const nodeData = transformedData.filter((item)=>item.nodeInfos?.info?.length > 0 || item.nodeInfos?.infosCompare?.length > 0);
|
|
57
|
-
console.log(
|
|
57
|
+
console.log("nodeData:", nodeData);
|
|
58
58
|
const { minY, maxY } = useMemo(()=>{
|
|
59
59
|
const dataValues = transformedData.filter((item)=>"-" !== item[safeY] && void 0 !== item[safeY] && null !== item[safeY]).map((item)=>Number(item[safeY]));
|
|
60
60
|
const compareValues = transformedData.filter((item)=>"-" !== item["subGroupValue"] && null != item["subGroupValue"]).map((item)=>Number(item["subGroupValue"]));
|
|
@@ -77,7 +77,7 @@ const G2LineChart = ({ height = 300, data, x = "", y = "", z = "", indicatorMap,
|
|
|
77
77
|
auxiliaryLineData
|
|
78
78
|
]);
|
|
79
79
|
const formatAxis = useCallback((val)=>{
|
|
80
|
-
const indicatorId = indicators?.length > 1 ?
|
|
80
|
+
const indicatorId = indicators?.length > 1 ? "" : safeLegend;
|
|
81
81
|
return getAxisFormat(val, safeIndicatorMap, indicatorId);
|
|
82
82
|
}, [
|
|
83
83
|
safeIndicatorMap,
|
|
@@ -175,6 +175,7 @@ const G2LineChart = ({ height = 300, data, x = "", y = "", z = "", indicatorMap,
|
|
|
175
175
|
legendSize: 12,
|
|
176
176
|
useStrictTicks: true,
|
|
177
177
|
onNodeListChange: (nodes)=>{
|
|
178
|
+
console.log("setXYList:", nodes);
|
|
178
179
|
setXYList(nodes);
|
|
179
180
|
},
|
|
180
181
|
onChartRender: (chartProps)=>{
|
|
@@ -186,15 +187,20 @@ const G2LineChart = ({ height = 300, data, x = "", y = "", z = "", indicatorMap,
|
|
|
186
187
|
}
|
|
187
188
|
});
|
|
188
189
|
chartRef.current = chart;
|
|
189
|
-
if (onChartClick)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
190
|
+
if (onChartClick) {
|
|
191
|
+
chart.on("plot:click", (_e)=>{
|
|
192
|
+
const tooltipTitle = currentTooltipTitleRef.current;
|
|
193
|
+
if (null != tooltipTitle) {
|
|
194
|
+
console.log("使用 tooltip title 触发下钻:", tooltipTitle);
|
|
195
|
+
onChartClick({
|
|
196
|
+
title: tooltipTitle
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
chart.on("plot:pointerenter:", (event)=>{
|
|
201
|
+
console.log("plot:pointerenter:", event);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
198
204
|
return ()=>{
|
|
199
205
|
if (chartRef.current) {
|
|
200
206
|
chartRef.current.off("plot:click");
|
|
@@ -255,7 +261,7 @@ const G2LineChart = ({ height = 300, data, x = "", y = "", z = "", indicatorMap,
|
|
|
255
261
|
children: xyList?.map((item, index)=>/*#__PURE__*/ jsx(NodePopover, {
|
|
256
262
|
style: {
|
|
257
263
|
position: "absolute",
|
|
258
|
-
top: item.pointP?.y +
|
|
264
|
+
top: item.pointP?.y + 12,
|
|
259
265
|
left: item.pointP?.x,
|
|
260
266
|
width: 12,
|
|
261
267
|
height: 12,
|
|
@@ -307,3 +307,5 @@ export declare function applyNodeData(view: any, nodeData: any[], x: string, y:
|
|
|
307
307
|
}[];
|
|
308
308
|
export declare function adjustDomainMax(domainMin: number, domainMax: number): number;
|
|
309
309
|
export declare const sortByIndicators: (arr: string[], indicators: string[]) => string[];
|
|
310
|
+
export declare function intervalSort(a: any, b: any): number;
|
|
311
|
+
export declare function fillMissingIndicator(baseItems: any[], safeTitle: string, isCompare: boolean, isGroup?: boolean): any[];
|
|
@@ -151,19 +151,14 @@ function applyAuxiliaryLineY(view, lines, options = {}) {
|
|
|
151
151
|
console.log('applyAuxiliaryLineY:', lines);
|
|
152
152
|
const { stroke = '#F4664A', strokeOpacity = 1, labelMaxLength = 5 } = options;
|
|
153
153
|
lines.forEach((auxLine)=>{
|
|
154
|
-
console.log('lines:', auxLine);
|
|
155
154
|
view.lineY().encode('y', auxLine.value).style('stroke', stroke).style('strokeOpacity', strokeOpacity).style('lineWidth', 1).style('shadowColor', 'transparent').scale('y', {
|
|
156
155
|
key: auxLine?.axis === 'right' ? 'line' : 'main'
|
|
157
156
|
}).axis('x', false).label({
|
|
158
157
|
dx: 0,
|
|
159
158
|
dy: 0,
|
|
160
|
-
text: splitTextToMultiline(auxLine.name, labelMaxLength, '
|
|
159
|
+
text: splitTextToMultiline(auxLine.name, labelMaxLength, '<br />'),
|
|
161
160
|
position: auxLine?.axis === 'right' ? 'bottom-right' : 'bottom-left',
|
|
162
|
-
style: {
|
|
163
|
-
fill: stroke,
|
|
164
|
-
shadowColor: 'transparent',
|
|
165
|
-
fillOpacity: 1
|
|
166
|
-
}
|
|
161
|
+
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
162
|
});
|
|
168
163
|
});
|
|
169
164
|
}
|
|
@@ -186,13 +181,7 @@ function applyHighlightDate(view, x, data, highlightDate, isHighlight) {
|
|
|
186
181
|
domainMin: 0,
|
|
187
182
|
domainMax: 100,
|
|
188
183
|
independent: true
|
|
189
|
-
}).tooltip(false).axis('y',
|
|
190
|
-
position: 'top',
|
|
191
|
-
title: false,
|
|
192
|
-
grid: false,
|
|
193
|
-
label: false,
|
|
194
|
-
tick: false
|
|
195
|
-
});
|
|
184
|
+
}).tooltip(false).axis('y', false);
|
|
196
185
|
highlightInterval.style({
|
|
197
186
|
columnWidthRatio: 0.6,
|
|
198
187
|
fill: '#cccccc',
|
|
@@ -203,13 +192,7 @@ function applyHighlightDate(view, x, data, highlightDate, isHighlight) {
|
|
|
203
192
|
domainMin: 0,
|
|
204
193
|
domainMax: 100,
|
|
205
194
|
independent: true
|
|
206
|
-
}).tooltip(true).axis('y', {
|
|
207
|
-
position: 'top',
|
|
208
|
-
title: false,
|
|
209
|
-
grid: false,
|
|
210
|
-
label: false,
|
|
211
|
-
tick: false
|
|
212
|
-
}).style({
|
|
195
|
+
}).tooltip(true).axis('y', false).style({
|
|
213
196
|
stroke: 'transparent',
|
|
214
197
|
strokeOpacity: 1
|
|
215
198
|
});
|
|
@@ -242,7 +225,7 @@ function applyNodeData(view, nodeData, x, y) {
|
|
|
242
225
|
const c1 = document.createElement('circle', {
|
|
243
226
|
style: {
|
|
244
227
|
cx: px,
|
|
245
|
-
cy: py,
|
|
228
|
+
cy: py + 3,
|
|
246
229
|
r: 2,
|
|
247
230
|
fill: 'white'
|
|
248
231
|
}
|
|
@@ -250,7 +233,7 @@ function applyNodeData(view, nodeData, x, y) {
|
|
|
250
233
|
const c2 = document.createElement('circle', {
|
|
251
234
|
style: {
|
|
252
235
|
cx: px,
|
|
253
|
-
cy: py,
|
|
236
|
+
cy: py + 3,
|
|
254
237
|
r: 5,
|
|
255
238
|
fill: item.color
|
|
256
239
|
}
|
|
@@ -275,4 +258,60 @@ const sortByIndicators = (arr, indicators)=>arr.sort((a, b)=>{
|
|
|
275
258
|
if (-1 !== indexA && -1 !== indexB) return indexA - indexB;
|
|
276
259
|
return 0;
|
|
277
260
|
});
|
|
278
|
-
|
|
261
|
+
function intervalSort(a, b) {
|
|
262
|
+
const itemRank = (item)=>{
|
|
263
|
+
if (item.isChange) return 2;
|
|
264
|
+
if (item.name.includes('_compare')) return 1;
|
|
265
|
+
return 0;
|
|
266
|
+
};
|
|
267
|
+
return itemRank(a) - itemRank(b);
|
|
268
|
+
}
|
|
269
|
+
function fillMissingIndicator(baseItems, safeTitle, isCompare, isGroup = false) {
|
|
270
|
+
const indicatorIds = baseItems.filter((item)=>item.indicatorId).map((item)=>item.indicatorId);
|
|
271
|
+
const indicatorIdSet = new Map(indicatorIds.map((id)=>[
|
|
272
|
+
id,
|
|
273
|
+
0
|
|
274
|
+
]));
|
|
275
|
+
console.log('baseItems:', baseItems);
|
|
276
|
+
if (isCompare && !isGroup) {
|
|
277
|
+
baseItems.forEach((item)=>{
|
|
278
|
+
if (item.indicatorId) indicatorIdSet.set(item.indicatorId, (indicatorIdSet.get(item.indicatorId) ?? 0) + 1);
|
|
279
|
+
});
|
|
280
|
+
indicatorIdSet.forEach((count, indicatorId)=>{
|
|
281
|
+
if (3 !== count) {
|
|
282
|
+
const color = baseItems.filter((item)=>'transparent' !== item.color).map((item)=>item.color)[0];
|
|
283
|
+
if (!baseItems.find((item)=>item.indicatorId === indicatorId && item.name === indicatorId)) baseItems.push({
|
|
284
|
+
indicatorId: indicatorId,
|
|
285
|
+
name: indicatorId,
|
|
286
|
+
value: '-',
|
|
287
|
+
x: safeTitle,
|
|
288
|
+
color: color
|
|
289
|
+
});
|
|
290
|
+
if (!baseItems.find((item)=>item.indicatorId === indicatorId && item.name === indicatorId + '_compare')) baseItems.push({
|
|
291
|
+
indicatorId: indicatorId,
|
|
292
|
+
name: indicatorId + '_compare',
|
|
293
|
+
tipType: 'compareline',
|
|
294
|
+
value: '-',
|
|
295
|
+
x: safeTitle
|
|
296
|
+
});
|
|
297
|
+
if (!baseItems.find((item)=>item.indicatorId === indicatorId && item.name === indicatorId + '_change')) baseItems.push({
|
|
298
|
+
indicatorId: indicatorId,
|
|
299
|
+
name: indicatorId + '_change',
|
|
300
|
+
isChange: true,
|
|
301
|
+
value: '-',
|
|
302
|
+
x: safeTitle
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
const safeItems = baseItems.map((item)=>{
|
|
308
|
+
if (item.x !== safeTitle) return {
|
|
309
|
+
...item,
|
|
310
|
+
value: '-'
|
|
311
|
+
};
|
|
312
|
+
return item;
|
|
313
|
+
}).sort(intervalSort);
|
|
314
|
+
console.log('safeItems:', safeItems);
|
|
315
|
+
return safeItems;
|
|
316
|
+
}
|
|
317
|
+
export { adjustDomainMax, applyAuxiliaryLineY, applyAxisX, applyAxisY, applyHighlightDate, applyLegendColor, applyNodeData, applyScaleYLinear, createChart, fillMissingIndicator, getColorByGroupType, getMainView, intervalSort, sortByIndicators };
|
|
@@ -85,6 +85,8 @@ export interface RenderG2CombineChartOptions {
|
|
|
85
85
|
}>;
|
|
86
86
|
/** 当前指标 id(用于 tooltip 展示) */
|
|
87
87
|
indicatorId?: string;
|
|
88
|
+
/** 是否将 tooltip 挂载到 body(用于可视化看板、编辑看板场景,避免被父容器裁剪) */
|
|
89
|
+
isTooltipContent?: boolean;
|
|
88
90
|
}
|
|
89
91
|
/**
|
|
90
92
|
* 在容器上渲染 G2 柱状 + 折线组合图,返回 Chart 实例便于 destroy/更新
|
|
@@ -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, y, z: _z, maxY, 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 } = options;
|
|
8
|
+
const { data, nodeData, x, y, z: _z, maxY, 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,
|
|
@@ -38,11 +38,10 @@ function renderG2CombineChart(container, options) {
|
|
|
38
38
|
console.log('renderG2CombineChart interval data:', intervalData);
|
|
39
39
|
const intervalMaxY = intervalData.reduce((max, item)=>{
|
|
40
40
|
const key = isGroup ? "total" : BAR_Y_FIELD;
|
|
41
|
-
console.log('
|
|
41
|
+
console.log('tdv item:', key, item[key], intervalData);
|
|
42
42
|
if ('-' === item[key] || void 0 === item[key] || null === item[key] || '' === item[key]) return max;
|
|
43
43
|
return Math.max(max, item[key]);
|
|
44
44
|
}, 0);
|
|
45
|
-
console.log('intervalMaxY:', intervalMaxY);
|
|
46
45
|
console.log('tdv:', intervalMaxY);
|
|
47
46
|
const auxLeftValues = auxiliaryLineData?.length ? auxiliaryLineData.filter((item)=>'left' === item.axis).map((item)=>item.value) : [];
|
|
48
47
|
const maxAuxLeft = auxLeftValues.length ? Math.max(...auxLeftValues) : 0;
|
|
@@ -58,7 +57,6 @@ function renderG2CombineChart(container, options) {
|
|
|
58
57
|
}).style({
|
|
59
58
|
columnWidthRatio: 0.6,
|
|
60
59
|
insetLeft: (_d, index, _data, _column)=>{
|
|
61
|
-
console.log('insetLeft:', index, isCompare);
|
|
62
60
|
if (isGroup) return 0;
|
|
63
61
|
if (isCompare) return index % 2 === 0 ? 0 : 0;
|
|
64
62
|
return 0;
|
|
@@ -256,7 +254,6 @@ function renderG2CombineChart(container, options) {
|
|
|
256
254
|
});
|
|
257
255
|
compareLine.axis('y', false);
|
|
258
256
|
const hasCompareData = data.some((item)=>item.groupType.includes('_compare'));
|
|
259
|
-
console.log('hasCompareData:', hasCompareData, data);
|
|
260
257
|
if (hasCompareData) compareLine.tooltip({
|
|
261
258
|
items: [
|
|
262
259
|
(datum)=>datum.groupType.includes('_compare') ? {
|
|
@@ -265,7 +262,7 @@ function renderG2CombineChart(container, options) {
|
|
|
265
262
|
name: datum['groupType'],
|
|
266
263
|
indicatorId: datum['groupType'].replace('_compare', ''),
|
|
267
264
|
channel: Y_AXIS_FIELD,
|
|
268
|
-
color: lineColors[indicators.slice(1).indexOf(String(datum['groupType'])) ?? 0] || '
|
|
265
|
+
color: lineColors[indicators.slice(1).indexOf(String(datum['groupType']).replace('_compare', '')) ?? 0] || 'trans1parent',
|
|
269
266
|
isCombine: true,
|
|
270
267
|
tipType: 'compareline',
|
|
271
268
|
x: datum[x]
|
|
@@ -282,102 +279,131 @@ function renderG2CombineChart(container, options) {
|
|
|
282
279
|
} : false
|
|
283
280
|
].filter(Boolean)
|
|
284
281
|
});
|
|
285
|
-
if (tooltipRender) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
return
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
const domEvent = event?.event ?? event;
|
|
337
|
-
const clientX = domEvent?.clientX ?? domEvent?.x ?? 0;
|
|
338
|
-
const clientY = domEvent?.clientY ?? domEvent?.y ?? 0;
|
|
339
|
-
const rect = container.getBoundingClientRect();
|
|
340
|
-
const offsetX = 12;
|
|
341
|
-
const offsetY = 12;
|
|
342
|
-
const applyClamp = ()=>{
|
|
343
|
-
let el = content;
|
|
344
|
-
while(el && el.parentElement){
|
|
345
|
-
const p = el.parentElement;
|
|
346
|
-
if (p.classList?.contains('g2-tooltip')) {
|
|
347
|
-
el = p;
|
|
348
|
-
break;
|
|
349
|
-
}
|
|
282
|
+
if (tooltipRender) view.interaction('tooltip', {
|
|
283
|
+
shared: true,
|
|
284
|
+
crosshairsY: true,
|
|
285
|
+
marker: false,
|
|
286
|
+
...isTooltipContent ? {
|
|
287
|
+
mount: 'body'
|
|
288
|
+
} : {},
|
|
289
|
+
render: (event, payload)=>{
|
|
290
|
+
const { title, items } = payload;
|
|
291
|
+
console.log('tooltipRender:', title, items, isCompare);
|
|
292
|
+
let safeTitle = title.replace(/,.*$/, '');
|
|
293
|
+
const baseItems = items.filter((item)=>item.hasOwnProperty('isCombine') && !item.isCombine);
|
|
294
|
+
const safeItems = fillMissingIndicator(baseItems, safeTitle, isCompare, isGroup);
|
|
295
|
+
const combineItems = items.filter((item)=>item.hasOwnProperty('isCombine') && item.isCombine);
|
|
296
|
+
const safeCombineItems = fillMissingIndicator(combineItems, safeTitle, isCompare, isGroup);
|
|
297
|
+
const indicatorOrder = new Map(indicators.map((id, i)=>[
|
|
298
|
+
id,
|
|
299
|
+
i
|
|
300
|
+
]));
|
|
301
|
+
const sortedCombineItems = [
|
|
302
|
+
...safeCombineItems
|
|
303
|
+
].sort((a, b)=>{
|
|
304
|
+
const orderA = indicatorOrder.get(a.indicatorId) ?? 1 / 0;
|
|
305
|
+
const orderB = indicatorOrder.get(b.indicatorId) ?? 1 / 0;
|
|
306
|
+
if (orderA !== orderB) return orderA - orderB;
|
|
307
|
+
const typeRank = (item)=>{
|
|
308
|
+
if (item.isChange) return 2;
|
|
309
|
+
if ('compareline' === item.tipType) return 1;
|
|
310
|
+
return 0;
|
|
311
|
+
};
|
|
312
|
+
return typeRank(a) - typeRank(b);
|
|
313
|
+
});
|
|
314
|
+
const content = tooltipRender(safeTitle, [
|
|
315
|
+
...safeItems,
|
|
316
|
+
...sortedCombineItems
|
|
317
|
+
]) ?? null;
|
|
318
|
+
if (content && isTooltipContent) {
|
|
319
|
+
const domEvent = event?.event ?? event;
|
|
320
|
+
const canvas = container.querySelector('canvas');
|
|
321
|
+
const canvasRect = canvas ? canvas.getBoundingClientRect() : container.getBoundingClientRect();
|
|
322
|
+
const canvasX = domEvent?.canvasX ?? domEvent?.x ?? 0;
|
|
323
|
+
const canvasY = domEvent?.canvasY ?? domEvent?.y ?? 0;
|
|
324
|
+
const clientX = canvasRect.left + canvasX;
|
|
325
|
+
const clientY = canvasRect.top + canvasY;
|
|
326
|
+
const offsetX = 12;
|
|
327
|
+
const offsetY = 12;
|
|
328
|
+
const applyPosition = ()=>{
|
|
329
|
+
let el = content;
|
|
330
|
+
while(el && el.parentElement){
|
|
331
|
+
const p = el.parentElement;
|
|
332
|
+
if (p.classList?.contains('g2-tooltip')) {
|
|
350
333
|
el = p;
|
|
334
|
+
break;
|
|
351
335
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
336
|
+
el = p;
|
|
337
|
+
}
|
|
338
|
+
const wrapper = el && el.classList?.contains('g2-tooltip') ? el : null;
|
|
339
|
+
if (!wrapper) return;
|
|
340
|
+
const wRect = wrapper.getBoundingClientRect();
|
|
341
|
+
const tooltipW = wRect.width || 260;
|
|
342
|
+
const tooltipH = wRect.height || 300;
|
|
343
|
+
const viewportWidth = window.innerWidth;
|
|
344
|
+
const viewportHeight = window.innerHeight;
|
|
345
|
+
let left = clientX + offsetX;
|
|
346
|
+
let top = clientY + offsetY;
|
|
347
|
+
if (left + tooltipW > viewportWidth - 10) left = clientX - tooltipW - offsetX;
|
|
348
|
+
if (top + tooltipH > viewportHeight - 10) top = clientY - tooltipH - offsetY;
|
|
349
|
+
if (left < 10) left = 10;
|
|
350
|
+
if (top < 10) top = 10;
|
|
351
|
+
wrapper.style.position = 'fixed';
|
|
352
|
+
wrapper.style.left = `${left}px`;
|
|
353
|
+
wrapper.style.top = `${top}px`;
|
|
354
|
+
wrapper.style.transform = 'none';
|
|
355
|
+
wrapper.style.pointerEvents = 'none';
|
|
356
|
+
wrapper.style.zIndex = '99999';
|
|
357
|
+
};
|
|
358
|
+
try {
|
|
359
|
+
applyPosition();
|
|
360
|
+
requestAnimationFrame(applyPosition);
|
|
361
|
+
} catch {}
|
|
362
|
+
} else if (content && !isTooltipContent) {
|
|
363
|
+
const domEvent = event?.event ?? event;
|
|
364
|
+
const clientX = domEvent?.clientX ?? domEvent?.x ?? 0;
|
|
365
|
+
const clientY = domEvent?.clientY ?? domEvent?.y ?? 0;
|
|
366
|
+
const rect = container.getBoundingClientRect();
|
|
367
|
+
const offsetX = 12;
|
|
368
|
+
const offsetY = 12;
|
|
369
|
+
const applyClamp = ()=>{
|
|
370
|
+
let el = content;
|
|
371
|
+
while(el && el.parentElement){
|
|
372
|
+
const p = el.parentElement;
|
|
373
|
+
if (p.classList?.contains('g2-tooltip')) {
|
|
374
|
+
el = p;
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
el = p;
|
|
378
|
+
}
|
|
379
|
+
const wrapper = el && el.classList?.contains('g2-tooltip') ? el : null;
|
|
380
|
+
if (!wrapper) return;
|
|
381
|
+
const wRect = wrapper.getBoundingClientRect();
|
|
382
|
+
const tooltipW = wRect.width || 260;
|
|
383
|
+
const tooltipH = wRect.height || 300;
|
|
384
|
+
const minLeft = rect.left;
|
|
385
|
+
const maxLeft = rect.right - tooltipW;
|
|
386
|
+
const minTop = rect.top;
|
|
387
|
+
const maxTop = rect.bottom - tooltipH;
|
|
388
|
+
const desiredLeft = clientX + offsetX;
|
|
389
|
+
const desiredTop = clientY + offsetY;
|
|
390
|
+
const left = Math.min(Math.max(desiredLeft, minLeft), Math.max(maxLeft, minLeft));
|
|
391
|
+
const top = Math.min(Math.max(desiredTop, minTop), Math.max(maxTop, minTop));
|
|
392
|
+
wrapper.style.position = 'fixed';
|
|
393
|
+
wrapper.style.left = `${left}px`;
|
|
394
|
+
wrapper.style.top = `${top}px`;
|
|
395
|
+
wrapper.style.transform = 'translate(0px, 0px)';
|
|
396
|
+
wrapper.style.pointerEvents = 'none';
|
|
397
|
+
wrapper.style.zIndex = '9999';
|
|
398
|
+
};
|
|
399
|
+
try {
|
|
400
|
+
applyClamp();
|
|
401
|
+
requestAnimationFrame(applyClamp);
|
|
402
|
+
} catch {}
|
|
378
403
|
}
|
|
379
|
-
|
|
380
|
-
|
|
404
|
+
return content;
|
|
405
|
+
}
|
|
406
|
+
});
|
|
381
407
|
view.legend(false);
|
|
382
408
|
view.interaction('poptip', {
|
|
383
409
|
offsetY: -20,
|
|
@@ -33,7 +33,7 @@ function renderG2LineChart(container, options) {
|
|
|
33
33
|
lineWidth: 2,
|
|
34
34
|
stroke: (datum)=>getColorByGroupType(datum[0]?.groupType ?? '', colorOpts)
|
|
35
35
|
});
|
|
36
|
-
const compareLine = view.line().data(data.filter((item)=>item.groupType.includes('_compare'))).encode('x', x).encode('y', Y_AXIS_FIELD).encode('color', 'groupType').style({
|
|
36
|
+
const compareLine = view.line().data(data.filter((item)=>item.groupType.includes('_compare'))).encode('x', x).encode('y', Y_AXIS_FIELD).encode('color', 'groupType').encode('series', 'groupType').style({
|
|
37
37
|
lineDash: [
|
|
38
38
|
4,
|
|
39
39
|
4
|
|
@@ -15,19 +15,25 @@ const NodePopover = ({ style, pointData, pointP })=>{
|
|
|
15
15
|
return /*#__PURE__*/ jsx(Fragment, {
|
|
16
16
|
children: /*#__PURE__*/ jsx(Popover, {
|
|
17
17
|
blurToHide: true,
|
|
18
|
-
unmountOnExit:
|
|
18
|
+
unmountOnExit: false,
|
|
19
19
|
position: "right",
|
|
20
20
|
style: {
|
|
21
|
-
maxWidth:
|
|
21
|
+
maxWidth: "auto"
|
|
22
22
|
},
|
|
23
23
|
content: /*#__PURE__*/ jsx(Fragment, {
|
|
24
24
|
children: /*#__PURE__*/ jsx(NodePopoverContent, {
|
|
25
25
|
nodeInfos: nodeInfos
|
|
26
26
|
})
|
|
27
27
|
}),
|
|
28
|
+
onVisibleChange: (visible)=>{
|
|
29
|
+
if (visible) {
|
|
30
|
+
const tooltip = document.querySelector(".g2-tooltip");
|
|
31
|
+
if (tooltip) tooltip.style.visibility = "hidden";
|
|
32
|
+
}
|
|
33
|
+
},
|
|
28
34
|
children: /*#__PURE__*/ jsx("div", {
|
|
29
35
|
style: {
|
|
30
|
-
position:
|
|
36
|
+
position: "absolute",
|
|
31
37
|
top: pointP.y - 10,
|
|
32
38
|
left: pointP.x - 10,
|
|
33
39
|
zIndex: 999,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@publishfx/publish-chart",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.14",
|
|
4
4
|
"description": "A React chart component library for the Publish platform, including BarChart, LineChart, BarLineChart and other visualization components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|