Echarts-3D柱状图

通过Echarts的echarts.graphic.extendShape实现真正的3D柱状图

思路就是通过调整顶部面(CubeTop)、左侧面(CubeLeft)、右侧面(CubeRight)来决定柱状图的宽窄

建议优先调整顶部面,一般c1不需要动

javascript 复制代码
// 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;
    // 顶部右侧顶点
    const c1 = [shape.x, shape.y];
    // 顶部左侧顶点
    const c2 = [shape.x - 15, shape.y - 8];
    // 底部左侧
    const c3 = [xAxisPoint[0] - 15, xAxisPoint[1] - 8];
    // 底部右侧
    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;
    // 顶部左侧顶点
    const c1 = [shape.x, shape.y];
    // 底部左侧顶点
    const c2 = [xAxisPoint[0], xAxisPoint[1]];
    // 底部右侧顶点
    const c3 = [xAxisPoint[0] + 15, xAxisPoint[1] - 8];
    // 顶部右侧顶点
    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) {
    // 底部顶点
    const c1 = [shape.x, shape.y];
    // 右侧顶点
    const c2 = [shape.x + 15, shape.y - 8];
    // 顶部顶点
    const c3 = [shape.x, shape.y - 15];
    // 右侧顶点
    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);

然后在build-bar-option中引用即可

这里主要就是把series中的内容复制过来直接用就行了

javascript 复制代码
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;
}
相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang2 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、5 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
mirrornan6 小时前
产品如何3D建模?如何根据使用场景选购3D扫描仪?
科技·3d·3d建模·3d模型·三维扫描
兔老大的胡萝卜6 小时前
关于 3D Engine Design for Virtual Globes(三维数字地球引擎设计)
人工智能·3d
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
深蓝学院6 小时前
无需姿态,即刻重建!NoPoSplat,重新定义3DGS的重建Pipeline
3d