用echarts实现3d饼图

这篇具有很好参考价值的文章主要介绍了用echarts实现3d饼图。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

echarts实现3d饼图,echarts,前端,javascript

安装echarts和echarts-gl

npm install echarts

npm install echarts-gl

echarts版本5.x的话需要对应echarts-gl版本2.x

echarts版本4.x的话需要对应echarts-gl版本1.x

指定版本命令 npm install echarts-gl@1.1.2

1.关键函数,生成扇形的曲面参数方程,用于 series-surface

Documentation - Apache ECharts官网series-surface介绍 Documentation - Apache ECharts

getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {

    // 计算

    const midRatio = (startRatio + endRatio) / 2;

    const startRadian = startRatio * Math.PI * 2;

    const endRadian = endRatio * Math.PI * 2;

    const midRadian = midRatio * Math.PI * 2;

    // 如果只有一个扇形,则不实现选中效果。

    if (startRatio === 0 && endRatio === 1) {

        isSelected = false;

    }

    // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)

    k = 1;

    // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)

    const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;

    const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;

    // 计算高亮效果的放大比例(未高亮,则比例为 1)

    const 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;

        },

    };

  }

2.构建饼图函数,绘制3d图。internalDiameterRatio为透明的空心占比,0就是普通饼1就镂空

getPie3D(pieData, internalDiameterRatio) {

    const series = [];

    let sumValue = 0;

    let startValue = 0;

    let endValue = 0;

    const legendData = [];

    const k =

        typeof internalDiameterRatio !== 'undefined'

            ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)

            : 1 / 3;

    // 为每一个饼图数据,生成一个 series-surface 配置

    for (let i = 0; i < pieData.length; i += 1) {

        sumValue += pieData[i].value;

        const 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: k,

            },

            itemStyle:{}

        };

        if (typeof pieData[i].itemStyle !== 'undefined') {

            const itemStyle :any= {};

            if (typeof pieData[i].itemStyle.color !== 'undefined') {

                itemStyle.color = pieData[i].itemStyle.color;

            }

            if (typeof pieData[i].itemStyle.opacity !== 'undefined') {

                itemStyle.opacity = pieData[i].itemStyle.opacity;

            }

            seriesItem.itemStyle = itemStyle;

        }

        series.push(seriesItem);

    }

    // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,

    // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。

    for (let i = 0; i < series.length; i += 1) {

        endValue = startValue + series[i].pieData.value;

        series[i].pieData.startRatio = startValue / sumValue;

        series[i].pieData.endRatio = endValue / sumValue;

        console.log(series[i].pieData.startRatio,

            series[i].pieData.endRatio,

            false,  

            false,

            k,

            series[i].pieData.value)

            series[i].parametricEquation = this.getParametricEquation(

            series[i].pieData.startRatio,

            series[i].pieData.endRatio,

            false,

            false,

            k,

            25//高度

        );

        startValue = endValue;

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

    }

    return series;

  }

3.绘制2d饼图,添加label指引线

series.push({

      name: 'pie2d',

      type: 'pie',

      label: {

          opacity: 1,

          fontSize: 14,

          lineHeight: 20,

      },

      labelLine: {

          length: 50,

          length2: 50,

      },

      startAngle: -50, //起始角度,支持范围[0, 360]。

      clockwise: false, //饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式

      radius: ['20%', '50%'],

      center: ['50%', '50%'],

      data: optionsData,

      itemStyle: {

          opacity: 0,

      },

    });

