热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

D3js快速入门——用最新版D3js实现树图

文章目录:引言1.D3js是什么2.D3js相对其他数据可视化方案的优势2.1SVG对比Canvas2.2D3.js对比Echarts3.怎么用D3.js开发一个树图


文章目录:

      • 引言
      • 1. D3js 是什么
      • 2. D3js 相对其他数据可视化方案的优势
        • 2.1 SVG 对比 Canvas
        • 2.2 D3.js 对比 Echarts
      • 3. 怎么用 D3.js 开发一个树图
        • 3.1 前置基础
        • 3.2 d3开发树图流程
        • 3.3 动手实现一个树图
          • 3.3.1 普通tide tree
          • 3.3.2 你的树图不简单—— radio tide tree
          • 3.3.3 更多可能——更多类型的树图


引言

上周我们组新开项目,技术调研之后决定使用 d3.js 做数据可视化开发,mentor让我来做初期技术调研,之后的技术交流会与大家分享。可是初期的调研着实碰壁了 网上一些demo用的版本过低,包括d3js官网的demo也是如此,一些重要的API已废弃。
在这里插入图片描述

可是我们项目不打算用过低版本,于是我结合网上demo和d3文档,各种谷歌百度,总算是用最新版本实现了一些demo。想到好久没有记录学习到的技术了,趁此机会写下这篇 d3.js可视化开发快速入门博客,与大家交流分享。


1. D3js 是什么

近年来,数据可视化越来越流行,许多拥有大量数据的大型网站都开始使用可视化技术,使得大量杂乱的数据规则起来,易于理解,真可谓“一图胜千言”,毫不夸张。正是在这种趋势的催动下,各种数据化工具如井喷式的发展,而D3,Echarts正是其中的佼佼者。

D3 的全称是(Data-DrivenDocuments),顾名思义是一个被数据驱动的文档。其实是对数据进行可视化的Javascript库。D3将强大的可视化和交互技术与数据驱动的DOM操作方法相结合,能最大限度地使用现代浏览器的性能同时为设计可视化界面保留了最大的自由度。D3强调Web标准,所以无需将自己与专有框架联系起来。

D3js 是一个可以基于数据来操作文档的 Javascript 库。可以帮助你使用 HTML, CSS, SVG 以及 Canvas 来展示数据。D3 遵循现有的 Web 标准,可以不需要其他任何框架独立运行在现代浏览器中,它结合强大的可视化组件来驱动 DOM 操作。

D3 可以将数据绑定到 DOM 上,然后根据数据来计算对应 DOM 的属性值。例如你可以根据一组数据生成一个表格。或者也可以生成一个可以过渡和交互的 SVG 图形。

D3 不是一个框架,因此也没有操作上的限制。没有框架的限制带来的好处就是你可以完全按照自己的意愿来表达数据,而不是受限于条条框框,非常灵活。D3 的运行速度很快,支持大数据集和动态交互以及动画。


2. D3js 相对其他数据可视化方案的优势

对比D3和ECharts之前,先对比下两种浏览器图形渲染技术Canvas和SVG的主要区别,基本上所有的浏览器可视化第三方库都是基于这两种浏览器图形渲染技术实现的:


2.1 SVG 对比 Canvas


SVGCanvas
矢量图不依赖分辨率,放大不失真位图依赖分辨率
基于XML支持DOM事件处理器,SVG中每个图形节点都是单独的DOM节点可以附加js事件不支持事件处理器 如果要为细粒度的元素添加事件,就需要边缘检测算法,无疑增加了难度而且不一定能保证十分精确
适合带有大型渲染区域的应用(比如:地图(每个节点区域都比较大,节点不是很多))最适合图像密集型的应用比如游戏 能够方便的保存结果图像
复杂度高会减慢渲染速度(任何过度使用DOM的应用都快不了)一旦图形绘制完成,就不会再得到浏览器的关注 如果位置或者大小变化整个区域都要重新绘制
可以使用CSS 文本渲染能力较强文本渲染能力较弱

简单对比后,可以得出结论:
SVG比较适合 数据量不是很大,应用存在大量的用户交互场景。

Canvas比较适合事件交与较少,文本较少,或者数据量大画面刷新快的场景。


2.2 D3.js 对比 Echarts


