如何使用 D3.js 制作六边环形图
本文适合对 D3 API 稍有熟悉的人阅读,如果你是的话,继续看下去吧~
附 D3API 文档地址
对设计图的思考
先看我们要实现的设计图:
这个环形图适合多个共同展示, 高亮的环形表达的意义是,当前数据在总数的占比。so 实现这个图需要两个数据,一个是 当前数据num
,一个是总数sum
。
数据明确了,再看设计部分:
经过和设计师的沟通讨论,得出以下几点:
- 该组件背景为 0.1 透明度的黑色;
- 该组件六边环形未被填充的地方为镂空透明;
- 该组件环形填充的部分并不是直角截断,而是一个扇形截断:
所以最终组件应该实现为下面这个样子,这个也是我们做出的最终效果:
那么我们开始实现吧!
具体思路
这个环形图只要实现难点在于环形高亮的绘制,我想了两个方案,
给扇形应用环形蒙版
- 绘制一个高亮扇形
- 绘制一个环形蒙版(这里我用 ppt 画的,只有这种横着的六边形,将就下哈哈哈)
- 将蒙版应用在扇形上即可
但是这个方案有一些问题
,因为绘制扇形的时候需要用 translate 修改它的位置(因为默认圆心是从左上角的顶点),导致将环形蒙版应用到扇形上时,也被 translate 了,位置对不齐。。
所以采用了第二个方案:
给环形应用扇形蒙版,亲测可行~
实现步骤
新建一个 svg,这里模拟了数据 num 和 sum
// 数据var num = 2546;var sum = 2800;
// 新建 svgvar width = 100;var height = 64;var svg = d3.select('body').append('svg').attr('width', width).attr('height', height);
定义两个渐变颜色供之后使用:环形的渐变,字体的渐变
//设置线性渐变颜色renderLinearColor = (props) => {const { defs } = this;const {hexagonColor, textColor} = props;// 六边形渐变颜色let linearGradient1 = defs.append("linearGradient").attr("id","linearColor1").attr("x1","0%").attr("y1","0%").attr("x2","50%").attr("y2","100%");linearGradient1.append("stop").attr("offset","0%").style("stop-color", hexagonColor[0]).style('stop-opacity', 0.4);linearGradient1.append("stop").attr("offset","100%").style("stop-color", hexagonColor[1]);// 文字渐变颜色let linearGradient2 = defs.append("linearGradient").attr("id","linearColor2").attr("x1","0%").attr("y1","0%").attr("x2","0%").attr("y2","100%");linearGradient2.append("stop").attr("offset","0%").style("stop-color", textColor[0]);linearGradient2.append("stop").attr("offset","100%").style("stop-color", textColor[1]);}
设置扇形蒙版以便一会画六边环形的时候应用在环形上
// 扇形var arc = d3.arc()let arcDataSet = {innerRadius: 0,outerRadius: width/2,startAngle: 0,endAngle: - Math.PI * 2 * num / sum};// 扇形蒙版var mask = defs.append('mask').attr("id","mask1");// 遮住的部分mask.append('rect').attr('width', width).attr('height', height).attr('fill', 'black');// 露出的部分mask.append('path').attr('d', arc(arcDataSet)).attr('transform', function(d, i) {return `translate(${width/2},${height/2})`}).attr('fill', 'white');
绘制六边环形,并应用扇形蒙版
// 六边形var hexagonPoint = [[width/2, height*0.1],[width*0.85, height*0.28125],[width*0.85, height*0.71875],[width/2, height*0.9], [width*0.15, height*0.71875], [width*0.15, height*0.28125]];var linePath = d3.line();linePath.curve(d3.curveLinearClosed);svg.append('path').attr('d', linePath(hexagonPoint)).attr('stroke', 'url(#linearColor1)').attr('stroke-width', function(d,i) { return 0.05 * width + 'px' }).style("fill",'none').style("mask",'url(#mask1)');
至此,环形绘制好啦,但是还有一个半透明背景,且环形部分是透明的,所以这里还需要一个环形蒙版,应用在半透明背景上。
设置六边环形蒙版
// 六边形蒙版var mask = defs.append('mask').attr("id","mask2");// 露出的部分mask.append('rect').attr('width', width).attr('height', height).attr('fill', 'white');// 遮住的部分mask.append('path').attr('d', linePath(hexagonPoint)).attr('stroke', 'black').attr('stroke-width', function(d,i) { return 0.05 * width + 'px' }).style("fill",'none')
绘制半透明背景,应用六边环形蒙版
svg.append('rect').attr('id', 'rect').attr('width', width).attr('height', height).attr('fill', 'rgba(0,0,0,0.16)').style("mask",'url(#mask2)');
绘制文字
// 文字let text = svg.append('text').text(num).attr('x', '50%').attr('y', '50%').attr('text-anchor', 'middle').attr('dominant-baseline', 'central').attr('fill', 'url(#linearColor2)').style('font-size', `${width * 0.26}px`).style('font-family', 'CityDMed').style('font-weight', 'bold');
撒花完结!✿✿ヽ(°▽°)ノ✿!
后记: 这是我学习使用 D3 绘制的第一个自定义图形,如果大家还有更好的实现方法可以和我多多讨论~ 还有我一直在想,为啥网上 D3 的教程这么少捏?
以前因为不喜欢数学不敢接触可视化,后来到了真正上手,才发现是这么有趣!很喜欢这种视觉方面的东西,就像我很喜欢画画一样吧~
希望以后自己可以努力学习,提升自己,不要拖延,要自律!
ps:之前有个小伙伴,私信我问我为啥断更了如何使用 D3.js 制作六边环形图相关推荐
- D3.js 制作中国地图 .net 公共基础类
D3.js 制作中国地图 from: http://d3.decembercafe.org/pages/map/index.html GeoJSON is a format for encoding ...
- 深入理解 D3.js 可视化库之力导向图原理与实现
大厂技术 坚持周更 精选好文 简介 D3.js[1] 是一个基于 web 标准的 JS 可视化库,它借助 SVG.Canvas 和 HTML 进行数据可视化.在数据可视化中,我们很多时候会使用图来 ...
- chart.js使用学习——饼图/环形图
饼图/环形图能够展示数据集中各项的大小与各项总和的比例.chart.js中创建饼图/环形图,只需在chart构造函数中指定图表类型为pie/doughnut即可. 基本用法 创建饼图/环形图主 ...
- d3.js 制作简单的贪吃蛇
d3.js是一个不错的可视化框架,同时对于操作dom也是十分方便的.今天我们使用d3.js配合es6的类来制作一个童年小游戏–贪吃蛇.话不多说先上图片. 1. js snaker类 class Sna ...
- d3.js 制作简单的俄罗斯方块
d3.js是一个不错的可视化框架,同时对于操作dom也是十分方便的.今天我们使用d3.js配合es6的类来制作一个童年小游戏--俄罗斯方块.话不多说先上图片. 1. js tetris类 由于方法拆分 ...
- html树图制作,d3.js制作树结构图
一.运行效果 说明:使用鼠标滚轮放大缩小,点解节点可以收缩打开子节点,按住鼠标左键拖动可移动整体图形. 二.实现过程 1.编写html和css结构 .node { ursor: pointer; } ...
- d3.js 教程 模仿echarts折线图
今天我们来仿echarts折线图,这个图在echarts是折线图堆叠,但是我用d3改造成了普通的折线图,只为了大家学习(其实在简单的写一个布局就可以).废话不多说商行代码. 1 制作 Line 类 c ...
- 利用D3.js快速绘制力导向图
碎碎念: 最近课题需要基于图论和力导向图可视化每个脑电通道之间的连接性,MATLAB画的效果差强人意,于是上网搜寻到JavaScript 的一个函数库--D3.js,想快速得到数据的可视化结果 简介D ...
- 使用 D3.js 创建柱状堆积图
柱状堆积图 项目地址 使用 D3.js 创建的图表: 使用 D3.js 创建根据值域颜色渐变的地图 D3.js 中动态计算 x 轴 y 轴的宽度以及偏移量 在 Ember.js 项目中由浅入深使用 D ...
最新文章
- [BZOJ5292][BJOI2018]治疗之雨(概率DP+高斯消元)
- node学习笔记_01 环境搭建
- 华为电话面试题java_华为java面试题(含电话面试)
- java英语介绍_java,英文介绍项目.doc
- 真正理解 git fetch, git pull 以及 FETCH_HEAD
- Nmap的高级扫描(脚本)
- 设计灵感|总有一款对话界面符合你的应用风格!
- ios13.5正式版信号怎样?
- 《WinForm开发系列之控件篇》Item31 MenuStrip(暂无)
- 【唐宇迪 深度学习-3D点云实战系列】学习笔记
- 计算机二级用的ms什么版本,计算机二级ms office用的哪个版本
- VUE中隐藏和限制DIV或其他HTML元素
- oracle 中dummy,layout设计中dummy的作用详解(上图。好贴好贴,讲的很仔细)
- Wireshark菜单栏介绍
- 重磅!罗振宇跨年演讲:扎心5问
- 下一代数据架构Data Fabric到底是什么?
- CSS中flex的用法( 学习笔记 )
- 阿里云短信功能网址链接
- 网站商务BD(Bussiness Development--商务拓展)
- 既有内网又有外网的网络如何设置路由器模式
热门文章
- 51.深度解密五十一:如何精准选择网络创业项目和营销推广平台
- 如何用python制作五角星
- 优酷、腾讯视频播放器插件
- iphone释放空间_如何通过卸载未使用的应用程序来释放iPhone或iPad上的空间
- 苹果8p电池多少毫安的_18650锂电池容量最大多少毫安
- iphone计算机快捷键,PC 上的 iTunes 键盘快捷键
- 详解MySQL索引失效的几种情况
- 面试题:兔子搬运萝卜
- 佳能Canon相机SDK-C#版本64位
- ExcelToDatabase:批量导入Excel文件到MySQL/Oracle/SQL Server数据库的自动化工具