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.select
和 d3.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元素与数据的绑定,主要有两个方法datum
和 data
区别在于第一个函数将一个数据与所有选中元素绑定;而第二个函数是将一个列表与选中的所有元素绑定,从使用情况来看,方法二使用更为频繁。例子如下
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元素提供了两种方法append
和 insert
方法一是在选择集内部后面插入元素,方法二是在选择集内部前面插入元素。注意不是平级别的,如果选择只是一个元素,那么在这个元素里面插入,如果选择的是一个集合,那么会在集合中的每一个元素内部在插入元素。例子如下:
<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>
输出结果:
this is the first p
this is the second p
``` 输出结果:理解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 部分添加的元素不会再次添加}
输出的结果为:
同样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;});}
输出结果为:
可以看到一个有趣的现象,由于最后一个元素没有绑定数据,所以回调函数中传入的参数d为undefined可以理解,但是i这个表示Index的参数还持续生效。
关于比例尺
之前使用过简单的数据绑定,在绘制图形的时候是直接使用数据的大小表示图形中的像素大小,但是在某一些情况下却不能够这么做(比如数据list本身数据都很小,或者是都非常大) 此时就需要使用比例尺将数据等价转换成可以很好的可视化的数据。比例尺可以看做一个映射关系,即为X到Y的映射关系其中X称为定义域(domain) Y 称为值域(range)。再D3.js 中主要提供了两种比例尺:线性比例尺以及序列比例尺。
- 线性比例尺可以看做是一个线性变换,例子如下:
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 的项目,由于对最终呈现的…...
linux常用指令 | 适合初学者
linux常用指令 1.ls: 列出当前,目录中的文件和子目录 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 和访问控制
实验要求 综合练习:请给openlab搭建web网站 网站需求: 1.基于域名[www.openlab.com](http://www.openlab.com)可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息,教学资料和缴费网站,…...

微信小程序wx.showShareMenu配置全局分享功能
在app.js文件中配置如下即可: onLaunch() {//开启分享功能this.overShare()},/*** 开启朋友圈分享功能* 监听路由切换/自动执行*/overShare() {wx.onAppRoute((res) > {// console.log(route, res)let pages getCurrentPages()let view pages[pages.length - …...
机器学习面试八股总结
下面是本人在面试中整理的资料和文字,主要针对机器学习面试八股做浅显的总结,大部分来源于ChatGPT,中间有借鉴一些博主的优质文章,已经在各文中指出原文。有任何问题,欢迎随时不吝指正。 文章系列图像使用动漫 《星游…...

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

大数据新视界 -- Hive 数据湖集成与数据治理(下)(26 / 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
Android EventBus最全面试题及参考答案
目录 什么是 EventBus? 请解释 EventBus 是什么,以及它的工作原理。 简述 EventBus 的工作原理。 EventBus 的主要组成部分有哪些? EventBus 是如何实现发布订阅模式的? EventBus 与观察者模式有什么区别? Even…...
C++ 游戏开发:开启游戏世界的编程之旅(1)
在游戏开发领域,C 一直占据着极为重要的地位。它以高效的性能、对底层硬件的良好控制能力以及丰富的库支持,成为众多大型游戏开发项目的首选编程语言。今天,就让我们一同开启 C 游戏开发的探索之旅。 一、C 游戏开发基础 (一&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…...

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

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

JAVA 架构师面试 100套含答案:JVM+spring+ 分布式 + 并发编程》...
今年的行情,让招聘面试变得雪上加霜。已经有不少大厂,如腾讯、字节跳动的招聘名额明显减少,面试门槛却一再拔高,如果不用心准备,很可能就被面试官怼得哑口无言,甚至失去了难得的机会。 现如今,…...
多模态学习详解
多模态学习详解 引言 多模态(Multimodal)学习是机器学习和人工智能领域的一个重要分支,它涉及从多个不同类型的输入数据中提取信息,并将这些信息融合以改善模型的性能。多模态学习能够处理的数据类型广泛,包括但不限…...
C#应用开发:基于C# WPF界面实现本机网络通讯状态(下载速度)的显示
目录 概述 具体实现 第一步:获取网络接口信息 代码解释: 第二步:创建 WPF 界面 第三步:绑定数据 注意事项 概述 在 WPF 中实现一个界面来显示本机网络接口的状态,通常需要以下几个步骤: 获取网络接口…...

Octo—— 基于80万个机器人轨迹的预训练数据集用于训练通用机器人,可在零次拍摄中解决各种任务
概述 论文地址:https://arxiv.org/abs/2405.12213 在机器人学中,通常使用针对特定机器人或任务收集的数据集来学习策略。然而,这种方法需要为每项任务收集大量数据,由此产生的策略只能实现有限的泛化性能。利用其他机器人和任务的…...
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编程是指使用用户数据报协议(UDP)进行网络编程的过程。UDP是一种无连接的传输协议,它不保证数据的可靠性和顺序性。 在UDP编程中,程序可以使用套接字(socket)来进行数据的发送和接收。UDP套接字是一种用…...

论文阅读:Omnidirectional Image Super-resolution via Bi-projection Fusion
对于全景图像(ODIs)的超分辨率的技术有:等矩投影(ERP)但是这个没有利用 ODIs 的独特任何特性。ERP提供了完整的视场但引入了显著的失真,而立方体映射投影(CMP)可以减少失真但视场有限…...

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

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #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(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...