Echarts-3D histogram

Achieve true 3D histogram through Echarts’ echarts.graphic.extendShape
The idea is to determine the width of the histogram by adjusting the top surface (CubeTop), left surface (CubeLeft), and right surface (CubeRight).
It is recommended to adjust the top surface first. Generally, c1 does not need to be moved.

// echarts-3D-bar-config.js
import Vue from "vue";

const echarts = Vue.prototype.echarts;

const CubeLeft = echarts.graphic.extendShape({<!-- -->
  shape: {<!-- -->
    x: 0,
    y: 0
  },
  buildPath: function (ctx, shape) {<!-- -->
    const xAxisPoint = shape.xAxisPoint;
    // Top right vertex
    const c1 = [shape.x, shape.y];
    // Top left vertex
    const c2 = [shape.x - 15, shape.y - 8];
    //bottom left
    const c3 = [xAxisPoint[0] - 15, xAxisPoint[1] - 8];
    //bottom right
    const c4 = [xAxisPoint[0], xAxisPoint[1]];
    ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[ 1]).closePath();
  }
});

const CubeRight = echarts.graphic.extendShape({<!-- -->
  shape: {<!-- -->
    x: 0,
    y: 0
  },
  buildPath: function (ctx, shape) {<!-- -->
    const xAxisPoint = shape.xAxisPoint;
    // Top left vertex
    const c1 = [shape.x, shape.y];
    //bottom left vertex
    const c2 = [xAxisPoint[0], xAxisPoint[1]];
    //bottom right vertex
    const c3 = [xAxisPoint[0] + 15, xAxisPoint[1] - 8];
    // Top right vertex
    const c4 = [shape.x + 15, shape.y - 8];
    ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[ 1]).closePath();
  }
});

const CubeTop = echarts.graphic.extendShape({<!-- -->
  shape: {<!-- -->
    x: 0,
    y: 0
  },
  buildPath: function (ctx, shape) {<!-- -->
    // bottom vertex
    const c1 = [shape.x, shape.y];
    // right vertex
    const c2 = [shape.x + 15, shape.y - 8];
    // top vertex
    const c3 = [shape.x, shape.y - 15];
    // right vertex
    const c4 = [shape.x - 15, shape.y - 8];
    ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[ 1]).closePath();
  }
});
echarts.graphic.registerShape("CubeLeft", CubeLeft);
echarts.graphic.registerShape("CubeRight", CubeRight);
echarts.graphic.registerShape("CubeTop", CubeTop);

Then reference it in build-bar-option
The main thing here is to copy the content in the series and use it directly.

import Vue from "vue";
import "./echarts-3D-Bar-config"

const echarts = Vue.prototype.echarts;

export function buildBarOption(vm, xData = [], seriesData = [], originData = []) {<!-- -->
  const option = {<!-- -->
    xAxis: {<!-- -->
      type: "category",
      axisLabel: {<!-- -->
        color: "#fff",
        rotate: 45,
        fontSize: 10
      },
      axisTick: {<!-- -->
        show: false
      },
      axisLine: {<!-- -->
        show: true,
        lineStyle: {<!-- -->
          color: "rgb(53, 179, 229)",
          width: 2
        }
      },
      data:xData
    },
    tooltip: {<!-- -->
      trigger: "item",
      axisPointer: {<!-- -->
        type: "shadow",
        label: {<!-- -->
          show: true
        }
      },
      backgroundColor: "transparent",
      padding: 0,
      formatter: function (params) {<!-- -->
        // console.log(params)
        return `
            <div style="padding: 15px; background: linear-gradient(180.00deg, rgb(3, 36, 76),rgb(19, 36, 127) 100%)">
              <p>test</p>
            </div>
        `;
      }
    },
    grid: {<!-- -->
      left: "15",
      bottom: "10",
      right: "10",
      top: "40",
      containLabel: true
    },
    yAxis: {<!-- -->
      type: "value",
      axisLabel: {<!-- -->
        color: "#fff"
      },
      splitLine: {<!-- -->
        show: true,
        lineStyle: {<!-- -->
          type: "dotted",
          color: "rgb(53, 179, 229)"
        }
      }
    },
    series: [
      {<!-- -->
        type: "custom",
        renderItem: (params, api) => {<!-- -->
          const location = api.coord([api.value(0), api.value(1)]);
          return {<!-- -->
            type: "group",
            children: [
              {<!-- -->
                type: "CubeLeft",
                shape: {<!-- -->
                  api,
                  xValue: api.value(0),
                  yValue: api.value(1),
                  x: location[0],
                  y: location[1],
                  xAxisPoint: api.coord([api.value(0), 0])
                },
                style: {<!-- -->
                  fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    {<!-- -->
                      offset: 0,
                      color: "#3B80E2"
                    },
                    {<!-- -->
                      offset: 1,
                      color: "#49BEE5"
                    }
                  ])
                }
              },
              {<!-- -->
                type: "CubeRight",
                shape: {<!-- -->
                  api,
                  xValue: api.value(0),
                  yValue: api.value(1),
                  x: location[0],
                  y: location[1],
                  xAxisPoint: api.coord([api.value(0), 0])
                },
                style: {<!-- -->
                  fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    {<!-- -->
                      offset: 0,
                      color: "#3B80E2"
                    },
                    {<!-- -->
                      offset: 1,
                      color: "#49BEE5"
                    }
                  ])
                }
              },
              {<!-- -->
                type: "CubeTop",
                shape: {<!-- -->
                  api,
                  xValue: api.value(0),
                  yValue: api.value(1),
                  x: location[0],
                  y: location[1],
                  xAxisPoint: api.coord([api.value(0), 0])
                },
                style: {<!-- -->
                  fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    {<!-- -->
                      offset: 0,
                      color: "#3B80E2"
                    },
                    {<!-- -->
                      offset: 1,
                      color: "#49BEE5"
                    }
                  ])
                }
              }
            ]
          };
        },
        data: seriesData
      },
      {<!-- -->
        data: seriesData,
        type: "bar",
        barWidth: 13,
        itemStyle: {<!-- -->
          color: "transparent"
        }
      }
    ]
  };

  return option;
}