Recently, I used a lot of echarts chart elements in my project. I encountered some problems. Some of them can be solved quickly by consulting the official documentation, while others are not so easy.

Let me show you a picture

Problem 1: Ensure that the bar chart is displayed properly when the value of Legend (Legend component) is not fixed

First, to introduce the background, the bar chart here is the child component. Through prop, the parent component transmits values to the child component, and watches the changes of incoming data in the child component

Here is the listening code in the child component:

watch: {
    data: {
      handler(nv, ov) {
        if (this.chart) {
          this.chart.setOption( { ... this.defaultOption,series: [...this.series],
              dataset: {
                ...nv
              }
            }
          )
        } else {
          this.initChart()
        }
      },
      deep: true}},Copy the code

At first, the diagram was fine, too, until legend data was added

It can be seen that the data here has been messed up. Apart from the color problem, the legend type has been restored, but the rendering is not normal. I have checked the incoming data and it is also normal.

Using the echarts instance method setOption to update the configuration, parameters and data are merged by default, so we should set it to no merge

watch: {
    data: {
      handler(nv, ov) {
        if (this.chart) {
          this.chart.setOption( { ... this.defaultOption,series: [...this.series],
              dataset: {
                ...nv
              }
            },
            true)}else {
          this.initChart()
        }
      },
      deep: true}}Copy the code

After testing, the problem was solved.

For those who haven’t come yet, there’s a new problem. Look at the picture

Question 2: How to achieve the effect as shown in the figure

After a long search, I finally found a solution, that is, to set custom graphics through Echarts. The code here is directly copied after a simple modification, but I forgot the reference address, so I will not put the connection

var MyCubeRect = echarts.graphic.extendShape({
  shape: {
    x: 0.y: 0.width: 36 / / column width
    // zWidth: 8, // shadow fold Angle width
    // 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)

// Other configuration items are omitted
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'}}}}]Copy the code

The actual effect is as follows:

Or relatively close, so this problem is also solved!

Ok, new question

Problem 3: The abscissa data dynamic changes in the case of normal display

Because in question 2, the graph of the column is drawn by a custom graph, so the position of the graph is based on the current canvas. Suddenly, a group of data is added, and the position of the graph will be confused. I thought the solution of problem 1 could solve the problem, but it didn’t work, so I just looked for the data. My idea is that if you can’t update the graph, it is better to empty the canvas and redraw it every time the data changes

Here’s the scheme:

watch: {
    data(nv, ov) {
      this.chart.clear()
      this.chart.setOption({ ... this.defaultOption,dataset: {
          ...this.data
        }
      })
    }
  }
Copy the code

Finally, call it a day!

If you have another solution, please let me know, the road is long, I see no end, I will search up and down!