Skip to content

Commit 31d421a

Browse files
committed
fix: 修复G2图表初始化错误和数据验证问题
## 问题修复 - 解决 'ownerDocument' is null 错误 - 解决 'f.split is not a function' 错误 - 添加 DOM 元素存在性检查 - 添加数据格式验证 ## 优化措施 1. **延迟初始化** - 添加 100ms 延迟确保 DOM 已挂载 - 数据更新时延迟 50ms 避免频繁重渲染 2. **数据验证** - 过滤无效数据对象 - 检查必需字段存在性 - 验证数字类型字段 3. **错误处理** - 添加 console.warn 提示 - 容器不存在时优雅退出 - 无效数据时避免崩溃 ## 影响组件 - G2LineChart.vue - G2PieChart.vue - G2HBarChart.vue
1 parent 82a4605 commit 31d421a

File tree

3 files changed

+90
-13
lines changed

3 files changed

+90
-13
lines changed

web/src/components/charts/G2HBarChart.vue

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,27 @@ function initChart() {
3737
return
3838
}
3939
40+
// 确保 DOM 元素存在
41+
const container = document.getElementById(chartId.value)
42+
if (!container) {
43+
console.warn('Chart container not found:', chartId.value)
44+
return
45+
}
46+
47+
// 数据验证
48+
const validData = props.data.filter(d =>
49+
d &&
50+
typeof d === 'object' &&
51+
d[props.xField] !== undefined &&
52+
d[props.yField] !== undefined &&
53+
typeof d[props.xField] === 'number'
54+
)
55+
56+
if (validData.length === 0) {
57+
console.warn('No valid data for bar chart')
58+
return
59+
}
60+
4061
chart = new Chart({
4162
container: chartId.value,
4263
autoFit: true,
@@ -47,7 +68,7 @@ function initChart() {
4768
4869
chart
4970
.interval()
50-
.data(props.data)
71+
.data(validData)
5172
.encode('x', props.yField)
5273
.encode('y', props.xField)
5374
.encode('color', (d, idx) => {
@@ -87,11 +108,15 @@ function initChart() {
87108
}
88109
89110
onMounted(() => {
90-
initChart()
111+
setTimeout(() => {
112+
initChart()
113+
}, 100)
91114
})
92115
93116
watch(() => props.data, () => {
94-
initChart()
117+
setTimeout(() => {
118+
initChart()
119+
}, 50)
95120
}, { deep: true })
96121
97122
onBeforeUnmount(() => {

web/src/components/charts/G2LineChart.vue

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const props = defineProps({
3434
})
3535
3636
const chartId = ref(`g2-line-${Math.random().toString(36).substr(2, 9)}`)
37+
const chartRef = ref(null)
3738
let chart = null
3839
3940
function initChart() {
@@ -45,6 +46,26 @@ function initChart() {
4546
return
4647
}
4748
49+
// 确保 DOM 元素存在
50+
const container = document.getElementById(chartId.value)
51+
if (!container) {
52+
console.warn('Chart container not found:', chartId.value)
53+
return
54+
}
55+
56+
// 数据验证
57+
const validData = props.data.filter(d =>
58+
d &&
59+
typeof d === 'object' &&
60+
d[props.xField] !== undefined &&
61+
d[props.yField] !== undefined
62+
)
63+
64+
if (validData.length === 0) {
65+
console.warn('No valid data for chart')
66+
return
67+
}
68+
4869
chart = new Chart({
4970
container: chartId.value,
5071
autoFit: true,
@@ -54,7 +75,7 @@ function initChart() {
5475
// 折线
5576
chart
5677
.line()
57-
.data(props.data)
78+
.data(validData)
5879
.encode('x', props.xField)
5980
.encode('y', props.yField)
6081
.encode('shape', props.smooth ? 'smooth' : 'line')
@@ -69,7 +90,7 @@ function initChart() {
6990
// 面积填充
7091
chart
7192
.area()
72-
.data(props.data)
93+
.data(validData)
7394
.encode('x', props.xField)
7495
.encode('y', props.yField)
7596
.encode('shape', props.smooth ? 'smooth' : 'area')
@@ -81,7 +102,7 @@ function initChart() {
81102
// 数据点 - 增大尺寸,更明显
82103
chart
83104
.point()
84-
.data(props.data)
105+
.data(validData)
85106
.encode('x', props.xField)
86107
.encode('y', props.yField)
87108
.encode('size', 6)
@@ -106,11 +127,17 @@ function initChart() {
106127
}
107128
108129
onMounted(() => {
109-
initChart()
130+
// 延迟初始化,确保 DOM 已挂载
131+
setTimeout(() => {
132+
initChart()
133+
}, 100)
110134
})
111135
112136
watch(() => props.data, () => {
113-
initChart()
137+
// 延迟更新,避免频繁重渲染
138+
setTimeout(() => {
139+
initChart()
140+
}, 50)
114141
}, { deep: true })
115142
116143
onBeforeUnmount(() => {

web/src/components/charts/G2PieChart.vue

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,27 @@ function initChart() {
4141
return
4242
}
4343
44+
// 确保 DOM 元素存在
45+
const container = document.getElementById(chartId.value)
46+
if (!container) {
47+
console.warn('Chart container not found:', chartId.value)
48+
return
49+
}
50+
51+
// 数据验证
52+
const validData = props.data.filter(d =>
53+
d &&
54+
typeof d === 'object' &&
55+
d[props.valueField] !== undefined &&
56+
d[props.labelField] !== undefined &&
57+
typeof d[props.valueField] === 'number'
58+
)
59+
60+
if (validData.length === 0) {
61+
console.warn('No valid data for pie chart')
62+
return
63+
}
64+
4465
chart = new Chart({
4566
container: chartId.value,
4667
autoFit: true,
@@ -51,7 +72,7 @@ function initChart() {
5172
5273
chart
5374
.interval()
54-
.data(props.data)
75+
.data(validData)
5576
.transform({ type: 'stackY' })
5677
.encode('y', props.valueField)
5778
.encode('color', props.labelField)
@@ -66,7 +87,7 @@ function initChart() {
6687
})
6788
.label({
6889
text: (d) => {
69-
const total = props.data.reduce((sum, item) => sum + item[props.valueField], 0)
90+
const total = validData.reduce((sum, item) => sum + item[props.valueField], 0)
7091
const percent = ((d[props.valueField] / total) * 100).toFixed(1)
7192
return `${percent}%`
7293
},
@@ -81,7 +102,7 @@ function initChart() {
81102
.tooltip({
82103
items: [(d) => ({
83104
name: d[props.labelField],
84-
value: d[props.valueField] + ' (' + ((d[props.valueField] / props.data.reduce((sum, item) => sum + item[props.valueField], 0)) * 100).toFixed(1) + '%)'
105+
value: d[props.valueField] + ' (' + ((d[props.valueField] / validData.reduce((sum, item) => sum + item[props.valueField], 0)) * 100).toFixed(1) + '%)'
85106
})]
86107
})
87108
.style('stroke', '#fff')
@@ -99,11 +120,15 @@ function initChart() {
99120
}
100121
101122
onMounted(() => {
102-
initChart()
123+
setTimeout(() => {
124+
initChart()
125+
}, 100)
103126
})
104127
105128
watch(() => props.data, () => {
106-
initChart()
129+
setTimeout(() => {
130+
initChart()
131+
}, 50)
107132
}, { deep: true })
108133
109134
onBeforeUnmount(() => {

0 commit comments

Comments
 (0)