echarts3D堆叠柱状图+3D背景

这次涉及的效果,和之前发布的文章(如何自定义echarts悬浮窗echarts的tooltip悬浮窗的自定义_zero00122的博客-CSDN博客)是一个图。

这次则是把堆叠柱状图变为3D效果并且还要有个同样3D效果的柱状背景

思路:用顶部小圆盖+带下侧圆角边框的柱体组成一个伪3D柱子。堆叠在上的柱子底部就不需要圆角边框了。难点是x轴每个单位上都要有一个3D柱状的阴影背景。

大家仔细看这个阴影背景头顶上也有一个小圆盖子。其实实现也很简单,不要把这个想成背景,把这个同样看成一个柱子就行了,只不过它的高度是y轴最大值减去其他柱子高度的合。

let option = {
        //鼠标移入柱子不会有高亮效果
        emphasis: {
          disabled: true,
        },
        series: [
          {
            name: "存量(兆瓦)",
            legendHoverLink: false,
            type: "bar",
            stack: "Ad",
            color: {
              type: "linear",
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [
                {
                  offset: 0,
                  color: "#785BE4", // 0% 处的颜色
                },
                {
                  offset: 1,
                  color: "#A7CCF8", // 100% 处的颜色
                },
              ],
              global: false, // 缺省为 false
            },
            itemStyle: {
              normal: {
                barBorderRadius: [0, 0, 5, 5], // 让柱形上下变成圆角
                opacity: 0.5,
              },
            },
            emphasis: {
              focus: "series",
            },
            data: this.dataList3,
          },
          //存量顶部的圆盘
          {
            name: "存量(兆瓦)",
            legendHoverLink: false,
            symbolOffset: [0, -3], // 椭圆水平偏移,垂直偏移. 因为不一定正好盖住柱形,所以可能要移动一点点
            tooltip: {
              show: false,
            },
            type: "pictorialBar",
            color: "#785BE4",
            itemStyle: {
              opacity: 0.75,
            },
            symbol: "circle",
            symbolSize: ["83%", 20 / 2.5],
            symbolPosition: "end", // 图形边缘与柱子结束的地方内切。
            data: [
              30,
              40,
              50,
              70,
              90,
              140,
              200,
              300,
              //数据为0就通过这种方式把圆盖给隐藏
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
            ], // 数据要跟主体柱形一致
            z: 4, // 数值越大,层级越高,可以盖住下面的图形
          },
          {
            name: "增量(兆瓦)",
            legendHoverLink: false,
            type: "bar",
            stack: "Ad",
            color: {
              type: "linear",
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [
                {
                  offset: 0,
                  color: "#1ADBC7", // 0% 渐变顶部色
                },
                {
                  offset: 1,
                  color: "#2D6CE9", // 100% // 渐变底部色
                },
              ],
              global: false, // 缺省为 false
            },
            itemStyle: {
              normal: {
                // barBorderRadius: [20 / 3.5, 20 / 3.5, 0, 0], // 让柱形上下变成圆角
                opacity: 0.75,
              },
            },
            // showBackground:"true",
            emphasis: {
              focus: "series",
            },
            data: this.dataList6
              ? this.datalist6
              : [40, 10, 20, 20, 50, 60, 100, 150, 0, 0, 0, 0], //有bug,已解决
          },
          //增量顶部圆盘
          {
            name: "增量(兆瓦)",
            legendHoverLink: false,
            symbolOffset: [0, -3], // 椭圆水平偏移,垂直偏移. 因为不一定正好盖住柱形,所以可能要移动一点点
            tooltip: {
              show: false,
            },
            type: "pictorialBar",
            color: "#26A4FF",
            itemStyle: {
              opacity: 1,
            },
            symbol: "circle",
            symbolSize: ["83%", 20 / 2.5],
            symbolPosition: "end", // 图形边缘与柱子结束的地方内切。
            data: [
              70,
              50,
              70,
              90,
              140,
              200,
              300,
              450,
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
            ], // 数据要跟主体柱形一致
            z: 4, // 数值越大,层级越高,可以盖住下面的图形
          },
          {
            name: "“十四五”目标",
            legendHoverLink: false,
            type: "bar",
            stack: "Ad",
            itemStyle: {
              color: {
                type: "linear",
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [
                  {
                    offset: 0,
                    color: "#82E547", // 渐变顶部色
                  },
                  {
                    offset: 1,
                    color: "#2FE8E8", // 渐变底部色
                  },
                ],
                global: false, // 缺省为 false
              },
              barBorderRadius: [0, 0, 5, 5],
              opacity: 0.5,
            },
            // emphasis: {
            //   focus: "series",
            // },
            data: this.data_shisiwu,
          },
          //十四五顶部圆盘
          {
            name: "“十四五”目标",
            legendHoverLink: false,
            symbolOffset: [0, -3], // 椭圆水平偏移,垂直偏移. 因为不一定正好盖住柱形,所以可能要移动一点点
            tooltip: {
              show: false,
            },
            type: "pictorialBar",
            color: "#1ccd88",
            itemStyle: {
              opacity: 1,
            },
            symbol: "circle",
            symbolSize: ["83%", 20 / 2.5],
            symbolPosition: "end", // 图形边缘与柱子结束的地方内切。
            data: [
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
              800,
            ], // 数据要跟主体柱形一致
            z: 4, // 数值越大,层级越高,可以盖住下面的图形
          },
          {
            name: "",
            type: "bar",
            stack: "Ad",
            color: "#2d3e53",
            legendHoverLink: false,
            itemStyle: {
              normal: {
                barBorderRadius: 20 / 3.5, // 让柱形上下变成圆角
                opacity: 0.25,
              },
            },
            emphasis: {
              focus: "series",
            },
            data: [730, 750, 730, 710, 660, 600, 500, 350, 800, 800, 800, 0],
          },
          //背景阴影圆盘
          {
            name: "purple",
            legendHoverLink: false,
            symbolOffset: [0, -3], // 椭圆水平偏移,垂直偏移. 因为不一定正好盖住柱形,所以可能要移动一点点
            tooltip: {
              show: false,
            },
            type: "pictorialBar",
            color: "#2d3e53",
            itemStyle: {
              opacity: 0.25,
            },
            symbol: "circle",
            symbolSize: ["83%", 20 / 2.5],
            symbolPosition: "end", // 图形边缘与柱子结束的地方内切。
            data: [
              800,
              800,
              800,
              800,
              800,
              800,
              800,
              800,
              800,
              800,
              800,
              {
                value: 0,
                itemStyle: {
                  color: "transparent",
                },
              },
            ], // 数据要跟主体柱形一致
            z: 10, // 数值越大,层级越高,可以盖住下面的图形
          },
        ],
        tooltip: {
          trigger: "axis",
          formatter: (item) => {
            //将复用的模板字符串封装成函数,这里就相当于tooltip中显示的一行数据如下图
            //通过输入val,就能判断这个是series的第几个数据,0 是存量,1是增量,2是十四五
            //字符串中出入了三个数据分别用处是:小圆点颜色、数据名、数值,都是能在formatter的params中获取的,我这里命名为item
            function str(val) {
              return `
               <div class='hang'>
                <div style="display:flex;align-items: baseline;">
                  <div class="small" style='background-color:${item[val].color.colorStops[0].color};'></div>
                  <div style:"float:left">${item[val].seriesName}</div>  
                </div>
                <div style='font-weight:700'>${item[val].value}</div>
               </div>
                `;
            }
            //这里判断如果不是2025年就显示 存量和增量
            if (item[0].name != "2025") {
              return `
              <div class='echarts-tooltip'>
              ${item[0].name}<br>
               ${str(0)}
               ${str(1)}
              `;
            } else {
              //如果是2025年就显示 十四五
              return `
              <div class='echarts-tooltip'>
              ${item[0].name}<br>
               ${str(2)}
              `;
            }
          },
        },
        legend: {
          left: "1%",
          textStyle: {
            fontSize: 10, //字体大小
            color: "rgba(255, 255, 255, 0.75)", //字体颜色
          },
          formatter: (params) => {
            if (params == "存量(兆瓦)") {
              return "存量";
            } else if (params == "增量(兆瓦)") {
              return "增量";
            } else if (params == "“十四五”目标") {
              return params;
            }
            console.log(params);
          },
          data: [
            {
              name: "存量(兆瓦)",
            },
            { name: "增量(兆瓦)" },
            { name: "“十四五”目标" },
          ],
        },
        grid: {
          left: "5%",
          right: "",
          bottom: "3%",
          containLabel: true,
        },
        xAxis: [
          {
            type: "category",
            axisLabel: {
              interval: 0, //数据间隔
              //  改变x文字轴颜色
              textStyle: {
                color: "rgba(255, 255, 255, 0.75)",
                fontSize: 10,
              },
            },
            data: [
              "2014",
              "2015",
              "2016",
              "2017",
              "2018",
              "2019",
              "2020",
              "2021",
              "2022",
              "2023",
              "2024",
              "2025",
            ],
          },
        ],
        yAxis: [
          {
            name: "装机容量(兆瓦)",
            nameGap: 28,
            nameLocation: "center",
            nameTextStyle: {
              color: "rgba(255, 255, 255, 0.75)",
              fontSize: 10,
              // padding: [0, 0, 20, 0],
            },
            splitLine: {
              lineStyle: {
                opacity: 0.25,
              },
            },
            type: "value",
            axisLabel: {
              //  改变x轴文字颜色
              textStyle: {
                color: "rgba(255, 255, 255, 0.75)",
                fontSize: 10,
              },
            },
          },
        ],
      };

后期如果变为动态数据,这里面的data值还要进行变化。

欢迎大家来评论区留言,或者告诉我有那些可以优化的地方(感觉肯定有更方便的方法,只是我没有发现),谢谢大家。

猜你喜欢

转载自blog.csdn.net/zero00122/article/details/128376732
今日推荐