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)可以减少失真但视场有限…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...