js代码:

  setPie(){
    const optionsData = [
      {      
          name: 'aa',
          value: 20,
          itemStyle: {
              color: '#38ACEC',
              // opacity: 1,
          },
      },
      {
        name: 'bb',
        value: 15,
        itemStyle: {
            color: '#6960EC',
            // opacity: 1,
        },
      },
      {
          name: 'cc',
          value: 25,
          itemStyle: {
              color: '#6CBB3C',
              // opacity: 1,
          },
      },
    ];
    const series = this.getPie3D(optionsData, 0.5,);
    series.push({
      name: 'pie2d',
      type: 'pie',
      label: {
          opacity: 1,
          fontSize: 14,
          lineHeight: 20,
      },
      labelLine: {
          length: 50,
          length2: 50,
      },
      startAngle: -50, //起始角度,支持范围[0, 360]。
      clockwise: false, //饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式
      radius: ['20%', '50%'],
      center: ['50%', '50%'],
      data: optionsData,
      itemStyle: {
          opacity: 0,
      },
    });

    this.option1 = 
    {
      legend: {
          tooltip: {
              show: true,
          },
          data: ['aa', 'bb', 'cc'],
          right: '2%',
          textStyle: {
              color: '#fff',
              fontSize: 12,
          },
      },
      tooltip: {
          formatter: (params) => {
              if (params.seriesName !== 'mouseoutSeries' && params.seriesName !== 'pie2d') {
                  let bfb = (
                      (this.option.series[params.seriesIndex].pieData.endRatio -
                          this.option.series[params.seriesIndex].pieData.startRatio) *
                      100
                  ).toFixed(2);
                  return (
                      `${params.seriesName}<br/>` +
                      `<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;"></span>` +
                      `${bfb}%`
                  );
              }
          },
      },
      title: {
          text: '3D 饼图',
          x: 'center',
          top: '5%',
          textStyle: {
              color: '#fff',
              fontSize: 22,
          },
      },
      labelLine: {
          show: true,
          lineStyle: {
              color: '#7BC0CB',
          },
      },
      label: {
          show: true,
          position: 'outside',
          formatter: '{b} \n{c} {d}%',
      },
      xAxis3D: {
          min: -1,
          max: 1,
      },
      yAxis3D: {
          min: -1,
          max: 1,
      },
      zAxis3D: {
          min: -1,
          max: 1,
      },
      grid3D: {
          show: false,
          boxHeight: 25, // 三维笛卡尔坐标系在三维场景中的高度
          viewControl: {
              alpha: 45,
              // beta: 1000,
              distance: 300, //调整视角到主体的距离,类似调整zoom
              // rotateSensitivity: 0, // 设置为0无法旋转
              zoomSensitivity: 0, // 设置为0无法缩放
              panSensitivity: 0, // 设置为0无法平移
              autoRotate: false, // 自动旋转
          },
      },
      series: series,
    };
  }
   // 生成扇形的曲面参数方程,用于 series-surface.parametricEquation
  getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
    // 计算
    const midRatio = (startRatio + endRatio) / 2;
    const startRadian = startRatio * Math.PI * 2;
    const endRadian = endRatio * Math.PI * 2;
    const midRadian = midRatio * Math.PI * 2;
    // 如果只有一个扇形,则不实现选中效果。
    if (startRatio === 0 && endRatio === 1) {
        isSelected = false;
    }
    // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
    k = 1;
    // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
    const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
    const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
    // 计算高亮效果的放大比例(未高亮,则比例为 1)
    const 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;
        },
    };
  }
  //构建饼图数据,绘制3d图  internalDiameterRatio:透明的空心占比
  getPie3D(pieData, internalDiameterRatio) {
    const series = [];
    let sumValue = 0;
    let startValue = 0;
    let endValue = 0;
    const legendData = [];
    const k =
        typeof internalDiameterRatio !== 'undefined'
            ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
            : 1 / 3;
    // 为每一个饼图数据,生成一个 series-surface 配置
    for (let i = 0; i < pieData.length; i += 1) {
        sumValue += pieData[i].value;
        const 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: k,
            },
            itemStyle:{}
        };
        if (typeof pieData[i].itemStyle !== 'undefined') {
            const itemStyle :any= {};
            if (typeof pieData[i].itemStyle.color !== 'undefined') {
                itemStyle.color = pieData[i].itemStyle.color;
            }
            if (typeof pieData[i].itemStyle.opacity !== 'undefined') {
                itemStyle.opacity = pieData[i].itemStyle.opacity;
            }
            seriesItem.itemStyle = itemStyle;
        }
        series.push(seriesItem);
    }
    // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
    // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
    for (let i = 0; i < series.length; i += 1) {
        endValue = startValue + series[i].pieData.value;
        series[i].pieData.startRatio = startValue / sumValue;
        series[i].pieData.endRatio = endValue / sumValue;
        console.log(series[i].pieData.startRatio,
            series[i].pieData.endRatio,
            false,  
            false,
            k,
            series[i].pieData.value)
            series[i].parametricEquation = this.getParametricEquation(
            series[i].pieData.startRatio,
            series[i].pieData.endRatio,
            false,
            false,
            k,
            25//高度
        );
        startValue = endValue;
        legendData.push(series[i].name);
    }
    return series;
  }

