需求分析
使用echarts绘制如下图的立体坐标系,需要用到echarts-gl,该坐标系有如下特点:
- 三个坐标轴(立体坐标系)
- 大刻度步进值为10倍:
0 ~ 0.1,0.1 ~ 1,1 ~ 10 - 第一段刻度的子刻度为10个:
0、0.01……0.1 - 其他段刻度的子刻度为9个:
0.1、0.2……1 - 只显示大刻度:
0.1、1、10
| 段 / 子刻度位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 第一段 | 0 | 0.01 | 0.02 | 0.03 | 0.04 | 0.05 | 0.06 | 0.07 | 0.08 | 0.09 | 0.1 |
| 第二段 | 0.1 | 0.2 | 0.3 | 0.4 | 0.5 | 0.6 | 0.7 | 0.8 | 0.9 | 1 | 缺少一格 |
| 第三段 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 缺少一格 |
因为子刻度分别为10个和9个,所以考虑了两种方案来绘制
方式一:小刻度宽度一致
- 每个小刻度的宽度为
10px - 第一段刻度的宽度:
100px - 其他段刻度的宽度:
90px
优点:10px是整数,计算精度时结果完整
缺点:大刻度宽度不一样
为何小刻度的宽度为10px?
方便精度计算,例如:
0 ~ 0.1刻度中,绘制0.012这个点,那么这个点的所在像素位置为
10px * 0.012 * 100 = 12px
0.1 ~ 1刻度中,绘制0.34这个点,那么这个点的所在像素位置为
100px + 10px * 0.34 * 10 = 134px
1 ~ 10刻度中,绘制2.5这个点,那么这个点的所在像素位置为
100px + 90px + 10px * (2.5 - 1) = 205px
绘制结果
绘制结果分析
因为第一段100px而其他段为90px,所以刻度的实际像素位置分别为100px、190px、280px,这三个数的最小公因数为10,所以绘制结果的刻度线看起来密密麻麻
下方是绘制刻度标签的代码:
xAxis3D: {
type: 'value',
name: 'X',
min: 0,
max: 280, // 最大像素
interval: 10, // 间隔10
axisLabel: {
formatter: function (value) {
switch (value) {
case 0:
return '0'
case 100:
return '0.1'
case 190:
return '1.0'
case 280:
return '10'
}
return ''
}
}
完整代码
<template>
<b-container>
<div id="main-honyee" style="width: 800px;height:500px;"></div>
</b-container>
</template>
<script>
import * as echarts from 'echarts';
import 'echarts-gl';
export default {
methods: {
startDraw() {
let chartInstance = echarts.init(document.getElementById('main-honyee'));
const option = {
tooltip: {},
xAxis3D: this.axisConfig('X'),
yAxis3D: this.axisConfig('Y'),
zAxis3D: this.axisConfig('Z'),
grid3D: {
show: true,
temporalSuperSampling: {
enable: true
},
viewControl: {
alpha: 30,
beta: 160
},
},
series: []
}
chartInstance.setOption(option);
},
axisConfig(name) {
return {
type: 'value',
name: name,
min: 0,
max: 280,
interval: 10,
axisLabel: this.axisLabelConfig(),
}
},
axisLabelConfig() {
return {
formatter: function(value){
// 隐藏原点
switch (value) {
case 0:
return '0'
case 100:
return '0.1'
case 190:
return '1.0'
case 280:
return 10
}
return ''
}
}
},
},
mounted() {
this.startDraw();
}
}
</script>
方式二:大刻度宽度一致
- 每一段大刻度的宽度为
100px - 第一段小刻度的宽度:
100px ÷ 10 = 10px - 其他段刻度的宽度:
100px ÷ 9 ≈ 11.1px
优点:大刻度宽度相同,看着比较整齐,且与需求坐标图一致
缺点:10px和11.1px相差11%左右,小刻度长度不一致。且11.1px是四舍五入后的结果,所以位置像素计算结果会存在些许误差
绘制结果
绘制结果分析
下方是绘制刻度标签的代码:
<template>
<b-container>
<div id="main-honyee" style="width: 800px;height:500px;"></div>
</b-container>
</template>
<script>
import * as echarts from 'echarts';
import 'echarts-gl';
export default {
methods: {
startDraw() {
let chartInstance = echarts.init(document.getElementById('main-honyee'));
const option = {
tooltip: {},
xAxis3D: this.axisConfig('X'),
yAxis3D: this.axisConfig('Y'),
zAxis3D: this.axisConfig('Z'),
grid3D: {
show: true,
temporalSuperSampling: {
enable: true
},
viewControl: {
alpha: 30,
beta: 160
},
},
series: []
}
chartInstance.setOption(option);
},
axisConfig(name) {
return {
type: 'value',
name: name,
min: 0,
max: 300,
interval: 100, // 间隔100
axisLabel: this.axisLabelConfig()
}
},
axisLabelConfig() {
const base = 10
const scaleLength = base * 10 // 每段长度
return {
formatter: function (value) {
switch (value) {
case 0:
return '0'
case scaleLength:
return '0.1'
case scaleLength * 2:
return '1.0'
case scaleLength * 3:
return 10
}
return ''
}
}
},
},
mounted() {
this.startDraw();
}
}
</script>
结论
两种方式都可以,优缺点取舍