当前位置: 首页 > news >正文

D3.js 初探

文章目录

    • D3.js 简单介绍
    • 选择集与方法
    • 数据绑定方法
    • 选择集添加DOM元素以及删除元素
    • 理解update enter 以及 exit
    • 关于比例尺
    • layout 布局
      • force layout
    • 坐标轴元素
    • 添加动态效果
    • demo1: 绘制简单柱状图

#D3.js 初探
最近在做一个Data Visualization 的项目,由于对最终呈现的效果的交互性要求比较高,再加上自己做过前端的项目,对javascript还是比较熟悉的,所以最终采用D3.js 来完成数据的可视化。在工作之余花了点时间系统学习了一下D3.js,接下来几篇blog会对d3.js 做一些由简到繁的一些总结。

D3.js 简单介绍

D3.js 是一款数据可视化工具,说到数据可视化工具那简直不要太多,这里没必要一一列出。我主要说明一下我对D3.js 的一些认识。D3.js 是一个javascript 的函数库(称不上框架),地位类似于JQuery,只是区别在于一个是做可视化的库,一个是做纯前端开发的库,但最终目的都是方便开发者能够快速完成功能。而且本身底层就是javascript实现,非常适合于懂web前端开发并且又需要完成数据可视化任务的人;相比于Python的数据可视化工具,个人更倾向于使用D3.js。

选择集与方法

D3.js底层依然是操作DOM元素,所以依然需要选择操作的DOM元素实现绑定数据,添加事件,添加动画效果等等。D3.js 里面提供两种方法去选择元素d3.selectd3.selectAll 方法名称其实就表明了第一种方法只是选择匹配上的第一个元素,而第二种方法会选择匹配上的所有元素;两种方法参数就是CSS选择器参数相同,例子如下:

<body><p >hello</p><p >world</p>
</body>
var body = d3.select('body');// get body
// change the first p
var p = body.select('p');
p.text('just change the first p');
// change all the p
var p = body.selectAll('p')
p.text('just change all the p')

数据绑定方法