EChartsD3
Canvas为主4.0+也支持SVGSVG为主4.0+也支持Canvas
提供很多图表通过简单配置可以满足大部分需求不能通过简单配置实现大部分图表
基本不可定制自由度很大,基本可以自己绘制任何图表
提供完善中文文档,示例功能完善提供完善英文文档,3.x版本中文文档比较完善,之后翻译的不完善,部分翻译可能需求查看英文方便理解,大部分示例需要完善才能使用,主要是参考价值
开发效率高,通过快速配置即可完成大部分图表需要开发
大数据量性能较好需要实现时手动优化 例如virtual DOM
提供基于WebGl的GL版实现3D图表借助其他库来实现例如:three.js、glMatrix、Sylvester

总结
ECharts等提供的图表的确可以满足大部分的需求,遵循了数据可视化的一些经典范式,一切皆可配置。然而,每个不同的行业对于数据可视化都会有一些定制化的需求,希望能以一些带有行业特征的图表向使用者展示数据背后隐藏的秘密,但是ECharts这类图形库基本不可定制,而D3自由度度很大,基本可以自己绘制任何想要的图形,这类情况的需求可以使用D3进行二次开发,定制适合的图表,但是开发成本会稍高。因此,开发中要根据实际情况来判断。无论采用哪种方式开发都要做好二次封装,把实现的图表成可复用的组件。

ECharts,hightchart这类可视化库,经过配置即可完成图表的绘制,D3要稍微麻烦一点。

使用D3绘图需要


  • 熟悉SVG(canvas)作图、熟悉CSS
  • 熟悉D3的API
  • 学习D3.js的编程风格

总结:D3和ECharts,hightchart这类可视化库相比属于可视化中较为基础的工具库,需要一定的可视化方面的基础才能比较快速开发出较复杂的图表,可以先尝试实现简单的图形,官网首页上面就大部分酷炫的在线Demo,难度较高可以先从demo网址找些简单点来实现


3. 怎么用 D3.js 开发一个树图


3.1 前置基础

想要使用D3.js做数据可视化你需要了解一些前置知识,如SVG
首先你需要熟悉它的常用标签及属性:








...
width height color transform fill stroke class d ...

3.2 d3开发树图流程


  1. 根据需求确定图表类型(例如树图)

  2. 数据预处理(把输入的原始数据转化成为标准的D3可接受的数据格式一般图像是对象数组)

  3. 根据处理好的数据结合布局API作图(例如树图 :d3.hierarchy()和d3.tree()的结合使用)

  4. 再调整文本位置,间隔等细节的东西,从而让图形布局更合理

  5. 给已经完成的图形添加动画效果和事件交互


3.3 动手实现一个树图


3.3.1 普通tide tree

tide tree长啥样?
vijay的博客
怎么实现?
第一步:在页面中初始化设置 svg

// 1、 选中页面给页面添加svg标签;设置Svg绘制区域的宽和高;添加g元素(svg的group分组标签元素)并设置位置。// Set the dimensions and margins of the diagramlet margin = { top: 470, right: 90, bottom: 30, left: 90 };let width = 1960 - margin.left - margin.right;let height = 1200 - margin.top - margin.bottom;let svg = d3.select("body").append("svg").attr("width", width).attr("height", height).append("g").attr("transform", `translate(${margin.left},${margin.top})`);

第二步:数据预处理

// 2、生成树状布局,设置树图布局容器尺寸。let tree = d3.tree().nodeSize([30, 170]);let root = d3.hierarchy(this.treeData); // 第一次数据预处理,给每个节点添加了 height depth parent 属性this.tree(root); // 第二层数据预处理 确定每个节点在图上的位置,每个节点多了x,y属性

第三步:生成节点和链接

// 4.2生成连线。let link = svg.selectAll(".link").data(links)// .enter()// .append("path").join("path").attr("class", "link").attr("fill", "none").attr("stroke", "#ccc").attr("d", diagonal);// 4.3生成节点。let node = svg.selectAll(".node").data(nodes).enter().append("g").attr("class", "node").attr("transform", function (d) {return "translate(" + d.y + "," + d.x + ")";})// 4.4给节点添加圆圈,设置半径。node.append("circle").attr("r", 5);// 4.5给节点添加文本,设置文本的样式位置。node.append("text").text((d) => {console.log("d", d);return d.data.name;}).attr("dx", (d) => (d.children ? -15 : 15)).attr("dy", 5).attr("text-anchor", (d) => (d.children ? "end" : "start"));

第四步:给已经完成的图形添加动画效果和事件交互,例如这里给每个节点添加点击事件和mouseover事件

// 4.3生成节点。let node = svg.selectAll(".node").data(nodes).enter().append("g").attr("class", "node").attr("transform", function (d) {return "translate(" + d.y + "," + d.x + ")";}).on("click", (d) => {console.log(`----------click------------`);}).on("mouseover", () => {console.log(`----------hover------------`);});

