echarts绘制立方体

176 阅读2分钟

需求和分析

需求:

绘制一些立方体,并绘制出一个点,判定该点是否落在某个区域(立方体)内

因为是立方体,所以考虑使用echarts-gl。也考虑过使用其他方式,例如HighCharts、three.js、canvas、webgl,但综合需求考虑,且方便代码编写(旋转和绘制坐标轴),最终考虑echarts-gl

方案

echarts-gl使用的series类型为surface曲面图【文档】, 然后分别绘制立方体的六个面

Snipaste_2024-09-03_16-54-57.png

api梳理

surface中有参数parametricEquation,用来根据函数绘制曲面 其中uv分别设置区间、步进,然后echarts会循环调用xyz函数计算坐标

const parametricEquation = {
    u: {min: 0, max: 10, step: 1},
    v: {min: 0, max: 10, step: 1},
    x: (u, v) => u,
    y: (u, v) => v,
    z: (u, v) => u + v
}

完整代码

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="Author" content="Honyee">
  <meta name="Keywords" content="Honyee">
  <meta name="Description" content="Honyee">
  <title>echarts-gl绘制立方体</title>
</head>
<body>
<div id="app">
  <div id="main" style="width: 800px;height:500px;"></div>
</div>
</body>

<script src="vue.js"></script>
<script src="echarts.min.js"></script>
<script src="echarts-gl.min.js"></script>

var app = new Vue({
    el: '#app',
    data() {
      return {
        // surface基本配置
        surfaceConfig: {
          type: 'surface',
          parametric: true,
          wireframe: {
            show: false
          },
          shading: 'color',
          itemStyle: {
            opacity: 0.5
          }
        }
      }
    },
    methods: {
      startDraw() {
        let chartInstance = echarts.init(document.getElementById('main'));

        const cv = 60; // 长
        const kv = 89; // 宽
        const gv = 119; //  高
        const xv = 221; // x起点
        const yv = 191; // y起点
        const zv = 0; // z起点

        const option = {
          tooltip: {},
          xAxis3D: {},
          yAxis3D: {},
          zAxis3D: {},
          grid3D: {
            show: true,
            temporalSuperSampling: {
              enable: true
            },
          },
          series: this.drawCube(cv, kv, gv, xv, yv, zv, 'green')
        }
        chartInstance.setOption(option);

      },
      /**
       * 绘制立方体
       * @param cv 长
       * @param kv 宽
       * @param gv 高
       * @param xv x起点
       * @param yv y起点
       * @param zv z起点
       * @param color 立方体颜色
       */
      drawCube(cv, kv, gv, xv, yv, zv, color) {
        const series = [];
        const surfaceConfig = {...this.surfaceConfig};
        surfaceConfig.itemStyle = {...surfaceConfig.itemStyle}
        surfaceConfig.itemStyle.color = color;
        {
          // 底部
          const parametricEquation = {
            u: {min: xv, max: xv + cv, step: 1},
            v: {min: yv, max: yv + kv, step: 1},
            x: (u, v) => u,
            y: (u, v) => v,
            z: (u, v) => zv
          }
          series.push({...surfaceConfig, parametricEquation});
        }
        {
          // 顶部
          const parametricEquation = {
            u: {min: xv, max: xv + cv, step: 1},
            v: {min: yv, max: yv + kv, step: 1},
            x: (u, v) => u,
            y: (u, v) => v,
            z: (u, v) => zv + gv
          }
          series.push({...surfaceConfig, parametricEquation});
        }

        {
          // 侧面1
          const parametricEquation = {
            u: {min: zv, max: zv + gv, step: 1},
            v: {min: yv, max: yv + kv, step: 1},
            x: (u, v) => xv,
            y: (u, v) => v,
            z: (u, v) => u
          }
          series.push({...surfaceConfig, parametricEquation});
        }
        {
          // 侧面2
          const parametricEquation = {
            u: {min: zv, max: zv + gv, step: 1},
            v: {min: yv, max: yv + kv, step: 1},
            x: (u, v) => xv + cv,
            y: (u, v) => v,
            z: (u, v) => u
          }
          series.push({...surfaceConfig, parametricEquation});
        }

        {
          // 侧面3
          const parametricEquation = {
            u: {min: xv, max: xv + cv, step: 1},
            v: {min: zv, max: zv + gv, step: 1},
            x: (u, v) => u,
            y: (u, v) => yv,
            z: (u, v) => v
          }
          series.push({...surfaceConfig, parametricEquation});
        }

        {
          // 侧面4
          const parametricEquation = {
            u: {min: xv, max: xv + cv, step: 1},
            v: {min: zv, max: zv + gv, step: 1},
            x: (u, v) => u,
            y: (u, v) => yv + kv,
            z: (u, v) => v
          }
          series.push({...surfaceConfig, parametricEquation});
        }
        return series;
      }
    },
    mounted() {
      this.startDraw();
    }
  })