Appearance
故障排查
快速定位和解决常见问题。
诊断流程
按顺序检查:
控制台错误 → 数据格式 → 容器配置 → 浏览器兼容性常见错误
"Cannot read property 'exportImage' of null"
原因:组件引用为空
解决:
vue
<template>
<!-- ❌ 错误:ref 名称不匹配 -->
<RayBar ref="chart" :option="option" />
</template>
<script setup>
const chartRef = ref(null) // 变量名和 ref 不一致
</script>
<!-- ✅ 正确:ref 名称匹配 -->
<template>
<RayBar ref="chartRef" :option="option" />
</template>
<script setup>
const chartRef = ref(null)
</script>"WebGL context lost"
原因:GPU 资源耗尽
解决:减少同时渲染的图表数量、降低图表复杂度、刷新页面释放资源
javascript
// 监听 WebGL 上下文丢失
window.addEventListener('webglcontextlost', (event) => {
event.preventDefault()
console.warn('WebGL 上下文丢失,请刷新页面')
// 提示用户刷新
})"Failed to compile shader"
原因:GPU 不支持某些特性
解决:关闭高级后处理效果、使用简单材质、检查浏览器和 GPU 驱动更新
javascript
const option = {
series: [{ data: [120, 200, 150] }],
postprocessing: {
bloom: { enabled: false } // 关闭辉光
}
}渲染问题
图表显示全黑
可能原因:光照配置错误、材质颜色为黑色、相机位置不当
诊断:
javascript
// 1. 检查是否手动配置了光照
const option = {
series: [{ data: [120, 200, 150] }],
// 移除 lights 配置,使用自动光照
// lights: [...] // 注释掉
}
// 2. 检查材质颜色
const option = {
series: [{
data: [120, 200, 150],
color: ['#42b883'] // 确保不是黑色
}]
}
// 3. 启用光源辅助器调试
const option = {
series: [{ data: [120, 200, 150] }],
showLightHelpers: true
}图表闪烁或抖动
可能原因:
- Z-fighting(深度冲突)
- 数据更新过于频繁
- 浏览器性能问题
解决:
javascript
// 1. 调整 Z 轴偏移
const option = {
series: [{
data: [120, 200, 150],
itemStyle: {
polygonOffset: true,
polygonOffsetFactor: -1,
polygonOffsetUnits: -1
}
}]
}
// 2. 使用防抖合并高频更新(无需引入额外库)
let timer = null
function updateChart(newData) {
clearTimeout(timer)
timer = setTimeout(() => {
option.value = {
...option.value,
series: [{ data: newData }]
}
}, 100)
}图表模糊不清
可能原因:设备像素比问题、容器尺寸不当、抗锯齿未启用
解决:
html
<!-- 确保容器尺寸合适 -->
<div style="width: 800px; height: 600px">
<RayBar :option="option" width="100%" height="100%" />
</div>javascript
// 检查设备像素比
console.log('设备像素比:', window.devicePixelRatio)数据问题
数据不显示
诊断清单:
javascript
// ✅ 检查 1:数据格式正确
const option = {
series: [{
data: [120, 200, 150] // 数字数组
}],
xAxis3D: {
data: ['A', 'B', 'C'] // 类别数组
}
}
// ✅ 检查 2:数据不为空
console.log('数据:', option.series[0].data)
// ✅ 检查 3:数据范围合理
// 如果数据都是 0 或非常小,可能看不见
const hasValidData = option.series[0].data.some(v => v > 0)
console.log('有有效数据:', hasValidData)
// ✅ 检查 4:坐标轴范围
const option = {
series: [{ data: [120, 200, 150] }],
yAxis3D: {
min: 0, // 确保包含数据范围
max: 250
}
}数据更新不生效
组件对 option 做深度监听,直接修改与整体替换都会触发更新;若更新后未生效,优先排查以下两种情况:
javascript
// ❌ 常见错误 1:数据内容其实没变(内部会按内容哈希跳过重渲染)
option.value.series[0].data = [120, 200, 150] // 与旧数据完全相同
// ❌ 常见错误 2:修改的不是响应式对象
const rawOption = { series: [{ data: [1, 2, 3] }] } // 普通对象,非 ref/reactive
chartOption.value = rawOption
// ✅ 正确:保持 ref/reactive,且新数据与旧数据确有差异
option.value = {
...option.value,
series: [{
...option.value.series[0],
data: [180, 200, 150]
}]
}性能问题
帧率低(FPS < 30)
诊断工具:
javascript
// 监控帧率
let lastTime = performance.now()
let frames = 0
function checkFPS() {
frames++
const now = performance.now()
if (now >= lastTime + 1000) {
const fps = Math.round((frames * 1000) / (now - lastTime))
console.log('FPS:', fps)
if (fps < 30) {
console.warn('⚠️ 帧率过低,建议优化')
}
frames = 0
lastTime = now
}
requestAnimationFrame(checkFPS)
}
checkFPS()优化方案:
javascript
// 1. 减少数据量
const optimizedData = largeData.filter((_, i) => i % 2 === 0) // 采样
// 2. 简化材质
const option = {
series: [{
data: optimizedData,
itemStyle: {
metalness: 0,
roughness: 1
}
}],
postprocessing: {
bloom: { enabled: false } // 关闭辉光
}
}
// 3. 降低渲染质量(移动端)
const isMobile = /Mobile|Android|iPhone/i.test(navigator.userAgent)
if (isMobile) {
// 使用更小的尺寸
document.querySelector('#chart').style.height = '400px'
}内存泄漏
检查方法:
javascript
// 1. 使用 Chrome DevTools Memory Profiler
// 2. 检查组件销毁时是否清理资源
// ✅ 正确:清理事件监听
<script setup>
import { onBeforeUnmount } from 'vue'
const chartRef = ref(null)
let unsubscribe = null
onMounted(() => {
unsubscribe = chartRef.value?.on('click', handleClick)
})
onBeforeUnmount(() => {
// 清理事件监听
if (unsubscribe) {
unsubscribe()
}
})
</script>配置问题
TypeScript 类型错误
常见问题:
typescript
// ❌ 错误:类型不匹配
const option = {
series: [{
data: ['120', '200', '150'] // 字符串而非数字
}]
}
// ✅ 正确:使用正确类型
const option: RayChartOption = {
series: [{
data: [120, 200, 150] // 数字
}]
}
// ✅ 使用类型断言(确定类型正确时)
const option = {
series: [{
data: rawData.map(Number)
}]
} as RayChartOption配置不生效
检查优先级:
javascript
// 1. 组件 props:width / height 控制容器尺寸(与 option 无关)
<RayBar :option="option" width="800px" height="600px" />
// 2. series 配置覆盖默认值
const option = {
series: [{
data: [120, 200, 150],
color: ['#42b883'] // 覆盖默认颜色
}]
}
// 3. 检查拼写错误
const option = {
series: [{
data: [120, 200, 150],
itemStyle: {
metalness: 0.8, // ✅ 正确
// metaless: 0.8 // ❌ 拼写错误,不会生效
}
}]
}数据未变化不会重渲染
setOption 内部按内容哈希判断数据是否变化,内容完全一致时跳过渲染。修改配置后没生效时,请确认新值与旧值确实不同(例如新对象引用了同一份数组)。
浏览器兼容性
检测 WebGL 支持
直接使用 RayChart 内置的检测 API(见高级功能):
javascript
import { checkWebGLSupport } from 'raychart'
const support = checkWebGLSupport()
if (!support.supported) {
console.error('❌ 浏览器不支持 WebGL')
alert('您的浏览器不支持 WebGL,无法使用 3D 图表功能')
} else {
console.log('✅ WebGL 支持正常,版本:', support.version)
}需要打印完整能力信息时:
javascript
import { printWebGLCapabilities } from 'raychart'
printWebGLCapabilities() // 控制台分组打印版本、限制与扩展支持移动端特殊处理
javascript
const isMobile = /Mobile|Android|iPhone/i.test(navigator.userAgent)
const option = {
series: [{
data: isMobile ? sampledData : fullData
}],
postprocessing: {
bloom: { enabled: !isMobile } // 移动端关闭辉光
},
controlSettings: {
enableRotate: true,
enableZoom: true,
enablePan: true
}
}调试技巧
启用详细日志
javascript
// 在开发环境启用详细日志
if (import.meta.env.DEV) {
console.log('图表配置:', option)
console.log('图表引用:', chartRef.value)
}使用 Vue DevTools
- 安装 Vue DevTools 浏览器扩展
- 检查组件树中的 RayChart 组件
- 查看 props 和 data 是否正确
性能分析
javascript
// 使用 Performance API
performance.mark('chart-start')
// 渲染图表
await nextTick()
performance.mark('chart-end')
performance.measure('chart-render', 'chart-start', 'chart-end')
const measure = performance.getEntriesByName('chart-render')[0]
console.log('渲染耗时:', measure.duration, 'ms')获取帮助
以上方法都无法解决时:
- 查看文档:https://docs.raychart.cn
- 查看示例:https://raychart.cn/gallery
- 检查版本:确保使用最新版本
- 提供信息:RayChart 版本、浏览器版本、错误信息、最小可复现示例
