Skip to content

最佳实践

RayChart 的最佳用法,帮你构建高性能、易维护的 3D 可视化。

阅读建议

假设你已完成 快速上手,了解基本用法。

组件选择

优先用语义化组件

语义化组件让代码更清晰。

vue
<template>
  <RayBar :option="barOption" />
  <RayLine :option="lineOption" />
  <RayPie :option="pieOption" />
</template>
vue
<template>
  <!-- 不清晰,需要查看 option 才知道图表类型 -->
  <RayChart :option="option" />
</template>

优势

  • ✅ 代码可读性更强
  • ✅ IDE 自动补全更准确
  • ✅ 类型检查更严格
  • ✅ 团队协作更清晰

配置策略

渐进式配置

"最小化配置,按需增强"。

javascript
// 只提供必需的数据
const option = {
  series: [{ data: [120, 200, 150] }],
  xAxis3D: { data: ['A', 'B', 'C'] }
}
// ✅ 自动配置:光照、颜色、交互
javascript
// 需要特定颜色时才配置
const option = {
  series: [{
    data: [120, 200, 150],
    color: ['#42b883', '#35495e', '#ff6b6b']
  }],
  xAxis3D: { data: ['A', 'B', 'C'] }
}
javascript
// 需要特殊效果时才深度定制
const option = {
  series: [{
    data: [120, 200, 150],
    color: ['#42b883'],
    itemStyle: {
      metalness: 0.8,
      roughness: 0.2,
      emissive: '#42b883',
      emissiveIntensity: 0.5
    }
  }],
  xAxis3D: { data: ['A', 'B', 'C'] },
  postprocessing: {
    enable: true,
    bloom: { enable: true, strength: 1.5 }
  }
}

性能优化

数据更新策略

javascript
// Vue 会自动追踪变化
chartOption.value.series[0].data = newData
javascript
// 触发整个图表重新渲染,性能差
chartOption.value = {
  ...chartOption.value,
  series: [{ data: newData }]
}

大数据集优化

处理大量数据的优化:

javascript
const option = {
  series: [{
    data: largeDataset,  // 数千个数据点
    itemStyle: {
      // 简化材质
      metalness: 0,
      roughness: 1,
      // 降低透明度
      opacity: 0.6
    }
  }],
  // 关闭后处理
  postprocessing: {
    enable: false
  }
}
性能优化清单

数据层面

  • 数据采样 - 保留关键点
  • 数据聚合 - 合并相近数据
  • 分页加载 - 按需加载数据

渲染层面

  • 简化材质 - metalness: 0, roughness: 1
  • 关闭后处理 - postprocessing.enable: false
  • 降低透明度 - opacity: 0.6
  • 减小几何体尺寸

交互层面

  • 禁用不必要的动画
  • 限制交互频率 - 防抖/节流
  • 按需渲染 - 只在交互时更新

移动端优化

javascript
const isMobile = /Mobile|Android|iPhone/i.test(navigator.userAgent)

const option = {
  series: [{
    // 移动端使用采样数据
    data: isMobile ? sampledData : fullData
  }],
  postprocessing: {
    // 移动端关闭后处理
    enable: !isMobile
  }
}

TypeScript 最佳实践

完整类型定义

为配置添加类型:

typescript
import { ref } from 'vue'
import type { RayChartOption, Series3D } from 'raychart'

// 为配置添加类型
const chartOption = ref<RayChartOption>({
  series: [{
    data: [120, 200, 150]
  }],
  xAxis3D: {
    data: ['A', 'B', 'C']
  }
})

// 为系列数据添加类型
const createSeries = (data: number[]): Series3D => ({
  data,
  itemStyle: {
    metalness: 0.5,
    roughness: 0.5
  }
})

类型导入

typescript
// 导入常用类型
import type {
  RayChartOption,
  Series3D,
  Axis3D,
  LightConfig,
  PostprocessingOptions
} from 'raychart'

事件处理

声明式事件(推荐)

vue
<template>
  <RayBar 
    :option="chartOption"
    @click="handleClick"
    @mouseover="handleHover"
  />
</template>

