echarts三维立体扇形图+三维立体环形图配置详解记录

news2024/12/28 20:53:06

先看效果,注:三维立体echarts比较吃性能,同一页面如果有多个三维图进行渲染,进行跳转时可呢能会对整体页面产生影响,具体解决方法可查看本人另一篇文章
多个echarts使用3D导致页面卡顿的解决办法

三维立体扇形图

在这里插入图片描述

三维立体环形图

在这里插入图片描述
其实主要代码是一样的
下面是扇形图代码

 getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
      // 计算
      let midRatio = (startRatio + endRatio) / 2;

      let startRadian = startRatio * Math.PI * 2;
      let endRadian = endRatio * Math.PI * 2;
      let midRadian = midRatio * Math.PI * 2;

      // 如果只有一个扇形,则不实现选中效果。
      // if (startRatio === 0 && endRatio === 1) {
      //     isSelected = false;
      // }
      isSelected = false;
      // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
      k = typeof k !== "undefined" ? k : 1 / 3;

      // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
      let offsetX = isSelected ? Math.sin(midRadian) * 0.1 : 0;
      let offsetY = isSelected ? Math.cos(midRadian) * 0.1 : 0;

      // 计算高亮效果的放大比例(未高亮,则比例为 1)
      let hoverRate = isHovered ? 1.05 : 1;

      // 返回曲面参数方程
      return {
        u: {
          min: -Math.PI,
          max: Math.PI * 3,
          step: Math.PI / 32,
        },

        v: {
          min: 0,
          max: Math.PI * 2,
          step: Math.PI / 20,
        },

        x: function (u, v) {
          if (u < startRadian) {
            return (
              offsetX +
              Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          if (u > endRadian) {
            return (
              offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
        },

        y: function (u, v) {
          if (u < startRadian) {
            return (
              offsetY +
              Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          if (u > endRadian) {
            return (
              offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
        },

        z: function (u, v) {
          if (u < -Math.PI * 0.5) {
            return Math.sin(u);
          }
          if (u > Math.PI * 2.5) {
            return Math.sin(u) * h * 0.1;
          }
          return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
        },
      };
    },
    getPie3D(pieData, internalDiameterRatio) {
      let series = [];
      let sumValue = 0;
      let startValue = 0;
      let endValue = 0;
      let legendData = [];
      let k =
        typeof internalDiameterRatio !== "undefined"
          ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
          : 1 / 3;

      // 为每一个饼图数据,生成一个 series-surface 配置
      for (let i = 0; i < pieData.length; i++) {
        sumValue += pieData[i].value;

        let seriesItem = {
          name:
            typeof pieData[i].name === "undefined"
              ? `series${i}`
              : pieData[i].name,
          type: "surface",
          parametric: true,
          wireframe: {
            show: false,
          },
          pieData: pieData[i],
          pieStatus: {
            selected: false,
            hovered: false,
            k: 1 / 10,
          },
        };

        if (typeof pieData[i].itemStyle != "undefined") {
          let itemStyle = {};

          typeof pieData[i].itemStyle.color != "undefined"
            ? (itemStyle.color = pieData[i].itemStyle.color)
            : null;
          typeof pieData[i].itemStyle.opacity != "undefined"
            ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
            : null;

          seriesItem.itemStyle = itemStyle;
        }
        series.push(seriesItem);
      }

      // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
      // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
      for (let i = 0; i < series.length; i++) {
        endValue = startValue + series[i].pieData.value;

        series[i].pieData.startRatio = startValue / sumValue;
        series[i].pieData.endRatio = endValue / sumValue;
        series[i].parametricEquation = this.getParametricEquation(
          series[i].pieData.startRatio,
          series[i].pieData.endRatio,
          false,
          false,
          k,
          series[i].pieData.value
        );

        startValue = endValue;

        legendData.push(series[i].name);
      }

      return series;
    },
    initChart2() {//这里是对echarts进行渲染
      if (document.getElementById("echarts14")) {
        let myChart = this.$echarts.init(document.getElementById("echarts14"));
        this.$api.MMS.Building.GetRunStatusData().then((res) => {//获取数据
          if (res.ok) {
            const optionsData = [
              {
                name: "运行",
                value: res.data.run,
                itemStyle: {
                  color: "#11D9A2",
                },
              },
              {
                name: "故障",
                value: res.data.error,
                itemStyle: {
                  color: "#EA6C00",
                },
              },
              {
                name: "停止",
                value: res.data.stop,
                itemStyle: {
                  color: "#CCCCCC",
                },
              },
            ];

            // 生成扇形的曲面参数方程,用于 series-surface.parametricEquation

            // 生成模拟 3D 饼图的配置项

            let series = this.getPie3D(optionsData, 0);//注意这里0代表扇形图,要是想要环形图这里范围为0-1,1是一个线圈,环形图个人推荐0.5-0.7之间比较好看

     
            let option2 = {
              backgroundColor: "transparent",

              legend: {//图例设置
                show: true,
                tooltip: {
                  show: true,
                },
                orient: "horizontal",
                x: "10%",

                data: ["运行", "故障", "停止"],
                bottom: "5%",
                right: "center",
                itemGap: 20,
                itemHeight: 14,
                itemWidth: 24,
                // right: "4%",
                textStyle: {
                  color: "#fff",
                  fontSize: 12,
                  rich: {
                    name: {
                      width: 50,
                      fontSize: 28,
                      color: "#B0D8DF",
                      fontFamily: "Source Han Sans CN",
                    },
                    value: {
                      width: 20,
                      fontSize: 28,
                      padding: [0, 5, 0, 5],
                      color: "#fff",
                      fontFamily: "Source Han Sans CN",
                    },
                    A: {
                      fontSize: 28,
                      color: "#B0D8DF",
                      fontFamily: "Source Han Sans CN",
                    },
                    rate: {
                      width: 50,
                      fontSize: 28,
                      padding: [0, 0, 0, 10],
                      // color: "#10DD24",
                      fontFamily: "Source Han Sans CN",
                    },
                    B: {
                      fontSize: 28,
                      // color: "#B0D8DF",
                      padding: [0, 0, 0, 0],
                      fontFamily: "Source Han Sans CN",
                    },
                  },
                },
                formatter: function (name) {
                  let total = 0;
                  let target;
                  for (let i = 0; i < optionsData.length; i++) {
                    total += optionsData[i].value;
                    if (optionsData[i].name === name) {
                      target = optionsData[i].value;
                    }
                  }
                  let arr = [
                    "    {name|" + name + "}",
                    "{value|" + target + "}{A|}",
                    "{rate|" + ((target / total) * 100).toFixed(1) + "}{B|%}",
                  ];
                  return arr.join("              ");
                },
              },
              animation: true,

              backgroundColor: "transparent",
              labelLine: {
                show: true,
                lineStyle: {
                  color: "#7BC0CB",
                },
                normal: {
                  show: true,
                  length: 10,
                  length2: 10,
                },
              },
              label: {
                show: true,
                position: "outside",
                formatter: "{b} \n{c}\n{d}%",
                textStyle: {
                  color: "rgba(176, 216, 223, 1)",
                  fontSize: 24,
                },
              },
              xAxis3D: {
                min: -1,
                max: 1,
              },
              yAxis3D: {
                min: -1,
                max: 1,
              },
              zAxis3D: {
                min: -1,
                max: 1,
              },
              grid3D: {
                show: false,
                boxHeight: 0.3,
                //top: '30%',
                left: "0%",
                top: "-20%",
                width: "100%",
                // environment: "rgba(255,255,255,0)",
                viewControl: {
                  distance: 265,//这个数值越大图就越小
                  alpha: 30,//倾斜角度
                  beta: 15,//起始渲染角度
                  autoRotate: true, // 自动旋转
                  rotateSensitivity: 1,//旋转灵敏度,鼠标按住不放可进行角度偏移
                  zoomSensitivity: 1,//缩放灵敏度,鼠标滚轮可修改大小
                  panSensitivity: 0,// 平移操作的灵敏度,值越大越灵敏。默认为1,设置为0后无法平移。支持使用数组分别设置横向和纵向的平移灵敏度
                },
              },
              series: series,
            };

         
            
             function  getHeight3D(series, height) {
            series.sort((a, b) => {  
                return (b.pieData.value - a.pieData.value);
            })
            return height * 25 / series[0].pieData.value;
        }


//动态设置整体高度,防止超出渲染框
            option2.grid3D.boxHeight =getHeight3D(option2.series,15)
            // 准备待返回的配置项,把准备好的 legendData、series 传入。
            myChart.clear();
            myChart.setOption(option2);

            window.onresize = function () {
              myChart.resize();
            };
          }
        });
      }
    },

注意:this.getPie3D(optionsData, 0);这里0代表扇形图,要是想要环形图这里范围为0-1,1是一个线圈,环形图个人推荐0.5-0.7之间比较好看

环形图源码如下(支持右边数据点击隐藏)


    getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
      // 计算
      let midRatio = (startRatio + endRatio) / 2;

      let startRadian = startRatio * Math.PI * 2;
      let endRadian = endRatio * Math.PI * 2;
      let midRadian = midRatio * Math.PI * 2;

      // 如果只有一个扇形,则不实现选中效果。
      // if (startRatio === 0 && endRatio === 1) {
      //     isSelected = false;
      // }
      isSelected = false;
      // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
      k = typeof k !== "undefined" ? k : 1 / 3;

      // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
      let offsetX = isSelected ? Math.sin(midRadian) * 0.1 : 0;
      let offsetY = isSelected ? Math.cos(midRadian) * 0.1 : 0;

      // 计算高亮效果的放大比例(未高亮,则比例为 1)
      let hoverRate = isHovered ? 1.05 : 1;

      // 返回曲面参数方程
      return {
        u: {
          min: -Math.PI,
          max: Math.PI * 3,
          step: Math.PI / 32,
        },

        v: {
          min: 0,
          max: Math.PI * 2,
          step: Math.PI / 20,
        },

        x: function (u, v) {
          if (u < startRadian) {
            return (
              offsetX +
              Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          if (u > endRadian) {
            return (
              offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
        },

        y: function (u, v) {
          if (u < startRadian) {
            return (
              offsetY +
              Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          if (u > endRadian) {
            return (
              offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
        },

        z: function (u, v) {
          if (u < -Math.PI * 0.5) {
            return Math.sin(u);
          }
          if (u > Math.PI * 2.5) {
            return Math.sin(u) * h * 0.1;
          }
          return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
        },
      };
    },
    getPie3D(pieData, internalDiameterRatio) {
      let series = [];
      let sumValue = 0;
      let startValue = 0;
      let endValue = 0;
      let legendData = [];
      let k =
        typeof internalDiameterRatio !== "undefined"
          ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
          : 1 / 3;

      // 为每一个饼图数据,生成一个 series-surface 配置
      for (let i = 0; i < pieData.length; i++) {
        sumValue += pieData[i].value;

        let seriesItem = {
          name:
            typeof pieData[i].name === "undefined"
              ? `series${i}`
              : pieData[i].name,
          type: "surface",
          parametric: true,
          wireframe: {
            show: false,
          },
          pieData: pieData[i],
          pieStatus: {
            selected: false,
            hovered: false,
            k: 1 / 10,
          },
        };

        if (typeof pieData[i].itemStyle != "undefined") {
          let itemStyle = {};

          typeof pieData[i].itemStyle.color != "undefined"
            ? (itemStyle.color = pieData[i].itemStyle.color)
            : null;
          typeof pieData[i].itemStyle.opacity != "undefined"
            ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
            : null;

          seriesItem.itemStyle = itemStyle;
        }
        series.push(seriesItem);
      }

      // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
      // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
      for (let i = 0; i < series.length; i++) {
        endValue = startValue + series[i].pieData.value;

        series[i].pieData.startRatio = startValue / sumValue;
        series[i].pieData.endRatio = endValue / sumValue;
        series[i].parametricEquation = this.getParametricEquation(
          series[i].pieData.startRatio,
          series[i].pieData.endRatio,
          false,
          false,
          k,
          series[i].pieData.value
        );

        startValue = endValue;

        legendData.push(series[i].name);
      }

      return series;
    },
    initChart2() {
      if (document.getElementById("echarts53")) {
        let myChart = this.$echarts.init(document.getElementById("echarts53"));
        this.$api.MMS.Mms.GetAssetClassifyChart().then((res) => {
          if (res.ok) {
            let optionsData = [
              {
                name: res.data[0].name,
                value: res.data[0].value,
                itemStyle: {
                  color: "#00E4B1",
                },
              },
              {
                name: res.data[1].name,
                value: res.data[1].value,
                itemStyle: {
                  color: "#2DC5E4",
                },
              },
              {
                name: res.data[2].name,
                value: res.data[2].value,
                itemStyle: {
                  color: "#FB9A36",
                },
              },
              {
                name: res.data[3].name,
                value: res.data[3].value,
                itemStyle: {
                  color: "#A4F1F9",
                },
              },
            ];

            // 生成扇形的曲面参数方程,用于 series-surface.parametricEquation

            // 生成模拟 3D 饼图的配置项

            let series = this.getPie3D(optionsData, 0.7);

            let option2 = {
              backgroundColor: "transparent",
              title: [
                {
                  text: `174`,
                  textStyle: {
                    fontSize: 50,
                    fontFamily: "Microsoft Yahei",
                    fontWeight: "600",
                    color: "#fff",
                  },

                  x: "19%",
                  y: "30%",
                },
                {
                  text: `资产类型`,
                  textStyle: {
                    fontSize: 30,
                    fontFamily: "Microsoft Yahei",
                    fontWeight: "500",
                    color: "#ccc",
                  },

                  x: "56%",
                  y: "2%",
                },
                {
                  text: `数量`,
                  textStyle: {
                    fontSize: 30,
                    fontFamily: "Microsoft Yahei",
                    fontWeight: "500",
                    color: "#ccc",
                  },

                  x: "74%",
                  y: "2%",
                },
                {
                  text: `占比`,
                  textStyle: {
                    fontSize: 30,
                    fontFamily: "Microsoft Yahei",
                    fontWeight: "500",
                    color: "#ccc",
                  },

                  x: "86%",
                  y: "2%",
                },
              ],
              legend: [
                {
                  show: true,
                  tooltip: {
                    show: true,
                  },
                  orient: "vertical",
                  // x: "10%",
                  backgroundColor: "rgba(0, 110, 191, 0.20)",
                  borderColor: "rgba(0, 110, 191, 1)",
                  borderWidth: 2.5,
                  data: ["安防设备"],
                  top: "15%",
                  right: "30",
                  itemGap: 20,
                  itemHeight: 18,
                  itemWidth: 18,
                  padding: [15, 10, 15, 10],
                  // right: "4%",
                  textStyle: {
                    color: "#fff",
                    fontSize: 12,

                    rich: {
                      name: {
                        width: 80,
                        fontSize: 28,
                        color: "#B0D8DF",
                        fontFamily: "Source Han Sans CN",
                      },
                      value: {
                        width: 20,
                        fontSize: 28,
                        padding: [0, 5, 0, 5],
                        color: "#fff",
                        fontFamily: "Source Han Sans CN",
                      },
                      A: {
                        fontSize: 28,
                        color: "#B0D8DF",
                        fontFamily: "Source Han Sans CN",
                      },
                      rate: {
                        width: 50,
                        fontSize: 28,
                        padding: [0, 0, 0, 10],
                        // color: "#10DD24",
                        fontFamily: "Source Han Sans CN",
                      },
                      B: {
                        fontSize: 28,
                        // color: "#B0D8DF",
                        padding: [0, 0, 0, 0],
                        fontFamily: "Source Han Sans CN",
                      },
                    },
                  },
                  formatter: function (name) {
                    let total = 0;
                    let target;
                    for (let i = 0; i < optionsData.length; i++) {
                      total += optionsData[i].value;
                      if (optionsData[i].name === name) {
                        target = optionsData[i].value;
                      }
                    }
                    let arr = [
                      "    {name|" + name + "}",
                      "{value|" + target + "}{A|}",
                      "{rate|" + ((target / total) * 100).toFixed(0) + "}{B|%}",
                    ];
                    return arr.join("              ");
                  },
                },
                {
                  show: true,
                  tooltip: {
                    show: true,
                  },
                  orient: "vertical",
                  // x: "10%",
                  backgroundColor: "rgba(0, 110, 191, 0.20)",
                  borderColor: "rgba(0, 110, 191, 1)",
                  borderWidth: 2.5,
                  data: ["消防设备"],
                  top: "35%",
                  right: "30",
                  itemGap: 20,
                  itemHeight: 18,
                  itemWidth: 18,
                  padding: [15, 10, 15, 10],
                  // right: "4%",
                  textStyle: {
                    color: "#fff",
                    fontSize: 12,

                    rich: {
                      name: {
                        width: 80,
                        fontSize: 28,
                        color: "#B0D8DF",
                        fontFamily: "Source Han Sans CN",
                      },
                      value: {
                        width: 20,
                        fontSize: 28,
                        padding: [0, 5, 0, 5],
                        color: "#fff",
                        fontFamily: "Source Han Sans CN",
                      },
                      A: {
                        fontSize: 28,
                        color: "#B0D8DF",
                        fontFamily: "Source Han Sans CN",
                      },
                      rate: {
                        width: 50,
                        fontSize: 28,
                        padding: [0, 0, 0, 10],
                        // color: "#10DD24",
                        fontFamily: "Source Han Sans CN",
                      },
                      B: {
                        fontSize: 28,
                        // color: "#B0D8DF",
                        padding: [0, 0, 0, 0],
                        fontFamily: "Source Han Sans CN",
                      },
                    },
                  },
                  formatter: function (name) {
                    let total = 0;
                    let target;
                    for (let i = 0; i < optionsData.length; i++) {
                      total += optionsData[i].value;
                      if (optionsData[i].name === name) {
                        target = optionsData[i].value;
                      }
                    }
                    let arr = [
                      "    {name|" + name + "}",
                      "{value|" + target + "}{A|}",
                      "{rate|" + ((target / total) * 100).toFixed(0) + "}{B|%}",
                    ];
                    return arr.join("              ");
                  },
                },
                {
                  show: true,
                  tooltip: {
                    show: true,
                  },
                  orient: "vertical",
                  // x: "10%",
                  backgroundColor: "rgba(0, 110, 191, 0.20)",
                  borderColor: "rgba(0, 110, 191, 1)",
                  borderWidth: 2.5,
                  data: ["能耗设备"],
                  top: "55%",
                  right: "30",
                  itemGap: 20,
                  itemHeight: 18,
                  itemWidth: 18,
                  padding: [15, 10, 15, 10],
                  // right: "4%",
                  textStyle: {
                    color: "#fff",
                    fontSize: 12,

                    rich: {
                      name: {
                        width: 80,
                        fontSize: 28,
                        color: "#B0D8DF",
                        fontFamily: "Source Han Sans CN",
                      },
                      value: {
                        width: 20,
                        fontSize: 28,
                        padding: [0, 5, 0, 5],
                        color: "#fff",
                        fontFamily: "Source Han Sans CN",
                      },
                      A: {
                        fontSize: 28,
                        color: "#B0D8DF",
                        fontFamily: "Source Han Sans CN",
                      },
                      rate: {
                        width: 50,
                        fontSize: 28,
                        padding: [0, 0, 0, 10],
                        // color: "#10DD24",
                        fontFamily: "Source Han Sans CN",
                      },
                      B: {
                        fontSize: 28,
                        // color: "#B0D8DF",
                        padding: [0, 0, 0, 0],
                        fontFamily: "Source Han Sans CN",
                      },
                    },
                  },
                  formatter: function (name) {
                    let total = 0;
                    let target;
                    for (let i = 0; i < optionsData.length; i++) {
                      total += optionsData[i].value;
                      if (optionsData[i].name === name) {
                        target = optionsData[i].value;
                      }
                    }
                    let arr = [
                      "    {name|" + name + "}",
                      "{value|" + target + "}{A|}",
                      "{rate|" + ((target / total) * 100).toFixed(0) + "}{B|%}",
                    ];
                    return arr.join("              ");
                  },
                },
                {
                  show: true,
                  tooltip: {
                    show: true,
                  },
                  orient: "vertical",
                  // x: "10%",
                  backgroundColor: "rgba(0, 110, 191, 0.20)",
                  borderColor: "rgba(0, 110, 191, 1)",
                  borderWidth: 2.5,
                  data: ["建筑设备"],
                  top: "75%",
                  right: "30",
                  itemGap: 20,
                  itemHeight: 18,
                  itemWidth: 18,
                  padding: [15, 10, 15, 10],
                  // right: "4%",
                  textStyle: {
                    color: "#fff",
                    fontSize: 12,

                    rich: {
                      name: {
                        width: 80,
                        fontSize: 28,
                        color: "#B0D8DF",
                        fontFamily: "Source Han Sans CN",
                      },
                      value: {
                        width: 20,
                        fontSize: 28,
                        padding: [0, 5, 0, 5],
                        color: "#fff",
                        fontFamily: "Source Han Sans CN",
                      },
                      A: {
                        fontSize: 28,
                        color: "#B0D8DF",
                        fontFamily: "Source Han Sans CN",
                      },
                      rate: {
                        width: 50,
                        fontSize: 28,
                        padding: [0, 0, 0, 10],
                        // color: "#10DD24",
                        fontFamily: "Source Han Sans CN",
                      },
                      B: {
                        fontSize: 28,
                        // color: "#B0D8DF",
                        padding: [0, 0, 0, 0],
                        fontFamily: "Source Han Sans CN",
                      },
                    },
                  },
                  formatter: function (name) {
                    let total = 0;
                    let target;
                    for (let i = 0; i < optionsData.length; i++) {
                      total += optionsData[i].value;
                      if (optionsData[i].name === name) {
                        target = optionsData[i].value;
                      }
                    }
                    let arr = [
                      "    {name|" + name + "}",
                      "{value|" + target + "}{A|}",
                      "{rate|" + ((target / total) * 100).toFixed(0) + "}{B|%}",
                    ];
                    return arr.join("              ");
                  },
                },
              ],
              animation: true,

              backgroundColor: "transparent",
              labelLine: {
                show: true,
                lineStyle: {
                  color: "#7BC0CB",
                },
                normal: {
                  show: true,
                  length: 10,
                  length2: 10,
                },
              },
              label: {
                show: true,
                position: "outside",
                formatter: "{b} \n{c}\n{d}%",
                textStyle: {
                  color: "rgba(176, 216, 223, 1)",
                  fontSize: 24,
                },
              },
              xAxis3D: {
                min: -1,
                max: 1,
              },
              yAxis3D: {
                min: -1,
                max: 1,
              },
              zAxis3D: {
                min: -1,
                max: 1,
              },
              grid3D: {
                show: false,
                boxHeight: 0.1,
                //top: '30%',
                left: "-24%",
                top: "-15%",
                width: "100%",
                // environment: "rgba(255,255,255,0)",
                viewControl: {
                  distance: 165,
                  alpha: 30,
                  beta: 15,
                  autoRotate:true, // 自动旋转
                  rotateSensitivity: 1,
                  zoomSensitivity: 0,
                  panSensitivity: 0,
                },
              },
              series: series,
            };

            // option2.title[0].text=''//总数
            let sum = 0;
            for (let index = 0; index < optionsData.length; index++) {
              option2.legend[index].data = [optionsData[index].name];
              sum += optionsData[index].value;
            }

             function  getHeight3D(series, height) {
            series.sort((a, b) => {  
                return (b.pieData.value - a.pieData.value);
            })
            return height * 25 / series[0].pieData.value;
        }

            option2.grid3D.boxHeight =getHeight3D(option2.series,15)

            
            option2.title[0].text = sum;
            // 准备待返回的配置项,把准备好的 legendData、series 传入。
            myChart.clear();
            myChart.setOption(option2);
            window.onresize = function () {
              myChart.resize();
            };
          }
        });
      }
    },

另外:这里的立体图各部分高度是和数值有关系的,数值越高,高度越高,要想设置为统一高度,可以在getParametricEquation方法中设置z为下列样式,可以设置所有的高度都是一致的,其中的0.1可自行设置,效果是设置统一高度为多少


z: function (u, v) {
	if (u < -Math.PI * 0.5) {
		return Math.sin(u)
	}
	if (u > Math.PI * 2.5) {
		return Math.sin(u) * 0.1
	}
	return Math.sin(v) > 0 ? 0.1 : -1
},

## 看到这里了就点赞收藏一下吧,都是一个一个字打出来的


附上一些省略的series注释和方法,以上方法足够了,想详细研究的可以看看下列代码

series: [{

type: 'map3D', // 系列类型

name: 'map3D', // 系列名称

map: 'tongren', // 地图类型。echarts-gl 中使用的地图类型同 geo 组件相同(ECharts 中提供了两种格式的地图数据,一种是可以直接 script 标签引入的 js 文件,引入后会自动注册地图名字和数据。还有一种是 JSON 文件,需要通过 AJAX 异步加载后手动注册。)



// 环境贴图,支持純颜色值,渐变色,全景贴图的 url。默认为 'auto',在配置有 light.ambientCubemap.texture 的时候会使用该纹理作为环境贴图。否则则不显示环境贴图。

environment: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ // 配置为垂直渐变的背景

offset: 0, color: '#00aaff' // 天空颜色

}, {

offset: 0.7, color: '#998866' // 地面颜色

}, {

offset: 1, color: '#998866' // 地面颜色

}], false),



label: { // 标签的相关设置

show: true, // (地图上的城市名称)是否显示标签 [ default: false ]

//distance: 50, // 标签距离图形的距离,在三维的散点图中这个距离是屏幕空间的像素值,其它图中这个距离是相对的三维距离

//formatter:, // 标签内容格式器

textStyle: { // 标签的字体样式

color: '#000', // 地图初始化区域字体颜色

fontSize: 8, // 字体大小

opacity: 1, // 字体透明度

backgroundColor: 'rgba(0,23,11,0)' // 字体背景色

},

},



itemStyle: { // 三维地理坐标系组件 中三维图形的视觉属性,包括颜色,透明度,描边等。

color: 'rgba(95,158,160,0.5)', // 地图板块的颜色

opacity: 1, // 图形的不透明度 [ default: 1 ]

borderWidth: 0.5, // (地图板块间的分隔线)图形描边的宽度。加上描边后可以更清晰的区分每个区域 [ default: 0 ]

borderColor: '#000' // 图形描边的颜色。[ default: #333 ]

},



emphasis: { // 鼠标 hover 高亮时图形和标签的样式 (当鼠标放上去时 label和itemStyle 的样式)

label: { // label高亮时的配置

show: true,

textStyle: {

color: '#fff', // 高亮时标签颜色变为 白色

fontSize: 15, // 高亮时标签字体 变大

}

},

itemStyle: { // itemStyle高亮时的配置

areaColor: '#66ffff', // 高亮时地图板块颜色改变

}

},



groundPlane: { // 地面可以让整个组件有个“摆放”的地方,从而使整个场景看起来更真实,更有模型感。

show: false, // 是否显示地面。[ default: false ]

color: '#aaa' // 地面颜色。[ default: '#aaa' ]

},



regions: [{ // 可对单个地图区域进行设置

name: '玉屏侗族自治县', // 所对应的地图区域的名称

//regionHeight: '', // 区域的高度,可以设置不同的高度用来表达数据的大小。当 GeoJSON 为建筑的数据时,也可以通过这个值表示简直的高度。

itemStyle: { // 单个区域的样式设置

color: '#00FF00',

opacity: 1,

borderWidth: 0.4,

borderColor: '#5F9EA0'

},

}, {

name: '碧江区',

itemStyle: {

color: '#EEEE00',

opacity: 1,

borderWidth: 0.4,

borderColor: '#5F9EA0'

},

}],



//shading: 'lambert', // 三维地理坐标系组件中三维图形的着色效果,echarts-gl 中支持下面三种着色方式:

// 'color' 只显示颜色,不受光照等其它因素的影响。

// 'lambert' 通过经典的 lambert 着色表现光照带来的明暗。

// 'realistic' 真实感渲染,配合 light.ambientCubemap 和 postEffect 使用可以让展示的画面效果和质感有质的提升。ECharts GL 中使用了基于物理的渲染(PBR) 来表现真实感材质。

// realisticMaterial: {} // 真实感材质相关的配置项,在 shading 为'realistic'时有效。

// lambertMaterial: {} // lambert 材质相关的配置项,在 shading 为'lambert'时有效。

// colorMaterial: {} // color 材质相关的配置项,在 shading 为'color'时有效。



light: { // 光照相关的设置。在 shading 为 'color' 的时候无效。 光照的设置会影响到组件以及组件所在坐标系上的所有图表。合理的光照设置能够让整个场景的明暗变得更丰富,更有层次。

main: { // 场景主光源的设置,在 globe 组件中就是太阳光。

color: '#fff', //主光源的颜色。[ default: #fff ]

intensity: 1.2, //主光源的强度。[ default: 1 ]

shadow: false, //主光源是否投射阴影。默认关闭。 开启阴影可以给场景带来更真实和有层次的光照效果。但是同时也会增加程序的运行开销。

//shadowQuality: 'high', // 阴影的质量。可选'low', 'medium', 'high', 'ultra' [ default: 'medium' ]

alpha: 55, // 主光源绕 x 轴,即上下旋转的角度。配合 beta 控制光源的方向。[ default: 40 ]

beta: 10 // 主光源绕 y 轴,即左右旋转的角度。[ default: 40 ]

},

ambient: { // 全局的环境光设置。

color: '#fff', // 环境光的颜色。[ default: #fff ]

intensity: 0.5 // 环境光的强度。[ default: 0.2 ]

}

},



viewControl: { // 用于鼠标的旋转,缩放等视角控制。

projection: 'perspective', // 投影方式,默认为透视投影'perspective',也支持设置为正交投影'orthographic'。

autoRotate: false, // 是否开启视角绕物体的自动旋转查看。[ default: false ]

autoRotateDirection: 'cw', // 物体自传的方向。默认是 'cw' 也就是从上往下看是顺时针方向,也可以取 'ccw',既从上往下看为逆时针方向。

autoRotateSpeed: 10, // 物体自传的速度。单位为角度 / 秒,默认为10 ,也就是36秒转一圈。

autoRotateAfterStill: 3, // 在鼠标静止操作后恢复自动旋转的时间间隔。在开启 autoRotate 后有效。[ default: 3 ]

damping: 0, // 鼠标进行旋转,缩放等操作时的迟滞因子,在大于等于 1 的时候鼠标在停止操作后,视角仍会因为一定的惯性继续运动(旋转和缩放)。[ default: 0.8 ]

rotateSensitivity: 1, // 旋转操作的灵敏度,值越大越灵敏。支持使用数组分别设置横向和纵向的旋转灵敏度。默认为1, 设置为0后无法旋转。 rotateSensitivity: [1, 0]——只能横向旋转; rotateSensitivity: [0, 1]——只能纵向旋转。

zoomSensitivity: 1, // 缩放操作的灵敏度,值越大越灵敏。默认为1,设置为0后无法缩放。

panSensitivity: 1, // 平移操作的灵敏度,值越大越灵敏。默认为1,设置为0后无法平移。支持使用数组分别设置横向和纵向的平移灵敏度

panMouseButton: 'left', // 平移操作使用的鼠标按键,支持:'left' 鼠标左键(默认);'middle' 鼠标中键 ;'right' 鼠标右键(注意:如果设置为鼠标右键则会阻止默认的右键菜单。)

rotateMouseButton: 'left', // 旋转操作使用的鼠标按键,支持:'left' 鼠标左键;'middle' 鼠标中键(默认);'right' 鼠标右键(注意:如果设置为鼠标右键则会阻止默认的右键菜单。)



distance: 200, // [ default: 100 ] 默认视角距离主体的距离,对于 grid3D 和 geo3D 等其它组件来说是距离中心原点的距离,对于 globe 来说是距离地球表面的距离。在 projection 为'perspective'的时候有效。

minDistance: 40, // [ default: 40 ] 视角通过鼠标控制能拉近到主体的最小距离。在 projection 为'perspective'的时候有效。

maxDistance: 400, // [ default: 400 ] 视角通过鼠标控制能拉远到主体的最大距离。在 projection 为'perspective'的时候有效。



alpha: 40, // 视角绕 x 轴,即上下旋转的角度。配合 beta 可以控制视角的方向。[ default: 40 ]

beta: 15, // 视角绕 y 轴,即左右旋转的角度。[ default: 0 ]

minAlpha: -360, // 上下旋转的最小 alpha 值。即视角能旋转到达最上面的角度。[ default: 5 ]

maxAlpha: 360, // 上下旋转的最大 alpha 值。即视角能旋转到达最下面的角度。[ default: 90 ]

minBeta: -360, // 左右旋转的最小 beta 值。即视角能旋转到达最左的角度。[ default: -80 ]

maxBeta: 360, // 左右旋转的最大 beta 值。即视角能旋转到达最右的角度。[ default: 80 ]



center: [0,0,0], // 视角中心点,旋转也会围绕这个中心点旋转,默认为[0,0,0]。



animation: true, // 是否开启动画。[ default: true ]

animationDurationUpdate: 1000, // 过渡动画的时长。[ default: 1000 ]

animationEasingUpdate: 'cubicInOut' // 过渡动画的缓动效果。[ default: cubicInOut ]

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2106007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c# Avalonia 架构开发跨平台应用

实现了一个计算器的应用&#xff0c;先看在不同平台的效果 windows11上 ubuntu上 统信UOS 上 麒麟 kylin v10 好了&#xff0c;先说一下问题&#xff0c;如果想一套代码在不同平台同时运行&#xff0c;里面调用的逻辑还是要分系统的&#xff0c;先分linux系统和windows系统&a…

2024年全国铁路(铁路、高铁、地铁)矢量数据集

数据更新时间​&#xff1a;2024年6月​&#xff1b; ​数据范围&#xff1a;全国各省&#xff08;不包含台湾&#xff09;; 数据格式​&#xff1a;shp; ​数据包含类型&#xff1a;铁路、高铁、地铁 数据​坐标信息&#xff1a; EPSG Code 4326 大地基准面 D_WGS_1…

CTFSHOWRCE

web3 1.打开环境&#xff0c;上面给了一句php的话&#xff0c;意思是get传参url有文件包含漏洞 2.get传参运用伪协议&#xff0c;post传参命令执行看目录。 3.上面有一个文件ctf_go_go_go,访问这个文件就有flag web4 1.打开环境&#xff0c;和上一关的一样&#xff0c;但是不…

CSS实现优惠券透明圆形镂空打孔效果等能力学习

前言&#xff1a;无他&#xff0c;仅供学习记录&#xff0c;通过一个简单的优惠券Demo实践巩固CSS知识。 本次案例主要学习或巩固一下几点&#xff1a; 实现一个简单的Modal&#xff1b;如何进行复制文本到粘贴板&#xff1b;在不使用UI的svg图片的情况下&#xff0c;如何用C…

【C++】模板特化

目录 一、非类型模板参数 二、模板的特化 &#x1f31f;概念 扩展小知识补充(1)&#xff1a; 扩展小知识补充(2)&#xff1a; &#x1f31f;函数模板特化 扩展小知识&#xff1a; &#x1f31f;类模板特化 ✨全特化 ✨偏特化 • 部分特化&#xff1a;将模板参数表中…

前端几种常见框架【第一节】

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; 最近比较忙&#xff0c;本人在复习软考中级设计考试&#xff0c;所以本系列文从零基础开始复习软考到结束软考&#xff08;计算机技术与软件专业技术资格考试&#xff09;作为国家级职业资格认证考试&#x…

ROS2 2D相机基于AprilTag实现3D空间定位最简流程

文章目录 前言驱动安装下载安装方式一&#xff1a;方式二&#xff1a; 相机检测配置config文件编译、运行程序注意 内参标定标定板运行程序 apriltag空间定位标签打印下载安装可视化结果 前言 AprilTag是一种高性能的视觉标记系统&#xff0c;广泛应用于机器人导航、增强现实和…

简述CCS平面线性光源

光源在机器视觉系统中起着重要作用&#xff0c;不同环境、场景及应用合适光源都不一样&#xff0c;今天我们来看看LFX3-PT系列平面线性光源。它是最适合检测镜面物体的凹凸,外壳小巧的光源。备有根据检测条件可选的2种线间距。1mm型&#xff08;型号末尾&#xff1a;A&#xff…

【ArcGIS Pro第一期】界面简介

ArcGIS Pro简介 ArcGIS Pro界面简介1.1 打开工程1.2 使用功能区上的工具 参考 ArcGIS Pro 是一种基于功能区的应用程序。 ArcGIS Pro 窗口顶部的功能区有许多命令可供选择&#xff0c;而根据需要打开的各个窗格&#xff08;可停靠窗口&#xff09;中则提供了更为高级或专用的功…

erlang学习:用ETS和DETS存储数据

作用 ets和dets是两个系统模块&#xff0c;可以用来高效存储海量的Erlang数据。 ETS和DETS执行的任务基本相同&#xff1a;它们提供大型的键值查询表。ETS常驻内存&#xff0c;DETS则常驻磁盘。ETS是相当高效的&#xff1a;可以用它存储海量的数据&#xff08;只要有足够的内…

ACM模式 输入输出练习

牛客-练习地址 第一题 let cnt readline(); while(cnt--){let input readline()let arr input.split( ).map(Number)console.log(arr[0]arr[1]) }第二题 let cnt readline(); while(cnt--){let input readline()let arr input.split( ).map(Number)console.log(arr[0]ar…

Web攻防之应急响应(二)

目录 前提 &#x1f354;学习Java内存马前置知识 内存马 内存马的介绍 内存马的类型众多 内存马的存在形式 Java web的基础知识&#xff1a; Java内存马的排查思路&#xff1a; &#x1f354;开始查杀之前的需要准备 1.登录主机启动服务器 2.生成jsp马并连接成功 …

vivado 创建时间约束1

步骤3&#xff1a;创建时间约束 在此步骤中&#xff0c;您打开合成的设计并使用AMD Vivado™定时约束 男巫定时约束向导分析门级网表并发现缺失 约束。使用“定时约束”向导为此设计生成约束。 1.在“流导航器”中&#xff0c;单击“打开综合设计”。 2.当综合设计打开时&#…

六、MySQL高级—架构介绍(1)

&#x1f33b;&#x1f33b; 目录 一、Mysql 简介1.1 概述1.2 Mysql 高手是怎样炼成的 二、Mysql Linux 版的安装2.1 mysql5.52.2 mysql5.7 三、Mysql 的用户与权限管理3.1 MySQL的用户管理3.2 权限管理3.3 通过工具远程访问 四、 Mysql的一些杂项配置(了解)五、 Mysql 逻辑架构…

[UVM]3.核心基类 uvm_object 域的自动化 copy() compare() print() pack unpack

1.核心基类&#xff1a;uvm_object &#xff08;1&#xff09;虚类只能声明&#xff0c;不能例化。 &#xff08;2&#xff09;uvm_object提供的方法 2.域的自动化&#xff08;field automation&#xff09; &#xff08;1&#xff09;简述 &#xff08;2&#xff09;示例 格…

JVM5-垃圾回收

自动垃圾回收 在C/C这类没有自动垃圾回收机制的语言中&#xff0c;一个对象如果不再使用&#xff0c;需要手动释放&#xff0c;否则就会出现内存泄漏&#xff0c;称这种释放对象的过程为垃圾回收&#xff0c;而需要程序员编写代码进行回收的方式为手动回收 内存泄漏指的是不再…

进一步了解CSS布局——WEB开发系列29

CSS 页面布局技术允许我们拾取网页中的元素&#xff0c;并且控制它们相对正常布局流、周边元素、父容器或者主视口/窗口的位置。 一、正常布局流&#xff08;Normal Flow&#xff09; CSS的布局基础是“正常流”&#xff0c;也就是页面元素在没有特别指定布局方式时的默认排列…

OPenCV结构分析与形状描述符(3)计算一个点集的最小外接矩形的函数boundingRect()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算一个点集的最小右上边界矩形或灰度图像中的非零像素。 该函数计算并返回指定点集或灰度图像中非零像素的最小右上边界矩形。 在OpenCV中&am…

[项目][CMP][项目介绍及知识铺垫]详细讲解

目录 1.这个项目做的是什么&#xff1f;2.此项目涉及知识面3.什么是内存池&#xff1f;1.池化技术2.内存池3.内存池主要解决的问题 4.理解malloc 1.这个项目做的是什么&#xff1f; 实现一个高并发内存池&#xff0c;参考原型为Google的一个开源项目tcmalloc(Thread-Caching M…

61、Python之函数高级:为函数添加方法,实现属性可变的装饰器

引言 今天文章的标题&#xff0c;初读起来可能有些拗口&#xff0c;什么叫“为函数添加方法”&#xff1f;但是&#xff0c;如果真正对“Python函数也是对象”这个理念有清晰的理解的话&#xff0c;其实&#xff0c;也是不难理解的&#xff0c;本质上就是给一个对象新增一个自…