vue中用echarts实现复合饼图,带关系连接线

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

1.拿到产品原型图,需求中有这样一个图表

两个饼图合并包含关系,echarts,vue.js,前端,Powered by 金山文档

2.翻看echart的饼图示例,没有这种复合饼图,只有一个嵌套饼图

两个饼图合并包含关系,echarts,vue.js,前端,Powered by 金山文档

3. 于是网上查网友的文章,查到两篇类似的贴子,(52条消息) echarts模仿excel复合饼图(饼-饼)_相忘于江湖426543的博客-CSDN博客_echarts复核饼图 和 (52条消息) echarts实现复合饼图_JustMo_的博客-CSDN博客_echarts 复合饼图 其中一篇是react的,个别地方我看不太懂, 总之结合这两篇文章大概实现了这个需求

4. 首先是copy示例中的全部代码,在页面上先把这个嵌套的饼图搞出来

5. 移动中间的饼到右边,调整好两个饼的位置关系,这一步是通过media实现

在option中增加media属性,如图,内容见代码段

两个饼图合并包含关系,echarts,vue.js,前端,Powered by 金山文档
media: [
          {
            query: { minAspectRatio: 1 },
            option: {
              series: [{ center: ["70%", "50%"] }, { center: ["30%", "50%"] }],
            },
          },
        ],

然后修改第一个饼的半径 radius,使它成为一个实心的饼

两个饼图合并包含关系,echarts,vue.js,前端,Powered by 金山文档

调整第一个饼的旋转角度 startAngle,让它的较小的一个角朝正右方,这样方便后面画两条连接线

计算方式:这一角的数据占总数的比例去乘以360再除以2

原理:一个饼图渲染的时候默认是从90°开始的,x轴正向是0°,y轴正向是90°,依此类推一圈回来是360°。

startAngle() {
      let sum = 0;
      this.dataArr.forEach((element) => {
        sum += element.value;
      });
      return 360 * (this.dataArr[0].value / sum) * 0.5;
    },

效果:

两个饼图合并包含关系,echarts,vue.js,前端,Powered by 金山文档

最后就剩下两条线了。画线用markLine属性,两点确定一条直线,所以要找到两条线的分卸的起点坐标和终点坐标,终点的话这里就好说了,直接找到右边小饼的上下两个点就ok了,重点是两个起点坐标。

这里选择的办法是:先找到圆心坐标 和半径长度,再利用数学公式cos 算出它的x坐标值。我这里的圆心横坐标是450,半径长是200

两个饼图合并包含关系,echarts,vue.js,前端,Powered by 金山文档
两个饼图合并包含关系,echarts,vue.js,前端,Powered by 金山文档
 let x1 = x0 + (height / 4) * Math.cos((this.startAngle * 3.14) / 180);
      let y1 =
        height * 0.5 - (height / 4) * Math.sin((this.startAngle * 3.14) / 180);
 x2 = x1;
      y2 =
        height * 0.5 + (height / 4) * Math.sin((this.startAngle * 3.14) / 180);

全部代码:

<template>
  <div id="main" style="width: 1500px; height: 800px"></div>
</template>

