最近项目中使用了比较多的echarts图表元素,遇到了一些问题,有些通过查询官方文档可以很快解决,有些就没那么容易了,故记录下!
先放一张图
问题1:在legend(图例组件)值不固定的情况下,保证柱状图展示正常
先介绍下背景,这里的柱状图是子组件,通过prop,父组件向子组件传值,并在子组件中使用watch监听传入数据的变化
这里给出子组件中的监听代码:
watch: {
data: {
handler(nv, ov) {
if (this.chart) {
this.chart.setOption(
{
...this.defaultOption,
series: [...this.series],
dataset: {
...nv
}
}
)
} else {
this.initChart()
}
},
deep: true
}
},
一开始,图表也很正常,直到多了一种legend数据
可以看出,这里的数据已经乱了,抛开颜色的问题,这里多的legend类型是已恢复,但是却没有正常渲染,我查看了传入的数据也是正常的,那么问题到底出在哪里呢?
经过一番网络查询,找出了一点眉目,使用echarts实例方法setOption更新配置的话,默认是合并参数和数据的,所以我们应该将其设置成不合并
watch: {
data: {
handler(nv, ov) {
if (this.chart) {
this.chart.setOption(
{
...this.defaultOption,
series: [...this.series],
dataset: {
...nv
}
},
true
)
} else {
this.initChart()
}
},
deep: true
}
}
经过测试,问题解决。
还没来的急高兴一波,新的问题来了,看图
问题2:如何实现如图所示的效果
查询了echarts文档,没有找到相关的实例,没办法,再一次网上找资料,经过漫长的搜寻,终于又让我找到了解决方案,那就是通过echarts设置自定义图形,这里的代码是直接copy经过简单的修改,但参考地址我忘记了,就不放连接了
var MyCubeRect = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0,
width: 36 // 柱宽
// zWidth: 8, // 阴影折角宽
// zHeight: 4 // 阴影折角高
},
buildPath: function(ctx, shape) {
const api = shape.api
const xAxisPoint = api.coord([shape.xValue, 0])
const p0 = [shape.x, shape.y]
const p1 = [shape.x - shape.width / 2, shape.y]
const p4 = [shape.x + shape.width / 2, shape.y]
const p2 = [xAxisPoint[0] - shape.width / 2, xAxisPoint[1]]
const p3 = [xAxisPoint[0] + shape.width / 2, xAxisPoint[1]]
ctx.moveTo(p0[0], p0[1]) // 0
ctx.lineTo(p1[0], p1[1]) // 1
ctx.lineTo(p2[0], p2[1]) // 2
ctx.lineTo(p3[0], p3[1]) // 3
ctx.lineTo(p4[0], p4[1]) // 4
ctx.lineTo(p0[0], p0[1]) // 0
ctx.closePath()
}
})
var MyCubeShadow = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0,
width: 36,
zWidth: 8,
zHeight: 6
},
buildPath: function(ctx, shape) {
const api = shape.api
const xAxisPoint = api.coord([shape.xValue, 0])
// const p0 = [shape.x, shape.y]
const p1 = [shape.x - shape.width / 2, shape.y]
const p4 = [shape.x + shape.width / 2, shape.y]
const p6 = [
shape.x + shape.width / 2 + shape.zWidth,
shape.y - shape.zHeight
]
const p7 = [
shape.x - shape.width / 2 + shape.zWidth,
shape.y - shape.zHeight
]
const p3 = [xAxisPoint[0] + shape.width / 2, xAxisPoint[1]]
const p5 = [
xAxisPoint[0] + shape.width / 2 + shape.zWidth,
xAxisPoint[1] - shape.zHeight
]
ctx.moveTo(p4[0], p4[1]) // 4
ctx.lineTo(p3[0], p3[1]) // 3
ctx.lineTo(p5[0], p5[1]) // 5
ctx.lineTo(p6[0], p6[1]) // 6
ctx.lineTo(p4[0], p4[1]) // 4
ctx.moveTo(p4[0], p4[1]) // 4
ctx.lineTo(p6[0], p6[1]) // 6
ctx.lineTo(p7[0], p7[1]) // 7
ctx.lineTo(p1[0], p1[1]) // 1
ctx.lineTo(p4[0], p4[1]) // 4
ctx.closePath()
}
})
echarts.graphic.registerShape('MyCubeRect', MyCubeRect)
echarts.graphic.registerShape('MyCubeShadow', MyCubeShadow)
//其他配置项省略
series: [
{
type: 'custom',
renderItem: function(params, api) {
const location = api.coord([api.value(0), api.value(1)])
return {
type: 'group',
children: [
{
type: 'MyCubeRect',
shape: {
api,
xValue: api.value(0),
yValue: api.value(1),
x: location[0],
y: location[1]
},
style: {
fill: '#1bc4eb'
}
},
{
type: 'MyCubeShadow',
shape: {
api,
xValue: api.value(0),
yValue: api.value(1),
x: location[0],
y: location[1]
},
style: {
fill: '#1496b3'
}
}
]
}
}
}
]
实际效果如下:
还是比较接近的,那么这个问题也解决!
好的,新的问题
问题3:横坐标数据动态变化的情况下,正常展示
因为在问题二中,柱子的图形是通多自定义图形绘制的,所以图形的位置啥的都是按照目前的画布来的,突然多了一组数据,图形位置什么就会错乱。本来觉得按照问题一的解法应该可以解决问题,但并无卵用,所以就找找资料呗,我的想法是,如果不能更新图形,不如在每次数据变化的时候,先清空画布在重新绘制
这里的方案如下:
watch: {
data(nv, ov) {
this.chart.clear()
this.chart.setOption({
...this.defaultOption,
dataset: {
...this.data
}
})
}
}
终于,收工!
各位如果有其他的解法,也请告知,路漫漫其修远兮,吾将上下而求索!