D3.js 也提供了非常不错的数据绑定的方法,方便开发者完成DOM元素与数据的绑定,主要有两个方法datumdata 区别在于第一个函数将一个数据与所有选中元素绑定;而第二个函数是将一个列表与选中的所有元素绑定,从使用情况来看,方法二使用更为频繁。例子如下

			var body = d3.select('body');var p = body.selectAll('p');data = 'hello';p.datum(data);p.text(function(d,i){return 'number '+i+' is '+d;//其中d为当前元素绑定数据,i为元素索引。});

输出:

number 0 is hellonumber 1 is hello

绑定数据唯一所以在text的回调函数里面d这个参数传递内容都是一样的。如果采用data 函数又是如下的效果:

number 0 is hellonumber 1 is how

选择集添加DOM元素以及删除元素

选择集中添加DOM元素提供了两种方法appendinsert 方法一是在选择集内部后面插入元素,方法二是在选择集内部前面插入元素。注意不是平级别的,如果选择只是一个元素,那么在这个元素里面插入,如果选择的是一个集合,那么会在集合中的每一个元素内部在插入元素。例子如下:

	<body><p>this is the first p</p><p>this is the second p</p><script>var body = d3.select('body');var p = body.selectAll('p');data = ['how','are','you'];p.data(data);p.text(function(d,i){return d;});p.append('p').text('hello');//每一个选中的p中都会再插入一个p元素并且内容为hello</script></body>

输出结果:

![append结果](https://img-blog.csdn.net/20170924204348443?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQWxsb2NhdG9y/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
删除是remove方法,例子如下: ```javascript

this is the first p

this is the second p

``` 输出结果:
![remove](https://img-blog.csdn.net/20170924204659118?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQWxsb2NhdG9y/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

理解update enter 以及 exit

update enter 以及 exit 是D3.js 里面非常重要的概念。用于处理当数据数量与元素数量关系不一致的情况。
update 表示DOM元素与绑定数据一一对应的部分。可以这样理解再任何选择集合上面调用data 方法绑定数据之后返回的其实都是update部分。而enter指的是当集合中元素小于绑定数据时候,D3.js 会创建一些空的"元素空间"和绑定数据对应,以便于增加新的元素最终保持数量与绑定的数据的量一致;而exit正好是另外一种情况,当DOM元素数量多于绑定数据数量时,exit值得正式那一部分多出的数据。一般正对exit的部分都直接调用remove函数,因为没有必要保留没有绑定数据的DOM元素。例子如下:
html如下

<body onload="load()"><p >this is the first p</p><p>this is the second p</p><p> this is third p</p>
</body>

javascript代码如下:

			function load(){var p = d3.select('body').selectAll('p');data = [1,2,3,4,5,6];p.data(data) //获取到了update部分 .text(function(d,i){return 'update content '+d+' and'+i;}).enter() //获取到enter 部分.append('p') //针对剩余的数据添加p元素并绑定.text(function(d,i){return 'enter content '+d+' and'+i;});p.append('p').text('shows?');// 此时p 只是代表update 部分所以调用append 只会在前三个p内部添加元素,后面enter 部分添加的元素不会再次添加}

输出的结果为:

![enter](https://img-blog.csdn.net/20170924213726068?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQWxsb2NhdG9y/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

同样exit的例子如下,处理当DOM元素数量大于绑定数据量的情况:

<body onload="load()"><p >this is the first p</p><p>this is the second p</p><p> this is third p</p>
</body>

javascript:

function load(){var p = d3.select('body').selectAll('p');data = [1,2];p.data(data)//获取到了update部分 .text(function(d,i){return 'update content '+d+' and'+i;}).exit() //获取到exit部分.text(function(d,i){return 'exit content '+d+' and'+i;});}

输出结果为:

![exit](https://img-blog.csdn.net/20170924214239153?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQWxsb2NhdG9y/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

可以看到一个有趣的现象,由于最后一个元素没有绑定数据,所以回调函数中传入的参数d为undefined可以理解,但是i这个表示Index的参数还持续生效。

关于比例尺

之前使用过简单的数据绑定,在绘制图形的时候是直接使用数据的大小表示图形中的像素大小,但是在某一些情况下却不能够这么做(比如数据list本身数据都很小,或者是都非常大) 此时就需要使用比例尺将数据等价转换成可以很好的可视化的数据。比例尺可以看做一个映射关系,即为X到Y的映射关系其中X称为定义域(domain) Y 称为值域(range)。再D3.js 中主要提供了两种比例尺:线性比例尺以及序列比例尺。

  1. 线性比例尺可以看做是一个线性变换,例子如下:
function load(){src_data = [0.2,0.3,0.1,0.4,0.5]; //原始数组max_value = d3.max(src_data); //获取原始数据的最大值与最小值,作为定义域范围min_value = d3.min(src_data);var linear_scale = d3.scale.linear().domain([min_value,max_value]).range([0,50]);//构建一个线性的比例尺函数for(var i=0;i<src_data.length;i++){console.log('原始数据'+src_data[i]);console.log('线性比例尺变换结果'+linear_scale(src_data[i]);}}

返回的线性比例尺为一个函数,传递原始数据范围内的任意一个数值都可以映射到Range范围内相应的一个数值。所以实际操作中只需要知道原始数据的最大值和最小值以及最终Range的范围就可以确定这个比例尺函数。线性比例尺适用于domain以及Range都是连续数值的应用场景。
2.序数比例尺
序数比例尺适用于domain 和Range 取值都是离散的应用情况,只是单纯的从domain中的元素一一映射到range中的元素。

	var ord_src = [0,1,2,3,4]var ord_ran = ['red','blue','white']var ordinal_scale = d3.scale.ordinal().domain(ord_src).range(ord_ran);for(var i=0;i<ord_src.length;i++){console.log('src data'+ord_src[i]);console.log('ordinal data'+ordinal_scale(ord_src[i]));}

从输出来看即便Range的元素少于domain元素,最终结果依然是循环映射,不会出现undefined的情况。

layout 布局

layout布局元素是为了实现更加强大而多样化的可视化功能,D3.js 中有非常多的layout。下面以force layout(力量图)作为一个demo进行讲解

force layout

force layout 即是力量图,此种图形中的元素是可以进行拖拽的。demo如下:


一一讲解demo中调用函数的意义:

坐标轴元素

D3提供了坐标轴,使用d3.svg.axis()可以构建坐标轴,本质上这一段代码返回的是一个函数,后续跟scale()确定比例尺orient()指定刻度位置,ticks()指定刻度数量。

	var margin = {'left':100,'top':20,'bottom':20,'right':20};var body = d3.select('body');var svg = body.append('svg').attr('width',200).attr('height',200).style('margin-left',margin.left+'px').style('margin-top',margin.top+'px').style('padding',20).style('background-color','yellow');var min_val = 0;var max_val = 40;// domain shows the ticks value and range shows the length(px) of the axisvar linear_scale = d3.scale.linear().domain([min_val,max_val]).range([0,200]);var axis = d3.svg.axis().scale(linear_scale).orient('bottom').ticks(6);svg.append('g').call(axis);// add the axis

添加动态效果

图标的动态效果在可视化中是非常关键而重要的,一张静态的图并不能够很好的反应出数据的一些变化规律,所以需要一些动态的效果辅助改特性的展现,数据应该是“动”的。
1.transation
过度效果,其实本身用CSS以及JavaScript都能够实现这些功能,D3.js也只是做了一些封装,保证编程风格一致。transition用于启动过度效果,实现增加元素一个状态(位置或者颜色)到另外一个状态的动态感。
2.duration
过度持续时间,单位为毫秒,一些状态的变换需要较长的时间来凸显效果。
3.ease
设定过度的方式,常用的方式为:1)linear线性变化,circle缓慢变化到最终状态,elastic弹性变化,bounce变换状态终点时弹几次。
4.delay
指定过度的延迟时间,单位毫秒,给定回调函数可以指定特定的元素过度效果的延迟时间。
简单的例子如下:

demo1: 绘制简单柱状图

一般使用D3.js 绘制图标都会选择在SVG上面绘制,使用矢量图即可以保证放大缩小图像不失真,又能够保证图形中每一个元素都能够添加事件,提高了图形的交互能力。有一点需要注意SVG中X轴正方向是水平向右,而Y轴正方向是竖直向下。绘制简易的柱状图如下:

function load(){var height = 200,width = 200;var rectheight = 30;var body = d3.select('body');var svg = body.append('svg').attr('width',width).attr('height',height);data = [100,50,45,120,300];//表示柱状图的宽度。svg.append('rect');// 添加一个初始空的rect 便于统一选择并且设置属性与文本,DOM上面只是增加一个空白的rectsvg.selectAll('rect').data(data).enter().append('rect') //enter 部分添加rect.attr('x',10) //设置每一个rectx 坐标.attr('y',function(d,i){return i*rectheight;}) //设置每一个rect y坐标.attr('width',function(d){ return d;})// 设置每一个rect 宽度.attr('height',rectheight-5)// 设置每一个rect 高度.attr('fill','blue');// 设置每一个rect 颜色}

相关文章:

D3.js 初探

文章目录 D3.js 简单介绍选择集与方法数据绑定方法选择集添加DOM元素以及删除元素理解update enter 以及 exit关于比例尺layout 布局force layout 坐标轴元素添加动态效果demo1: 绘制简单柱状图 #D3.js 初探 最近在做一个Data Visualization 的项目&#xff0c;由于对最终呈现的…...

linux常用指令 | 适合初学者

linux常用指令 1.ls: 列出当前&#xff0c;目录中的文件和子目录 ls 2.pwd: 显示当前工作目录的路径 pwd3.cd切换工作目录 cd /path/to/director4.mkdir:创建新目录 mkdir directory_name5.rmdir:删除空目录 rmdir directory_name6.rm: 删除文件或目录 rm file_name r…...

用 NotePad++ 运行 Java 程序

安装包 网盘链接 下载得到的安装包: 安装步骤 双击安装包开始安装. 安装完成: 配置编码 用 NotePad 写 Java 程序时, 需要设置编码. 在 设置, 首选项, 新建 中进行设置, 可以对每一个新建的文件起作用. 之前写的文件不起作用. 在文件名处右键, 可以快速打开 CMD 窗口, 且路…...

在 Linux 环境下搭建 OpenLab Web 网站并实现 HTTPS 和访问控制

实验要求 综合练习&#xff1a;请给openlab搭建web网站 ​ 网站需求&#xff1a; ​ 1.基于域名[www.openlab.com](http://www.openlab.com)可以访问网站内容为 welcome to openlab!!! ​ 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c…...

微信小程序wx.showShareMenu配置全局分享功能

在app.js文件中配置如下即可&#xff1a; onLaunch() {//开启分享功能this.overShare()},/*** 开启朋友圈分享功能* 监听路由切换/自动执行*/overShare() {wx.onAppRoute((res) > {// console.log(route, res)let pages getCurrentPages()let view pages[pages.length - …...

机器学习面试八股总结

下面是本人在面试中整理的资料和文字&#xff0c;主要针对机器学习面试八股做浅显的总结&#xff0c;大部分来源于ChatGPT&#xff0c;中间有借鉴一些博主的优质文章&#xff0c;已经在各文中指出原文。有任何问题&#xff0c;欢迎随时不吝指正。 文章系列图像使用动漫 《星游…...

南京邮电大学《2024年812自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《南京邮电大学812自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2024年真题 Part1&#xff1a;2024年完整版真题 2024年真题...

大数据新视界 -- Hive 数据湖集成与数据治理(下)(26 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

Android EventBus最全面试题及参考答案

目录 什么是 EventBus&#xff1f; 请解释 EventBus 是什么&#xff0c;以及它的工作原理。 简述 EventBus 的工作原理。 EventBus 的主要组成部分有哪些&#xff1f; EventBus 是如何实现发布订阅模式的&#xff1f; EventBus 与观察者模式有什么区别&#xff1f; Even…...

C++ 游戏开发:开启游戏世界的编程之旅(1)

在游戏开发领域&#xff0c;C 一直占据着极为重要的地位。它以高效的性能、对底层硬件的良好控制能力以及丰富的库支持&#xff0c;成为众多大型游戏开发项目的首选编程语言。今天&#xff0c;就让我们一同开启 C 游戏开发的探索之旅。 一、C 游戏开发基础 &#xff08;一&am…...

SpringBoot mq快速上手

1.依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency> 2.示例代码 基础信息配置 package com.example.demo.config;import org.springframework.amqp.co…...

图像处理网络中的模型水印

论文信息&#xff1a;Jie Zhang、Han Fang、Weiming Zhang、Wenbo Zhou、Hao Cui、Hao Cui、Nenghai Yu&#xff1a;Model Watermarking for Image Processing Networks 本文首次提出了图像处理网络中深度水印问题&#xff0c;将知识产权问题引入图像处理模型 提出了第一个深…...

Halcon 瑕疵检测原理及应用

摘要&#xff1a; 本文详细阐述了 Halcon 在瑕疵检测领域的原理、相关技术以及广泛的应用场景。首先介绍了 Halcon 软件的基本概况及其在机器视觉领域的重要地位&#xff0c;接着深入剖析了瑕疵检测所涉及的图像采集、预处理、特征提取与分析以及分类与判定等核心原理&#xff…...

JAVA 架构师面试 100套含答案:JVM+spring+ 分布式 + 并发编程》...

今年的行情&#xff0c;让招聘面试变得雪上加霜。已经有不少大厂&#xff0c;如腾讯、字节跳动的招聘名额明显减少&#xff0c;面试门槛却一再拔高&#xff0c;如果不用心准备&#xff0c;很可能就被面试官怼得哑口无言&#xff0c;甚至失去了难得的机会。 现如今&#xff0c;…...

多模态学习详解

多模态学习详解 引言 多模态&#xff08;Multimodal&#xff09;学习是机器学习和人工智能领域的一个重要分支&#xff0c;它涉及从多个不同类型的输入数据中提取信息&#xff0c;并将这些信息融合以改善模型的性能。多模态学习能够处理的数据类型广泛&#xff0c;包括但不限…...

C#应用开发:基于C# WPF界面实现本机网络通讯状态(下载速度)的显示

目录 概述 具体实现 第一步&#xff1a;获取网络接口信息 代码解释&#xff1a; 第二步&#xff1a;创建 WPF 界面 第三步&#xff1a;绑定数据 注意事项 概述 在 WPF 中实现一个界面来显示本机网络接口的状态&#xff0c;通常需要以下几个步骤&#xff1a; 获取网络接口…...

Octo—— 基于80万个机器人轨迹的预训练数据集用于训练通用机器人,可在零次拍摄中解决各种任务

概述 论文地址&#xff1a;https://arxiv.org/abs/2405.12213 在机器人学中&#xff0c;通常使用针对特定机器人或任务收集的数据集来学习策略。然而&#xff0c;这种方法需要为每项任务收集大量数据&#xff0c;由此产生的策略只能实现有限的泛化性能。利用其他机器人和任务的…...

2022高等代数下【南昌大学】

设 ε 1 , ε 2 , ε 3 \varepsilon_1, \varepsilon_2, \varepsilon_3 ε1​,ε2​,ε3​ 是复数域上线性空间 V V V 的一组基,线性变换 σ \sigma σ 在 ε 1 , ε 2 , ε 3 \varepsilon_1, \varepsilon_2, \varepsilon_3 ε1​,ε2​,ε3​ 下的矩阵为 J = ( 2 0 0 1 2…...

UDP编程

UDP编程是指使用用户数据报协议&#xff08;UDP&#xff09;进行网络编程的过程。UDP是一种无连接的传输协议&#xff0c;它不保证数据的可靠性和顺序性。 在UDP编程中&#xff0c;程序可以使用套接字&#xff08;socket&#xff09;来进行数据的发送和接收。UDP套接字是一种用…...

论文阅读:Omnidirectional Image Super-resolution via Bi-projection Fusion

对于全景图像&#xff08;ODIs&#xff09;的超分辨率的技术有&#xff1a;等矩投影&#xff08;ERP&#xff09;但是这个没有利用 ODIs 的独特任何特性。ERP提供了完整的视场但引入了显著的失真&#xff0c;而立方体映射投影&#xff08;CMP&#xff09;可以减少失真但视场有限…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...