使用Echart线柱混合图排坑记录
在Vue中使用Echart
- 官方文档
https://echarts.apache.org/zh/option.html#title
- 安装
//vue 2
npm install echarts vue-echarts
npm i -D @vue/composition-api
//vue 3
npm install echarts vue-echarts
- 引用
//可全局也可在要使用的文件中用
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { PieChart } from 'echarts/charts'
import {
TitleComponent,
TooltipComponent,
LegendComponent
} from 'echarts/components'
import ECharts, { THEME_KEY } from 'vue-echarts'
use([
CanvasRenderer,
PieChart,
TitleComponent,
TooltipComponent,
LegendComponent
])
- 完整示例
这是一个简单折线图的示例,想要触发重绘的话直接设置data的options即可。
注意:Echart必须要设置高度,否则会出现异常情况,出现白屏的现象
<template>
<v-chart class="chart" :option="options" />
</template>
<script>
import ECharts from 'vue-echarts'
import 'echarts'
export default {
components: {
'v-chart': ECharts,
},
data() {
return {
options: {
xAxis: {
type: "category",
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
},
yAxis: {},
series: [{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: "line"
}]
}
}
},
}
</script>
<style scoped>
.chart {
height: 400px;
}
</style>
这里我们进入正题,折柱混合情况,其实也是所有的各类混合图都会遇到的问题
来一段标准的或者说是官方示例:
<template>
<v-chart class="chart" :option="options" />
</template>
<script>
import ECharts from 'vue-echarts'
import 'echarts'
export default {
components: {
'v-chart': ECharts,
},
data() {
return {
options: {
legend: {
data: ['蒸发量', '降水量']
},
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
name: 'Precipitation',
min: 0,
max: 250,
interval: 50,
axisLabel: {
formatter: '{value} ml'
}
}
],
series: [
{
name: '蒸发量',
type: 'bar',
tooltip: {
valueFormatter: function (value) {
return value + ' ml';
}
},
data: [
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
]
},
{
name: '降水量',
type: 'line',
tooltip: {
valueFormatter: function (value) {
return value + ' ml';
}
},
data: [
2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3
]
}
]
}
}
},
}
</script>
<style scoped>
.chart {
height: 400px;
}
</style>
看效果是不是觉得很完美,但是现实会遇到各种各样的问题
- 第一个问题:两个视图的x轴不一致情况,比如说蒸发量没有二月份数据,这种情况下这样子的代码显示就不行了。
这个问题看了下官方文档找到解决方案就是使用值和x轴的值去对应,官方说明如下:
『值』与 轴类型 的关系:
- 当某维度对应于数值轴(axis.type 为
'value'
或者'log'
)的时候:
其值可以为number
(例如12
)。(也可以兼容string
形式的 number,例如'12'
) - 当某维度对应于类目轴(axis.type 为
'category'
)的时候:
其值须为类目的『序数』(从0
开始)或者类目的『字符串值』。例如:
xAxis: {
type: 'category',
data: ['星期一', '星期二', '星期三', '星期四']
},
yAxis: {
type: 'category',
data: ['a', 'b', 'm', 'n', 'p', 'q']
},
series: [{
data: [
// xAxis yAxis
[ 0, 0, 2 ], // 意思是此点位于 xAxis: '星期一', yAxis: 'a'。
[ '星期四', 2, 1 ], // 意思是此点位于 xAxis: '星期四', yAxis: 'm'。
[ 2, 'p', 2 ], // 意思是此点位于 xAxis: '星期三', yAxis: 'p'。
[ 3, 3, 5 ]
]
}]
// 在数据进来之后处理下数据
// 1. 遍历各个视图的数据元,把x轴的值合并去重,然后排序,
// 2. 给各个series设置对应的值,值每个项对应[`${item[0]}`, item[1]],就是把x轴转为字符串,然后对应y轴的值。
render(data) {
if (Object.keys(data).length) {
let xdata = []
for (let i = 0; i < this.keys.length; i++) {
let key = this.keys[i]
this.options.series[i].data = data[key]
? data[key].map(item => [`${item[0]}`, item[1]])
: []
let date = data[key] ? data[key].map(item => `${item[0]}`) : []
xdata = [...xdata, ...date]
this.options.series[i].name = key
}
xdata = Array.from(new Set(xdata))
this.options.xAxis.data = xdata ? xdata.sort((a, b) => a - b) : []
} else {
this.clearChart()
}
},
clearChart() {
if (this.init) {
this.$refs.chart.clear()
}
},
提测,感觉没啥问题,x轴排序了,然后x轴和y轴也一一对应了。但是打脸来的飞快,线图是乱的
贴个示意图
看了下发现数据源是没排过序的,所以,x轴排序了,x和y的值也是对应的,但是线图的点是顺序画的,所以要先对数据源进行排序才行
// 在数据进来之后处理下数据
// 1. 先将数据按照x轴大小进行排序,保证x轴数据从小到大展示
// 2. 遍历各个视图的数据元,把x轴的值合并去重,然后排序,
// . 给各个series设置对应的值,值每个项对应[`${item[0]}`, item[1]],就是把x轴转为字符串,然后对应y轴的值。
render(data) {
if (Object.keys(data).length) {
let xdata = []
for (let i = 0; i < this.keys.length; i++) {
let key = this.keys[i]
// 先将数据按照x轴大小进行排序,保证x轴数据从小到大展示
list[key] && (list[key] = list[key].sort((a, b) => a[0] - b[0]))
this.options.series[i].data = list[key]
? list[key].map(item => [`${item[0]}`, item[1]])
: []
let date = data[key] ? data[key].map(item => `${item[0]}`) : []
xdata = [...xdata, ...date]
this.options.series[i].name = key
}
xdata = Array.from(new Set(xdata))
this.options.xAxis.data = xdata ? xdata.sort((a, b) => a - b) : []
} else {
this.clearChart()
}
},
clearChart() {
if (this.init) {
this.$refs.chart.clear()
}
},