没错,正是在第三步添加节点后接着链式调用on()方法即可绑定事件
如此,一颗简单的树就生成了!


3.3.2 你的树图不简单—— radio tide tree

关于树图,你是否还有其他联想?接下来我们看看一个不太“规矩”的树图——radio tide tree
在这里插入图片描述
radio tide tree又是如何实现的呢?
一番摸索后,我发现这两种树图实现的差别在于:


  • d3.tree()传入参数不同
  • link对角线生成器不同
  • 节点transform设置不同

差别tide treeradio tide tree
d3.tree()传入参数不同[width,height][radian,radius]
link对角线生成器不同linkHorizontal()或者linkRadial()
节点transform设置不同x,y坐标极坐标

具体设置方法,如下:
切记d3.tree().size()参数为弧度和半径

// 2、生成树状布局,设置树图布局容器尺寸。let tree = d3.tree().size([2 * Math.PI, 140]).separation(function (a, b) {return (a.parent == b.parent ? 1 : 2) / a.depth;}); let root = d3.hierarchy(this.treeData);tree(root);

link对角线生成器的不同,linkRadial()

// 4.2生成连线。let link = svg.selectAll(".link").data(links)// .enter()// .append("path").join('path').attr("class", "link").attr('fill','none').attr('stroke','#ccc').attr('stroke-width','1.5px').attr("d",d3.linkRadial().angle(function (d) {return d.x;}).radius(function (d) {return d.y;}));

节点transform设置不同,极坐标的方式设置

// 4.3生成节点。// 极坐标function radialPoint(x, y) {return [(y = +y) * Math.cos((x -= Math.PI / 2)), y * Math.sin(x)];}let node = svg.selectAll(".node").data(nodes).enter().append("g").attr("class", "node").attr("stroke", "red").attr("transform", d => `rotate(${d.x * 180 / Math.PI - 90})translate(${d.y},0) `) // return "translate(" + radialPoint(d.x, d.y) + ")";

此处可上滑与tide tree代码进行对比,观察不同


3.3.3 更多可能——更多类型的树图

当然,树图的具体实现效果绝不仅此两种,可以预见的是,符合树型特点的图皆可称之为树图,它们对数据的层次结构要求皆相同
例如:
indented tree
在这里插入图片描述
Tangled tree visualization II
在这里插入图片描述
Sunburst
在这里插入图片描述
看了这么多炫酷的tree,不如自己去操作一番!!
在这里插入图片描述
文中所用demo已上传到github仓库:demo地址链接https://github.com/coder-WJie/D3-test/tree/

D3js 官网:https://d3js.org/


推荐阅读
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 最近学习了关于使用最为流行的jquery发送请求,在实践中以最为简单的聊天室作为测验的辅助工具,对相关网页开发有一个初步的认识,希望大家能够一起学习进步。首先介绍一下 ... [详细]
  • 本文实例为大家分享了d3.js图形拖拽的具体代码,供大家参考,具体内容如下 ... [详细]
  • 前端提高篇(七十):SVG基本使用、基本样式、路径path
    SVG是使用XML来描述二维图形和绘图程序的语言。SVG遵循的是xml的规范,与html5的使用有所区别SVG绘制出来的是矢量图,放大之后不会失真官方文 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 4554:[Tjoi2016&Heoi2016]游戏 ... [详细]
  • 在搜索数据库中的数据时,您可以使用SQL通配符。SQL通配符在搜索数据库中的数据时,SQL通配符可以替代一个或多个字符。SQL通配符必须与LIKE运算符 ... [详细]
  • 人脸检测 pyqt+opencv+dlib
    一、实验目标绘制PyQT界面,调用摄像头显示人脸信息。在界面中,用户通过点击不同的按键可以实现多种功能:打开和关闭摄像头, ... [详细]
  • 今天周六,原则上要休息,但想到下周还有一堆任务,还是先做一部分工作吧,就把之前做的票面设计器改了改,增加了上传图片和更换背景底图的功能。现在打算整理下这个设计器,也算对齐一个总结。不过这属于我们部门的 ... [详细]
  • MindFusion Diagramming for Java, 最新版 Crack
    DiagrammingforJava,V4.6.1AuniqueJavaSwinglibraryforanytypeofflowchart.您需要的每一个图表功能图表、方案、图形、 ... [详细]
  • 用JavaScript实现的太空人手表
    用JavaScript实现的太空人手表-JS写的太空人手表,没有用canvas、svg。主要用几个大的函数来动态显示时间、天气这些。天气的获取用到了AJAX请求。代码中有详细的注释 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
author-avatar
王责宇0218
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有