JavaScript 可视化库D3介绍

本文介绍了JavaScript可视化库D3,包括渲染器选择(SVG与Canvas)、核心概念如selection、事件注册、数据绑定及过渡,以及D3的模块如Forces和在线平台Observable。D3使用SVG进行开发,简化了DOM操作,并提供了强大的数据绑定和动画功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaScript 可视化库D3介绍

渲染器的选择

  • SVG
  • Canvas
  • HTML element

一般来说,Canvas 更适合绘制图形元素数量较多(这一般是由数据量大导致)的图表(如热力图、地理坐标系或平行坐标系上的大规模线图或散点图等),也利于实现某些视觉 特效。但是,在不少场景中,SVG 具有重要的优势:它的内存占用更低(这对移动端尤其重要)、并且用户使用浏览器内置的缩放功能时不会模糊。 选择哪种渲染器,我们可以根据软硬件环境、数据量、功能需求综合考虑。 在软硬件环境较好,数据量不大的场景下,两种渲染器都可以适用,并不需要太多纠结。 在环境较差,出现性能问题需要优化的场景下,可以通过试验来确定使用哪种渲染器。比如有这些经验: 在须要创建很多 ECharts 实例且浏览器易崩溃的情况下(可能是因为 Canvas 数量多导致内存占用超出手机承受能力),可以使用 SVG 渲染器来进行改善。大略得说,如果图表运行在低端安卓机,或者我们在使用一些特定图表如 水球图 等,SVG 渲染器可能效果更好。 数据量较大(经验判断 > 1k)、较多交互时,建议选择 Canvas 渲染器。 我们强烈欢迎开发者们反馈给我们使用的体验和场景,帮助我们更好的做优化。

来自echarts 最佳实践 canvas vs svg

引入

import {scaleLinear} from "d3-scale"; 
import * as d3 from "d3"; 
const d3 = await import("d3"); 

d3当中的核心概念

最简单的一个例子

d3.js当中主要使用 SVG 进行开发,相比直接操作恶心的HTML DOM,D3提供的一套声明式语法更加舒服。

var paragraphs = document.getElementsByTagName("p");
for (var i = 0; i < paragraphs.length; i++) {
  var paragraph = paragraphs.item(i);
  paragraph.style.setProperty("color", "blue", null);
} 

显然能够降低心智负担

d3.selectAll("p").style("color", "blue"); 

练习

d3.selectAll("p").style("color", function(d, i) {
  return i % 2 ? "blue" : "red";
}); 

selection

概念

d3当中大部分的操作都是针对selection进行的

  • 事件侦听
  • style属性设置
  • 数据绑定

通过以下函数可以生成一个selection

d3.create() //创造一个元素
d3.select() //选择匹配的第一个元素
d3.selectAll() //选择一组元素 

Selection对象的结构如下

{
    export function Selection(groups, parents) {
        this._groups = groups;
        this._parents = parents;
  }
​
    function selection() {
        return new Selection([[document.documentElement]], root);
  }
​
    function selection_selection() {
        return this;
  }
​
    Selection.prototype = selection.prototype = {
        constructor: Selection,
        select: selection_select,
        selectAll: selection_selectAll,
        selectChild: selection_selectChild,
        selectChildren: selection_selectChildren,
        filter: selection_filter,
        data: selection_data,
        enter: selection_enter,
        exit: selection_exit,
        ...
  };
} 

实际生成 Selection 对象

生成的selection对象会有两个隐藏属性,来表示该selection的结构,selection具体是如何工作的,可以查看 Mike Bostock 的 How Selection work

d3通过创建或者选择DOM元素生成一个Selection

这些函数本质上也是调用的W3C DOM API中的Selector API

function empty() {return [];
}

