前言

之前项目中需要用到3d饼图,最开始使用的是highcharts ,但是后来发现highcharts商用收费,而且收费有点贵,最终只能放弃了。
查了一下,发现可以使用d3js 来实现,对d3不太熟悉的可以看一下下面这两篇文章:

D3JS的简单学习

D3JS常用API

如果你学过jquery 的话,你会发现上手还是非常容易的。d3基本的使用还是很容易的,但是用d3写一个3d饼图还是有亿点点难的,但是如果你能站在巨人的肩膀上,那就相对简单了。

巨人:就是 3D Dount

3D Donut 有时候会打不开,多刷新几次试试。

把源码拷贝下拉,在此基础上进行封装就简单多了

实现

效果图

使用案例

<template><div><div id="abc"></div><el-button type="primary" @click="changeData">修改</el-button></div></template><script>
import pie from './js/pie';
export default {data() {return {salesData: [{ label: 'Basic',value: 10, color: '#3366CC' },{ label: 'Plus',value: 20, color: '#DC3912' },{ label: 'Lite', value: 30,color: '#FF9900' },{ label: 'Elite',value: 40, color: '#109618' },{ label: 'Delux',value: 50, color: '#990099' }]};},mounted() {pie('#abc',700,400,this.salesData,250, 200, 150, 100, 30);},methods: {changeData() {pie('#abc',700,400,this.randomData(),250, 200, 150, 100, 30);},randomData() {return this.salesData.map(function(d) {return { label: d.label, value: 1000 * Math.random(), color: d.color };});}}
};
</script><style scoped lang="scss">
</style>

pie.js

import * as d3 from 'd3';
import { draw } from './renderUtils';/*** 生成3d饼图* @param {*} id :id唯一标识* @param {*} width :svg的宽* @param {*} height :svg的高* @param {*} data :要渲染的数据* @param {*} x :横向偏移量* @param {*} y :纵向偏移量* @param {*} rx :饼图的横向半径* @param {*} ry :饼图的纵向半径* @param {*} h :饼图的高度*/
export default function pie(id,width,height,data,x,y,rx,ry,h) {d3.select(id).selectAll('svg').remove();const svg = d3.select(id).append('svg').attr('width', width).attr('height', height);let gId = id.replaceAll('#','');svg.append('g').attr('id', gId + 'pie');draw(gId + 'pie', data,x,y,rx,ry,h);
}

renderUtils.js