html代码:文章来源地址https://www.toymoban.com/news/detail-593030.html

<div  id="option" echarts [options]="option1"  style="width:100%;height:100%"></div>

到了这里,关于用echarts实现3d饼图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • echarts实现3D柱状图(视觉层面)和3D饼图

    原理: 立体图形从一个方向只能看到三个面,于是我们通过echarts图表实现 顶部,明面,和暗面。 效果图如下: 需要四份数据, 两个柱子的数据+X轴数据+颜色数据, 通过 setData 和 setColor 生成需要的数据,横向柱状图同理,参照代码中注释。 以下是完整案例代码: 3D饼图没

    2024年02月16日
    浏览(28)
  • vue中使用echarts与echarts-gl 实现3D饼图环形饼图

    注意:我不知道版本差异会不会有影响(可以指定版本 也可以借鉴我的) 指定版本命令 加个@后面跟版本号即可 成功之后可以在package.json中检查是否安装成功(如上图) 引入位置:我没有在main.js中全局引用,而是哪个页面用到就引入哪里 代码: 注意:我没有封装起来(你

    2024年02月03日
    浏览(29)
  • echarts3d饼图实现

    效果图: 安装echarts 在package.json文件中添加 完整代码如下(示例): HTML代码 js脚本代码  

    2024年02月16日
    浏览(31)
  • vue实现echarts3D饼图

    效果图: 1.首先安装依赖 2.mainjs中导入以及挂载 3.传入数据生成3D的配置项以及option的配置 4.指示线的配置

    2024年02月06日
    浏览(34)
  • vue 使用echarts实现3D饼图和环形图

    记录一下echarts实现3d饼图和环形图功能## 标题 实现效果 首先第一步安装echarts和echarts-gl echarts-gl安装最新版本可能会有异常,建议安装\\\"echarts-gl\\\": \\\"^1.1.2\\\"版本 第二步在vue文件中引入 第三步我这里把实现3d饼图的代码给封装一下,如下: 第四步 vue文件内使用 饼图的实现 如果对

    2024年02月12日
    浏览(38)
  • echarts-pie---------3D曲状环形饼图实现!!!

    此套代码可以直接再echarts官网中的此处运行

    2024年02月14日
    浏览(36)
  • vue3.0 使用echarts与echarts-gl 实现可旋转,可放大3D饼图

    echarts与echarts-gl 实现3D饼图 实现效果: 旋转效果 缩放效果 实现步骤 1、安装echarts npm install echarts npm install echarts-gl 2、页面定义容器 3、js中引入echarts VUE 组件完整源码:

    2024年04月26日
    浏览(26)
  • 【echarts】使用 ECharts 绘制3D饼图

    在数据可视化中,饼图是表达数据占比信息的常见方式。ECharts 作为一个强大的数据可视化库,除了标准的二维饼图,也支持更加生动的三维饼图绘制。本文将指导你如何使用 ECharts 来创建一个3D饼图,提升你的数据展示效果。 在 ECharts 中,3D 饼图主要是通过 surface 类型的图

    2024年04月27日
    浏览(19)
  • echarts的3D饼图

    1、需要安装 2、使用方法 3、案例 效果图: 需要底座背景图自取

    2024年01月21日
    浏览(38)
  • 基于echarts开发的3D饼图

    可以自动旋转,鼠标高亮选中 第一步 echarts-gl 装包 我用的是上面两个版本,最开始因为echarts-gl 和echarts 版本不对应,报错找了半天,大坑,所以一定要下载对应的版本,建议直接复制到项目中package.json文件中,然后npm i 自动装包就行了 第二步 封装成了一个插件,可以直接复制到自己项

    2024年02月11日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包