export default function(selector) {return selector == null ? empty : function() {// 调用元素的selectorreturn this.querySelectorAll(selector);};
} 

selection上暴露了大量的方法以供用户操作,方便对元素添加、更新、删除对应的节点


事件注册

早期版本的d3 是通过全局的d3.event获取当前事件信息,在后续版本已经移除,直接在事件监听器中传递当前的事件信息,d3的版本可以通过全局暴露的d3.version获取

 d3.selectAll("div").on("mouseover", function(){d3.select(this).style("background-color", "orange");// Get current event infoconsole.log(d3.event);// Get x & y co-ordinatesconsole.log(d3.mouse(this));}).on("mouseout", function(){d3.select(this).style("background-color", "steelblue")}); 

d3通过selection.on()方法注册事件监听器, 任何浏览器支持的标准事件类型都支持

d3.create("ul").call(ul => ul.selectAll("li").data(names).join("li").text(name => `My name is ${name}! `).append("a").attr("href", "#").on("click", click).text("Pick me.")).node() 
数据绑定

D3直接绑定数据到selection上,数据可以是任意数组类型,给定一个数组和selection就可以将每个数组元素追加到selection当中每个元素。

比如,一个number的数组

[1,2,3,4,5]; 

或者一个二维数组

const matrix = [[11975,5871, 8916, 2868],[ 1951, 10048, 2060, 6171],[ 8010, 16145, 8090, 8045],[ 1013, 990,940, 6907]
]; 

或者一个对象数组

const letters = [{name: "A", frequency: .08167},{name: "B", frequency: .01492},{name: "C", frequency: .02780},{name: "D", frequency: .04253},{name: "E", frequency: .12702}
]; 

数据绑定会在对应的dom元素上挂载一个对应的__data__属性

data当中的数据和selection当中的元素对应关系如下

如果没有为数据绑定提供一个 key function 那么会默认的根据元素在DOM当中的顺序绑定数据

d3.selectAll("div").data(data, function(d) { return d ? d.name : this.id; }).text(d => d.number); 
过渡

transition 是一个类 selection 的接口,用来对 DOM 进行动画修改。这种修改不是立即修改,而是在规定的事件内平滑过渡到目标状态。

应用过渡,首先要选中元素,然后调用 selection.transition,并且设置期望的改变,例如:

d3.select(“body”) .transition() .style(“background-color”, “red”); 过渡支持大多数选择集的方法(比如 transition.attr 和 transition.style 对应 selection.attr 和 selection.style),但是并不是所有的方法都支持; 比如必须在对元素过渡之前 append 元素或者 bind data。transition.remove 操作可以在动画结束时方便的移除元素。

为了计算过渡过程中的状态,过渡集成了大量的 built-in interpolators。Colors, numbers, 以及 transforms 会被自动检测。内嵌数字的 Strings 也会被检测到,可以方便的对许多样式(比如 padding 或 font size) 以及 path 进行过渡。可以使用 transition.attrTween, transition.styleTween 或 transition.tween 指定一个自定义插值器。

模块

d3是各个模块配合一起工作的,可以从collection of modules单独引入,也可以一起使用。 如果是绘制柱状图、折线图、这类图表,可以选择axes来提供定义坐标的样式,选择Scales来定义比例尺。如果还有颜色和交互上的需求可以选择 Zooming Drag 等模块 来缩放和拖拽…

还有一些有意思的模块

  • Forces,来提供力学模拟
  • Geographies 提供地理以及几何的绘制

Forces

D3的力学模拟是通过韦尔莱积分法(Verlet Integration)实现,通过对数据当中的节点添加力学函数来实现特定的力学模拟,每次触发tick事件时,会更新节点的各个属性

 const simulation = d3.forceSimulation(nodes).force("link", forceLink).force("charge", forceNode).force("center",d3.forceCenter()).on("tick", ticked); 

在线的可视化平台Observable

d3的主要维护人员,同时也是Overvable的创始人

D3提供了一个在线的可视化平台 Observable 为一些简单的例子提供了在线可运行的编辑器,并且封装了一些交互式组件提供了极大的便利

demo地址

在Observable中的notebooks中编写的代码是分块执行的,各个代码块组成的程序结构是一个有向无环图(DAG) 更改其中的代码块之后会触发相关联的代码块重新执行

每个代码块要求必须返回一个值,如果返回的时HTML元素,那么会在notebooks当中进行渲染, 一个典型的代码块是

{// 返回对应HTML元素return svg.node()
} 

另外比较比较好用的功能是,Observable提供文件存储功能,可能利用它提供的FileAttachment(file_name)来访问对应的文件,以便对程序当中的数据进行填充

更方便的是可以提供类似 Jupter Notebooks 的功能,在编辑中可以书写markdown文档,而且提供部分_TeX_的数学公式语法支持,如果需要自定义样式的,也可以在代码块当中书写HTML

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值