Skip to content

故障排查

快速定位和解决常见问题。

诊断流程

按顺序检查:

控制台错误 → 数据格式 → 容器配置 → 浏览器兼容性

常见错误

"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
}

图表闪烁或抖动

可能原因

  1. Z-fighting(深度冲突)
  2. 数据更新过于频繁
  3. 浏览器性能问题

解决

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

  1. 安装 Vue DevTools 浏览器扩展
  2. 检查组件树中的 RayChart 组件
  3. 查看 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')

获取帮助

以上方法都无法解决时:

  1. 查看文档:https://docs.raychart.cn
  2. 查看示例:https://raychart.cn/gallery
  3. 检查版本:确保使用最新版本
  4. 提供信息:RayChart 版本、浏览器版本、错误信息、最小可复现示例

相关资源