import * as d3 from 'd3';export const draw = (id, // svg的id】data, // 要渲染的数据x , // 横向偏移量y , // 纵向偏移量rx , // 椭圆的x半径ry , // 椭圆的y半径h , // 饼图的高ir = 0 // 饼图的内半径
) => {// 生成饼图数据const dataset = d3.pie().sort(null).value(function(d) {return d.value;})(data);// 获取svgconst slices = d3.select(`#${id}`).append('g').attr('transform', `translate(${x},${y})`).attr('class', 'slices');// 环形内曲面slices.selectAll('.innerSlice').data(dataset).enter().append('path').attr('class', 'innerSlice').style('fill', function(d) {return d3.hsl(d.data.color).darker(0.7);}).attr('d', function(d) {return pieInner(d, rx + 0.5, ry + 0.5, h, ir);}).each(function(d) {this._current = d;});// 上层2d平面slices.selectAll('.topSlice').data(dataset).enter().append('path').attr('class', 'topSlice').style('fill', function(d) {return d.data.color;}).style('stroke', function(d) {return d.data.color;}).attr('d', function(d) {return pieTop(d, rx, ry, ir);}).each(function(d) {this._current = d;});// 侧面曲面slices.selectAll('.outerSlice').data(dataset).enter().append('path').attr('class', 'outerSlice').style('fill', function(d) {return d3.hsl(d.data.color).darker(0.7);}).attr('d', function(d) {return pieOuter(d, rx - 0.5, ry - 0.5, h);}).each(function(d) {this._current = d;});// 线条slices.selectAll('lines').data(dataset).enter().append('line').attr('stroke',d => d.data.color).attr('x1',0).attr('y1', 0).attr('x2', function(d) {return 1.5 * rx * Math.cos(0.5 * (d.startAngle + d.endAngle));}).attr('y2', function(d) {return 1.5 * ry * Math.sin(0.5 * (d.startAngle + d.endAngle));});// 文本slices.selectAll('desc').data(dataset).enter().append('text').attr('font-weight',900).attr('fill','#ffffff').attr('stroke','#000000').attr('stroke-width','0.5px').attr('transform',d => {let x = 1.6 * rx * Math.cos(0.5 * (d.startAngle + d.endAngle));let y = 1.6 * ry * Math.sin(0.5 * (d.startAngle + d.endAngle));return 'translate(' + x + ',' + y + ')';}).attr('font-size','12px').attr('text-anchor','middle').text(d => d.data.label);
};// 生成内曲面
function pieInner(d, rx, ry, h, ir) {const startAngle = d.startAngle < Math.PI ? Math.PI : d.startAngle;const endAngle = d.endAngle < Math.PI ? Math.PI : d.endAngle;const sx = ir * rx * Math.cos(startAngle);const sy = ir * ry * Math.sin(startAngle);const ex = ir * rx * Math.cos(endAngle);const ey = ir * ry * Math.sin(endAngle);const ret = [];ret.push('M',sx,sy,'A',ir * rx,ir * ry,'0 0 1',ex,ey,'L',ex,h + ey,'A',ir * rx,ir * ry,'0 0 0',sx,h + sy,'z');return ret.join(' ');
}// 生成饼图的顶部
function pieTop(d, rx, ry, ir) {if (d.endAngle - d.startAngle === 0) { return 'M 0 0'; }const sx = rx * Math.cos(d.startAngle);const sy = ry * Math.sin(d.startAngle);const ex = rx * Math.cos(d.endAngle);const ey = ry * Math.sin(d.endAngle);const ret = [];ret.push('M',sx,sy,'A',rx,ry,'0',d.endAngle - d.startAngle > Math.PI ? 1 : 0,'1',ex,ey,'L',ir * ex,ir * ey);ret.push('A',ir * rx,ir * ry,'0',d.endAngle - d.startAngle > Math.PI ? 1 : 0,'0',ir * sx,ir * sy,'z');return ret.join(' ');
}// 外曲面算法
function pieOuter(d, rx, ry, h) {const startAngle = d.startAngle > Math.PI ? Math.PI : d.startAngle;const endAngle = d.endAngle > Math.PI ? Math.PI : d.endAngle;const sx = rx * Math.cos(startAngle);const sy = ry * Math.sin(startAngle);const ex = rx * Math.cos(endAngle);const ey = ry * Math.sin(endAngle);const ret = [];ret.push('M',sx,h + sy,'A',rx,ry,'0 0 1',ex,h + ey,'L',ex,ey,'A',rx,ry,'0 0 0',sx,sy,'z');return ret.join(' ');
}// 计算扇形所占百分比
function getPercent(d) {return d.endAngle - d.startAngle > 0.2? `${Math.round((1000 * (d.endAngle - d.startAngle)) / (Math.PI * 2)) / 10}%`: '';
}