<script>
import * as echarts from "echarts";
export default {
  data() {
    return {
      chartDom: null,
      myChart: null,
      chartView: null,
      dataArr: [
        { value: 220, name: "Baidu" },
        { value: 500, name: "Direct" },
      ],
    };
  },
  computed: {
    startAngle() {
      let sum = 0;
      this.dataArr.forEach((element) => {
        sum += element.value;
      });
      return 360 * (this.dataArr[0].value / sum) * 0.5;
    },
    option() {
      if (this.chartView) {
        console.log("222");
        // changePos = true;
        let tmp = this.chartView[1]._data._itemLayouts[0];
        // let tmp = this.chartView; //[1]._data._itemLayouts[0];
        pos.startTop = {
          x: tmp.cx + Math.cos(tmp.startAngle) * tmp.r,
          y: tmp.cy + Math.sin(tmp.startAngle) * tmp.r,
        };
        pos.startBootom = {
          x: tmp.cx + Math.cos(tmp.endAngle) * tmp.r,
          y: tmp.cy + Math.sin(tmp.endAngle) * tmp.r,
        };
      }

      return {
        tooltip: {
          trigger: "item",
          formatter: "{a} <br/>{b}: {c} ({d}%)",
        },
        legend: {
          data: [
            "Direct",
            "Marketing",
            "Search Engine",
            "Email",
            "Union Ads",
            "Video Ads",
            "Baidu",
            "Google",
            "Bing",
            "Others",
          ],
        },
        series: [
          {
            name: "Access From",
            type: "pie",
            // selectedMode: "single",
            radius: [0, "30%"],
            label: {
              position: "inner",
              fontSize: 14,
            },
            labelLine: {
              show: false,
            },
            data: [
              { value: 1548, name: "Search Engine" },
              { value: 775, name: "Direct" },
              { value: 679, name: "Marketing", selected: true },
            ],
          },
          {
            name: "Access From",
            type: "pie",
            radius: [0, "50%"],
            labelLine: {
              length: 30,
            },
            label: {
              formatter: "{a|{a}}{abg|}\n{hr|}\n  {b|{b}:}{c}  {per|{d}%}  ",
              backgroundColor: "#F6F8FC",
              borderColor: "#8C8D8E",
              borderWidth: 1,
              borderRadius: 4,
              rich: {
                a: {
                  color: "#6E7079",
                  lineHeight: 22,
                  align: "center",
                },
                hr: {
                  borderColor: "#8C8D8E",
                  width: "100%",
                  borderWidth: 1,
                  height: 0,
                },
                b: {
                  color: "#4C5058",
                  fontSize: 14,
                  fontWeight: "bold",
                  lineHeight: 33,
                },
                per: {
                  color: "#fff",
                  backgroundColor: "#4C5058",
                  padding: [3, 4],
                  borderRadius: 4,
                },
              },
            },
            data: this.dataArr,
            startAngle: this.startAngle,
            markLine: {
              silent: true,
              symbol: "none",
              data: this.getMarkLineData(),
            },
          },
        ],
        media: [
          {
            query: { minAspectRatio: 1 },
            option: {
              series: [{ center: ["70%", "50%"] }, { center: ["30%", "50%"] }],
            },
          },
        ],
      };
    },
  },
  mounted() {
    this.chartDom = document.getElementById("main");
    this.myChart = echarts.init(this.chartDom);

    this.myChart.setOption(this.option);
    console.log("mychart", this.myChart);
  },
  methods: {
    getMarkLineData(percent) {
      // 1.获取画布 width,height
      let height = this.myChart.getHeight();
      let width = this.myChart.getWidth();
      console.log("width", width, "height", height);

      // 2.  根据 series[0].center 获取圆心坐标
      let x0 = 450; // 圆心x轴坐标
      let x1 = x0 + (height / 4) * Math.cos((this.startAngle * 3.14) / 180);
      let y1 =
        height * 0.5 - (height / 4) * Math.sin((this.startAngle * 3.14) / 180);
      x2 = x1;
      y2 =
        height * 0.5 + (height / 4) * Math.sin((this.startAngle * 3.14) / 180);
      let result = [
        [
          {
            x: x1,
            y: y1,
          },
          {
            x: "70%",
            y: "35%",
          },
        ],
        [
          {
            x: x1,
            y: y2,
          },
          {
            x: "70%",
            y: 521,
          },
        ],
      ];
      return result;
    },
  },
};
</script>

最终效果图文章来源地址https://www.toymoban.com/news/detail-686247.html

两个饼图合并包含关系,echarts,vue.js,前端,Powered by 金山文档

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

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

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

相关文章

  • vue 使用echarts实现3D饼图和环形图

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

    2024年02月12日
    浏览(54)
  • 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日
    浏览(39)
  • 本地连接线上服务器数据库(基于MobaXterm实现)

     本地无法直接连接线上服务器,需要由ssh隧道代理实现,用xshell、MobaXterm等工具皆可实现。由于习惯使用MobaXterm,本文以此工具为演示。 线上测试服务器一台、本地电脑安装MobaXterm、navicat、(pycharm--数据库自动化使用) 打开mobaXterm,进入Tunneling 点击【New SSH tunnel】,新建

    2024年02月08日
    浏览(67)
  • Vue2 Echarts 3D饼图

    2024年01月19日
    浏览(42)
  • vue3使用 echarts - 饼图、折线图

    饼图 - 带中心图形 - graphic - elements 折线图 - 图表标记 markPoint

    2024年02月08日
    浏览(38)
  • vue-echarts饼图/柱状图点击事件

    在实际的项目开发中,我们通常会用到Echarts来对数据进行展示,有时候需要用到Echarts的点击事件,增加系统的交互性,一般是点击Echarts图像的具体项来跳转路由并携带参数,当然也可以根据具体需求来做其他的业务逻辑。下面就Echarts图表的点击事件进行实现,文章省略了

    2024年02月06日
    浏览(47)
  • 用echarts在vue2中实现3d饼图

    先看效果,再看文章: 3d的图不仅用到echarts,还用到了echarts-gl,因此都需要安装一下哦~ 直接复制粘贴吧,省事 1、修改3d饼图大小,在大概244行的位置,grid3D的对象里面,修改distance属性,即可调整 值越小,图越大    2、修改3d饼图视角高度,在大概161行的位置,修改函数

    2024年02月07日
    浏览(40)
  • 动态渲染 echarts 饼图(vue 2 + axios + Springboot)

    因为上文中提到的需求就是在 vue2 里面绘制echarts,所以,这里就搭建一个 vue2 的脚手架了。 想要深入了解 echarts 属性,请到此篇文章: 如何用echarts画一个好看的饼图 至于如何在 vue2 中使用 echarts,请见这篇文章:https://blog.csdn.net/m0_54355172/article/details/131960527 先搭建一个 v

    2024年02月09日
    浏览(35)
  • vue2之echarts的封装 折线图,饼图,大图

    chartPan.vue 使用 chartPan.vue 之饼图 效果 使用 chartPan.vue 之折线图 效果 展开大图 handlePreViewChart 事件 大图组件 maxChart.vue 大图效果

    2024年02月01日
    浏览(39)
  • 用echarts实现3d饼图

    安装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介绍 

    2024年02月16日
    浏览(28)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包