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

D3js快速入门——用最新版D3js实现树图文章目录 引言 1 D3js 是什么 2 D3js 相对其他数据可视化方案的优势 2 1SVG 对比 Canvas2 2D3 js 对比 Echarts3 怎么用 D3 js 开发一个树图 3 1 前置基础 3 2d3 开发树图流程 3 3 动手实现一个树图 3 3 1 普通 tidetree3 3 2 你的树图不简单 radiotidetre 3 3 更多可能 更多类型的树图引言上周我们组新开项目 技术调研之后决定使用 d3 js 做数据可视化开发 mentor 让我来做初期技术调研 之后的技

引言

可是我们项目不打算用过低版本,于是我结合网上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

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

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

2.2 D3.js 对比 Echarts

ECharts D3
Canvas为主4.0+也支持SVG SVG为主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 前置基础

<!-- 常用标签 --> <svg></svg> <g></g> <circle> <path> <line> <rect> <text> ... <!-- 常用属性 --> 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
// 1、 选中页面给页面添加svg标签;设置Svg绘制区域的宽和高;添加g元素(svg的group分组标签元素)并设置位置。 // Set the dimensions and margins of the diagram let 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------------`); }); 
3.3.2 你的树图不简单—— radio tide tree
  • d3.tree()传入参数不同
  • link对角线生成器不同
  • 节点transform设置不同
差别 tide tree radio tide tree
d3.tree()传入参数不同 [width,height] [radian,radius]
link对角线生成器不同 linkHorizontal()或者 linkRadial()
节点transform设置不同 x,y坐标 极坐标
 // 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 更多可能——更多类型的树图

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232229.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • matlab求解不定方程组_matlab解参数方程组

    matlab求解不定方程组_matlab解参数方程组最想说的一句话:要查matlab用法,一定要到官网去查,一些用法matlab官方是在不断更新的,现存的一些办法已经无法解决问题使用的是solve这个函数它拥有解决优化问题,解方程的功能,下面我将举一些常用的例子文章目录一、解单变量方程二、解多变量方程三、解带参数方程四、解不等式知识点总结一、解单变量方程题目:求解方程2x+1=0 2x+1=02x+1=0symsx…

    2022年9月14日
    4
  • elementui快速入门_vue element ui

    elementui快速入门_vue element ui什么是ElementUI这篇文章会告诉你带你快速入门学会ElementUI

    2025年9月28日
    3
  • JsonObject和JsonArray转换问题

    JsonObject和JsonArray转换问题开发过程中遇到需要将调用接口返回的JsonObject转换为JsonArray格式的数据,在使用过成中遇到转换问题,代码如下publicstaticJSONObjectgetRecJsonObj(StringstuId,StringschoolDate){Stringjson;try{json=Jsoup.connect(UrlConfig.URL+”GetStudentInfo?stuId=”+stuId+

    2022年5月31日
    40
  • Chrome 扩展 最近的历史 HistoryBar v1.1

    Chrome 扩展 最近的历史 HistoryBar v1.1

    2022年1月11日
    53
  • 企业级发卡网源码下载带代理系统授权搭建教程

    企业级发卡网源码下载带代理系统授权搭建教程  发卡网源码,英文名:Automaticshippingsourcecode,适用于构建在互联网上用于虚拟商品自动发货和交易的网购平台。往往根据用途和规模不同,分为:企业发卡网源码和个人发卡网源码,其核心功能为自动发货和自动收付款,类似于线下的无人售货机。  发卡网只适用于虚拟物品的交易,无法完成实物的交易,由于实物涉及快递时长,不符合发卡网方便快捷的特点。要想搭建一个运转良好的发卡网是需要做大量工作的,但最重要最基础的是搭建的发卡网源码稳定且bug少,不然很难提供频繁的发卡交易服务。 

    2022年7月14日
    36
  • C++ nullptr

    c++nullptr

    2022年4月6日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号