vue加d3js实现3d饼图相关推荐

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

    记录一下echarts实现3d饼图和环形图功能## 标题 实现效果 首先第一步安装echarts和echarts-gl npm install echarts echarts-gl安装最新版本可能会有 ...

  2. 3d饼图 vue_在Vue中如何使用highCharts绘制3d饼图

    本篇文章主要介绍了在Vue中使用highCharts绘制3d饼图的方法,现在分享给大家,也给大家做个参考. highcharts是国外知名基于javascript的图表库.由于中文官网的vue中使用h ...

  3. eacharts和eacharts-gl、3d饼图、3d柱状图加折线图、下载gl报错解决

    eacharts-gl下载时版本一定要和eacharts版本对应.否则不出效果!!目前已知可以生效有: 第一种1: npm install echarts@5.1.2 --save npm insta ...

  4. 3d饼图 vue_在Vue中使用highCharts绘制3d饼图

    highcharts是国外知名基于javascript的图表库.由于中文官网的vue中使用highcharts配置繁琐并且需要引入jquery作为依赖,所以弃用. 接下来,给各位伙伴简要的讲叙下hig ...

  5. 3d饼图 vue_3D 饼图在 VUE 中的实现

    最近有多位读者反应,3D 饼图在 VUE 环境里跑不通.可我其实是一个先学 ECharts 后学 Javascript 的前端外行,再加上读者往往也没有告诉我具体的报错信息是什么,所以一时也没能帮读者 ...

  6. android自定义3d饼图,Android使用j4lChartAndroid插件绘制3D饼图

    图表是常见的直观表示数据的途径,目前在android手机上绘制图表基本有两种方法:一是利用java的canvas自己绘制,这种方法自己可操作性强,可以随心所欲地绘制,但是缺点就是工作量大:二是利用第三 ...

  7. vue3+heightchart实现3D饼图,echarts3D饼图,3D饼图引导线实现

    附上 heightcharts 官网地址 Highcharts 演示 | Highchartshttps://www.hcharts.cn/demo/highcharts 首先需要下载一下 heigh ...

  8. echarts 3d饼图

    echarts 3d饼图 效果图: 第一步: 在main.js引入echarts import * as echarts from 'echarts' Vue.prototype.$echarts = ...

  9. vue使用echart 完成3d系列2之曲面锥形

    vue使用echart 完成3d系列1之曲面空心圆 vue使用echart 完成3d系列3之曲面空心半圆 效果图 第一步,先安装依赖 npm install echarts-gl -S npm ins ...

  10. 在线作图丨如何绘制精美的3D饼图

    ​Question 1:什么是饼图? 饼图(pie chart)是常用的基本统计图形之一,可以直观地展示整体与个体之间的比较情况.在生信分析中,饼图常用于展示各元素数值相对于总数的占比情况,图中每个扇 ...

最新文章

  1. 根据功率计算用电量和电费
  2. C#3.0 为我们带来什么(5) —— 匿名类型
  3. 生活中处处有joke!!
  4. 每周一起读 × 招募 | ACL 2019:基于知识增强的语言表示模型
  5. boost::mpl::string相关的测试程序
  6. 关于使用jquery修改hover伪标签的样式
  7. 超大气APP下载页双语多国语言网站源码
  8. 【Elasticsearch】使用 Elasticsearch Painless 脚本以递归方式遍历 JSON 字段
  9. SU命令的功能及基本用法--psmerge
  10. Attribute in C#
  11. Solr 05 - Solr Web管理界面的基本使用
  12. MySQL安装详细图解
  13. dlan android手机,电脑与手机远程互通八款DLNA安卓手机推荐
  14. Mac OS - 让Myeclipse10支持Retina显示屏
  15. rocketdock 打不开 有进程
  16. react 中使用 marked + highlight.js 使语法高亮
  17. emui 4.1 基于android 6.0,【荣耀V8评测】基于Android 6.0的EMUI 4.1_荣耀 V8_手机评测-中关村在线...
  18. 亚马逊FBA箱子贴标有哪些要求
  19. 跟小博老师一起学习数据库 ——索引
  20. 牛客网 A-吐泡泡 栈的模拟

热门文章

  1. 教你快速搭建个人网站
  2. Office 2010如何打开MDI文件
  3. c语言max函数是什么,什么是C语言函数
  4. 【运维心得】只有百度能打开,其他页面打不开怎么办?
  5. html5考试简答题
  6. Lisp自动画梯形_CAD lisp 求助一段代码实现自动画弧!
  7. linux下dbf是什么文件,dbf是什么文件?dbf文件怎么读取
  8. 2021考研英语大作文笔记(刘晓燕版)
  9. 《Spring Cloud Netflix》--服务注册和服务发现-Eureka的深入了解
  10. 聊聊Netflix的技术创新