需求和分析
需求:
绘制一些立方体,并绘制出一个点,判定该点是否落在某个区域(立方体)内
因为是立方体,所以考虑使用echarts-gl。也考虑过使用其他方式,例如HighCharts、three.js、canvas、webgl,但综合需求考虑,且方便代码编写(旋转和绘制坐标轴),最终考虑echarts-gl
方案:
echarts-gl使用的series类型为surface,曲面图【文档】,
然后分别绘制立方体的六个面
api梳理
surface中有参数parametricEquation,用来根据函数绘制曲面
其中u和v分别设置区间、步进,然后echarts会循环调用x、y、z函数计算坐标
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();
}
})