<script setup>
const handleClick = (payload) => {
  console.log('点击数据:', payload.data)
  console.log('数据索引:', payload.dataIndex)
}

const handleHover = (payload) => {
  // 显示自定义提示
  showCustomTooltip(payload)
}
</script>

命令式事件(高级)

仅在需要动态管理监听器时使用:

vue
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'

const chartRef = ref()
let unsubscribe: (() => void) | undefined

onMounted(() => {
  // 动态添加监听器
  unsubscribe = chartRef.value?.on('click', (payload) => {
    console.log('Clicked:', payload)
  })
})

onBeforeUnmount(() => {
  // 清理监听器
  unsubscribe?.()
})
</script>

<template>
  <RayBar ref="chartRef" :option="chartOption" />
</template>

响应式布局

容器自适应

vue
<template>
  <div class="chart-container">
    <RayBar :option="chartOption" />
  </div>
</template>

<style scoped>
.chart-container {
  display: flex;
  width: 100%;
  height: 600px;
}
</style>
vue
<template>
  <div class="dashboard">
    <RayBar :option="salesOption" />
    <RayLine :option="trendOption" />
    <RayPie :option="distributionOption" />
  </div>
</template>

<style scoped>
.dashboard {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
  padding: 20px;
}
</style>

固定尺寸

vue
<template>
  <!-- 方式 1:组件 props -->
  <RayBar :option="chartOption" width="800px" height="600px" />
  
  <!-- 方式 2:容器样式 -->
  <div style="width: 800px; height: 600px">
    <RayBar :option="chartOption" />
  </div>
</template>

主题定制

颜色主题

javascript
// 定义主题色板
const themes = {
  default: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de'],
  business: ['#2c3e50', '#3498db', '#e74c3c', '#f39c12', '#1abc9c'],
  tech: ['#00d4ff', '#00ff9f', '#ff00ff', '#ffff00', '#ff6b00']
}

// 应用主题
const option = {
  series: [{
    data: [120, 200, 150],
    color: themes.tech
  }]
}

材质主题

javascript
// 定义材质预设
const materials = {
  matte: { metalness: 0, roughness: 1 },
  glossy: { metalness: 0.8, roughness: 0.2 },
  metal: { metalness: 0.9, roughness: 0.1 }
}

// 应用材质
const option = {
  series: [{
    data: [120, 200, 150],
    itemStyle: materials.glossy
  }]
}

调试技巧

光照调试

javascript
const option = {
  series: [{ data: [120, 200, 150] }],
  showLightHelpers: true  // 显示光源辅助器
}

数据验证

javascript
// 开发环境启用数据验证
if (import.meta.env.DEV) {
  console.log('图表配置:', chartOption.value)
  console.log('数据格式:', chartOption.value.series[0].data)
}

代码组织

配置抽离

javascript
// chartConfigs.js
export const barChartConfig = {
  series: [{
    data: [120, 200, 150]
  }],
  xAxis3D: {
    data: ['A', 'B', 'C']
  }
}

export const lineChartConfig = {
  series: [{
    data: [100, 150, 200]
  }],
  xAxis3D: {
    data: ['Jan', 'Feb', 'Mar']
  }
}
vue
<!-- Dashboard.vue -->
<script setup>
import { barChartConfig, lineChartConfig } from './chartConfigs'
</script>

<template>
  <RayBar :option="barChartConfig" />
  <RayLine :option="lineChartConfig" />
</template>

Composable 封装

javascript
// useChartData.js
import { ref, computed } from 'vue'

export function useChartData(initialData) {
  const data = ref(initialData)
  
  const chartOption = computed(() => ({
    series: [{ data: data.value }],
    xAxis3D: {
      data: data.value.map((_, i) => `Item ${i + 1}`)
    }
  }))
  
  const updateData = (newData) => {
    data.value = newData
  }
  
  return {
    chartOption,
    updateData
  }
}
vue
<script setup>
import { useChartData } from './useChartData'

const { chartOption, updateData } = useChartData([120, 200, 150])
</script>

<template>
  <RayBar :option="chartOption" />
</template>

相关资源