【D3.js 01】

D3.js 01

    • 说在前面
    • 1 概述
    • 2 配置Web环境
    • 3 HTML
    • 4 SVG
    • 5 DOM
    • 6 JS
    • 7 常用接口
    • 8 D3语法基础
    • 9 使用D3查询SVG
    • 10 使用D3设置SVG中属性
    • 11 修改整组属性
    • 12 使用D3添加与删除SVG元素
    • 13 数据读取 —— CSV数据
    • 14 D3.js的数值计算
    • 15 比例尺
      • Scale - Linear
      • Scale - Band
    • 16 引入坐标轴
    • 17 DATA-JOIN

说在前面

最近需要使用到D3.js,所以在B站上找到清华的D3.js教程,同时在这里做相关的自学笔记
原视频链接如下:

【数据可视化编程-使用D3.js(2022)】 https://www.bilibili.com/video/BV1qg411X7bB/?share_source=copy_web&vd_source=773b408053db6c74535b5afe2aa8feb9

1 概述

D3.js是目前最主流的,社区规模最大的,支持定制图元级别可视化效果的框架

相关文档:https://github.com/xswei/d3js_doc
D3画廊:https://observablehq.com/@d3/gallery

其他如Echarts不支持图元级别定制,但是支持图表混搭

之后课程会介绍动画与交互,可视化图表绘制,其他常用接口

D3: Data-Driven Documents
通过D3提供的接口基于数据操控文档(画布)的各个图元

接口约等于D3.js提供的函数调用

主要参考资料:

https://d3js.org/ 官网,文档,样例
https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute SVG 属性参考
https://github.com/d3/d3 官方样例仓库
https://observablehq.com/@d3/gallery 官方样例仓库
https://github.com/xswei/d3js_doc d3.js资源汇总,包括示例、书籍、API文档等
https://github.com/Shao-Kui/D3.js-Demos

2 配置Web环境

D3.js基于JS,用于在Web前端控制HTML中的元素

  • 使用VScode,安装Live Server
  • 直接应用常用框架:Python Simple HTTP Server(不推荐),Node.js Simple HTTP Server,Flask, Express等

3 HTML

HyperText Markup Language
HTML包含大量元素(标签)

  • 元素之间类别不同,如矩形,直线,文本,圆等等
  • 元素包含属性,如位置,大小,色调,文本风格等等

<script> :JS脚本或者脚本链接
D3.js或Echart的编程主要写于此标签中
<svg>:对于D3最重要的标签
主要操作的对象画布,同时包括所有图元应用的标签,如<rect>, <circle>, <path>

D3.js是JS的外库,必须先将其导入
如同Python的import
Java的import
C/C++的include
node.js的require
这里通过Script标签导入

  • 直接通过互联网链接 - <script src="https://d3js.org/d3.v7.min.js"></script>
  • 通过本地服务器链接 - ./d3.min.js
  • 通过unpkg链接 - https://unpkg.com/browse/d3@5.15.0/dist/d3.js
    尽量使用本地的d3.min.js库

4 SVG

D3的绘制画布
Scalable Vector Graphics 可缩放矢量图形

5 DOM

文档对象模型
在这里插入图片描述

对于根节点的操作会影响子节点
常用父节点<svg>中的<g>

  • Axis可以封装为一个group
  • Legend(图例)可以封装为一个group

6 JS

解释型
不需要编译
JS语句类似于C与C++
变量声明不需指定类型 int double function等,直接let, var const
运算操作基本等同C,C++和Java
下面是函数定义:

function abc(a) { return a + 5; }
const p = function(a, b){return a + b;}
let f = datum => datum.value;
let myFunction = (a, b) => a + b
let f = (d, i) => { console.log(d);return d + I;}

一个变量可以是一个函数
类似于C/C++中的函数指针
const myFunction = function(a, b){ return a + b; }
回调(CallBack)
JS脚本中常见将函数作为变量输入用于实现异步编程

setTimeout( funciton() {console.log('hello world')
}, 1000);

在D3中存在大量类似调用

  • 将函数作为参数给图元
  • 为每个数据点指定不同颜色
  • 配置坐标轴

7 常用接口

模版字符串

let a = 10;
let myString = `abc-${a}`;
// myString最终为'abc-10'

数组 a = [1, 2, 3]
对象 a = {name: ‘Zane’, age: 24, lab: ‘cs’}
D3数据可视化常见对象数组

a = [{name:'Zane', age: 20, dept: 'cs'},{name:'LJD', age: 21, dept: 'cs'},{name: 'LH', age: 22, dept: 'ee'}]

数组排序 a.sort()
- 可以通过加入回调函数来替代缺省的排序方案,如为日期排序
- a.sort(function(a, b){ return new Date(b.date) - new Date(a.date); }
数组查询 a.find()
a.find( d => d.name === ‘Zane’)

将字符串转为数值 +(‘3.14’)
D3.js经常读取CSV,JSON等文件,涉及大量数组,对象操作

8 D3语法基础

使用D3获取,修改,增加以及删除节点(图元)
数据读取 - CSV
数值计算
比例尺:1. 线性比例尺 Linear Scale
2. 条带比例尺 Band Scale
坐标轴绘制: Margin
Data-Join基础
基于D3与Data-Doin绘制柱状图

9 使用D3查询SVG

d3.select(‘#rect1’) 永远返回第一个
d3.selectAll(‘.class1’) 返回所有
ID前加#,Class前加.,标签前不加

层级查询
d3.select(‘#maingroup rect’)
d3.select(‘.tick text’)
d3.selectAll(‘#secondgroup rect’)

10 使用D3设置SVG中属性

常见属性:

  • id, class (特殊属性,可使用.attr设置)
  • x, y, cx, cy (注意屏幕坐标系)
  • fill, stroke
  • height, width, r (圆的半径)
  • transform -> translate, rotate, scale

SVG的属性非常多,并且属性的取值范围和类型各不相同

  1. 尽可能记住常见的属性来提高编程速度
  2. 遇见不认识的or想要设置某个属一定要查阅文档

https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute

<rect id='rect3' class='class1' stroke='black' height='200' width='66' fill='#7289AB' x='300' y='-100'>

屏幕空间的坐标系与常见坐标系不同
左上方为原点
y,x分别垂直向下、水平向右

element.attr(…)
设置元素属性: element.attr(‘attr_name’, ‘attr_value’)

  • 两参数:属性名,属性值
  • rect1.attr(‘y’, ‘100’)
  • d3.select(‘#rect1’).attr(‘y’, ‘100’)

获取元素属性: element.attr(‘attr_name’)

  • 一参数: 属性名

链式调用:

  • selection.attr(…).attr(…).attr(…)
  • .attr(…)返回的是选择的图元本身

11 修改整组属性

DOM
父节点的属性会影响子节点
子节点的属性相对于父节点
以下代码可以直接移动组内的所有元素
d3.select(‘#maingroup’).attr(‘transform’, ‘translate(200, 100)’)

12 使用D3添加与删除SVG元素

  • element.append(…)

    • const myRect = svg.append(‘rect’);
    • const myRect = d3.select(‘#mainsvg’).append(‘rect’)
    • const myRect = d3.select(‘#mainsvg’).append(‘rect’).attr(‘x’, ‘100’)
  • D3的链式添加(调用)

    • const myRect = d3.select(‘#mainsvg’).append(‘g’).attr(‘id’, ‘maingroup’)
    • .append(‘rect’).attr(‘fill’, ‘yellow’)
  • element.remove()

    • 小心使用
    • 因为将移除整个标签
    • d3.select(‘#rect1’).remove()

在debug过程中可以使用’opacity’属性hack出移除效果

  • element.attr(‘opacity’, ‘0’)

13 数据读取 —— CSV数据

第一行是属性列表,后面每一行对应一条数据
CSV本质上是纯文本,区别于EXCEL格式

  • d3.csv(…):

    • 读取目标路径下的某一CSV文件
    • d3.csv(‘static/data/hello.csv’);
  • d3.csv是一个JavaScript异步函数:

    • 不可以直接获得其返回值
    • 不可以有 let myData = d3.csv(‘static/data/hello.csv’);
  • d3.csv(‘path/to/data.csv’).then( data => { // ‘数据读取后的代码逻辑’ } )

    • 需要通过.then( data => {…} )的方式获得读取后的数据
    • then(…)中的 data => {…} 是一个函数
    • 该函数接收的是输入参数,也即data,是读取后的数据
  • JavaScript异步机制

    • d3.csv是异步函数,即便没有读取完毕数据,后面的代码依旧继续执行
    • d3.csv被调用后的返回值是一个JavaScript的Promise对象(object)
    • Promise 询问:数据读取完毕后需要做什么,做什么即对应.then()中函数的内容

读取后的数据格式(接口)与原本的CSV结构不同

14 D3.js的数值计算

数据可视化常常涉及对数据的处理与计算
下面三个接口分别用于计算数组的最大值,最小值,[最小值, 最大值]

  • d3.max(array)

  • 返回数组中的最大值

  • d3.min(array)

  • 返回数组中的最小值

  • d3.extent(array)

  • 同时以数组的形式返回最小值与最大值

数组中的内容可以是任意对象

  • 每个对象可能包含多个属性
  • 具体需要那个属性的最值可以通过回调函数提示d3.max, d3.min与d3.extent

15 比例尺

比例尺用于将实际数据空间映射到屏幕(画布)空间,也即两个空间转化
用于映射数据和创建坐标轴,区别主要在于数据的尺度不同

Scale - Linear

d3.scaleLinear():

  • 定义一个线性比例尺,返回的是一个函数
  • 如 let scale = d3.scaleLinear(); // scale是函数

scale.domain([min_d, max_d]).range([min, max]):

  • 设置比例尺的定义域与值域
  • 线性比例尺的定义域和值域都是连续的(Continuous),需要给出最大值与最小值
  • const scale = d3.scaleLinear().domain([20, 80]).range([0, 120]);

比例尺本质上是函数

  • scale(20) // 0
  • scale(50) // 60

常常结合读取的数据与d3.max等接口连用

  • const xScale = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).range([0, innerWidth]);

Scale - Band

d3.scaleBand():

  • 定义一个条带比例尺,返回一个函数
  • let scale = d3.scaleBand();

scale.domain(array).range([min, max]):

  • 设置比例尺的定义域和值域
  • Band比例尺的定义域是离散的(Discrete),值域是连续的
  • 如 const scale = d3.scaleBand().domain([‘a’, ‘b’, ‘c’]).range([0, 120]);
  • 比例尺本质上是函数:
    • scale(‘b’) // 40
    • scale(‘c’) // 80

d3.scaleBand()常常结合JS的array.map接口一同使用:

  • let a = [{name: ‘Zane’, value: 6}, {name: ‘LiHao’, value: 7}, {name:‘Ljd’, value: 8}]
  • a.map(d => d.name) // [‘Zane’, ‘LiHao’, ‘Ljd’]
  • const yScale = d3.scaleBand()
  • .domain(data.map(d => d.name))
  • .range([0, innerHeight])
  • .padding(0.1)

scale.padding(0.1):
设置条带间距占各自区域的比重

scale.bandwidth():
返回条带长度

16 引入坐标轴

一个坐标轴为一个group,也即<g>
通常需要两个坐标轴

坐标轴中包含:

  • 一个<path>用于横跨坐标轴的覆盖范围
  • 若干个刻度.tick,每个刻度也是一个group
  • 每个刻度下属包含一个<line>和一个<text>
    • <line>用于展示轴线,如左到右或上到下
    • <text>用于展示刻度值,如实数,姓名,日期
  • (可选)一个标签用于描述坐标轴

坐标轴的定义需要比例尺

定义坐标轴(获得结果仍是函数)

  • const yAxis = d3.axisLeft(yScale);
  • const xAxis = d3.axisBottom(xScale);
  • axisLeft: 左侧坐标轴
  • axisBottom: 底侧坐标轴
  • 坐标轴的刻度对应比例尺的定义域
  • 坐标轴在画布的绘制对应比例尺的值域
  • 仅仅是对坐标轴的定义,没有绘制

绘制坐标轴

  • const yAxisGroup = g.append(‘g’).call(yAxis);
  • const xAxisGroup = g.append(‘g’).call(xAxis);
  • 实际配置后会发现<g>中增加了与坐标轴相关的元素

任何坐标轴在初始化之后会默认放置在坐标原点,需要进一步平移

关于 selection.call(…)

  • 函数的输入为另一个函数
  • 另一个函数以selection本身(也即图元)作为输入
  • 另一个函数将根据函数体的内容修改selection对应的图元
  • 定义一个空白的<g>,D3会帮助我们定义好另一个函数,我们通过.call(…)让<g>得以在另一个函数中修改
    • const yAxis = d3.axisLeft(yScale);
    • const yAxisGroup = g.append(‘g’).call(yAxis);

配置坐标轴
可以对坐标轴的风格进行修改

  • 坐标轴本质上是图元的集合
  • d3.selectAll(‘.tick text’).attr(‘font-size’, ‘2em’);
  • .tick是D3对于坐标轴定义的统一class

坐标轴的标签加入不在D3.Axis接口的负责范围内:

  • 通过对坐标轴的<g>标签.append(‘text’)来实现
  • 左(纵)轴坐标需要.attr(‘transform’, ‘rotate(-90)’)来旋转
  • 纵轴坐标旋转后,x/y会颠倒甚至取值范围相反
  • 回忆DOM: 父节点属性会影响子节点,而坐标轴默认的’fill’属性是’none’,因此请一定手动设置文字颜色.attr(‘fill’, ‘black’)

Margin
SVG对于D3.js是一个画布
SVG范围外的任何内容属于画布之外,浏览器不予显示

  • 而坐标轴通常初始化在所在父节点的左上角

定义Margin:

  • const margin = {top: 60, right: 30, bottom: 60, left: 200}

计算实际操作的inner长/宽

  • const innerWidth = width - margin.left - margin.right;
  • const innerHeight = height - margin.top - margin,.bottom;

在SVG下额外定义一个组作为新的根节点

- const g = svg.append('g').attr('id', 'maingroup')
.attr('transform', `translate(${margin.left}, ${margin.top})`)

HTML确实在样式表中提供margin属性,然而设置其他图元的位置,仍
需要计算innerWidth(Height)

调用示例

const yAxis = d3.axisLeft(yScale) // .tickSize(-innerWidth);
const xAxis = d3.axisBottom(xScale) // .tickSize(-innerHeight);const yAxisGroup = g.append('g').call(yAxis)
.append('text')
.text('Name')
.attr('font-size', '3em')
.attr('transform', 'rotate(-90)') // y-axis label needs an additional transform;
.attr('x', -innerHeight / 2)
.attr('y', -120)
.attr('fill', 'black')
const xAxisGroup = g.append('g').call(xAxis)
.attr('transform', `translate(${0}, ${innerHeight})`)
.append('text')
.text('Value')
.attr('font-size', '3em')
.attr('x', innerWidth / 2)
.attr('y', 50)
.attr('fill', 'black');d3.selectAll('.tick text).attr('font-size', '2em');g.append('text').text('Members of CSCG').attr('font-size', '3em')
.attr('x', innerWidth / 2 - 200).attr('y', -10)

17 DATA-JOIN

本质上是将数据与图元进行绑定
以数据为中心的可视化操作(Data-Driven)

  • 根据数据自动调整图元属性
  • .attr(…)接口可以基于图元自己绑定的数据自动调整属性值

数据发生变化时可以自动对图元增删改查

  • 不需要手动添加,修改,删除图元
  • 根据数据的增删改,自动增删改图元

d3.selectAll(‘.class’).data(dataArray)
dataArray在保证是数组的前提下可以是任何形式如数值数组,对象数组

。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/68960.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

opencv进阶02-在图像上绘制多种几何图形

OpenCV 提供了方便的绘图功能&#xff0c;使用其中的绘图函数可以绘制直线、矩形、圆、椭圆等多种几何图形&#xff0c;还能在图像中的指定位置添加文字说明。 OpenCV 提供了绘制直线的函数 cv2.line()、绘制矩形的函数 cv2.rectangle()、绘制圆的函数cv2.circle()、绘制椭圆的…

SQL-每日一题【1341. 电影评分】

题目 表&#xff1a;Movies 表&#xff1a;Users 请你编写一个解决方案&#xff1a; 查找评论电影数量最多的用户名。如果出现平局&#xff0c;返回字典序较小的用户名。查找在 February 2020 平均评分最高 的电影名称。如果出现平局&#xff0c;返回字典序较小的电影名称。 …

利用ViewModel和LiveData进行数据管理

利用ViewModel和LiveData进行数据管理 1. 引言 在当今移动应用开发的世界中&#xff0c;数据管理是一个至关重要的方面。随着应用的复杂性不断增加&#xff0c;需要有效地管理和维护应用中的数据。无论是从服务器获取数据、本地数据库存储还是用户界面的状态&#xff0c;数据…

openpnp - 吸嘴是否吸取了元件的检测

文章目录 openpnp - 吸嘴是否吸取了元件的检测概述笔记补充 - 2023/8/11有bug, 元件底部视觉检测有时检测不到正确的元件外形END openpnp - 吸嘴是否吸取了元件的检测 概述 设备本身调试好了, 现在进行试贴. 发现一个奇怪的问题, 不管是否吸嘴吸取到了元件, 都会往板子上贴元…

【Windows 常用工具系列 8 -- 修改鼠标光标(指针)大小和颜色的快速方法方法】

文章目录 修改方法 上篇文章&#xff1a;Windows 常用工具系列 7 – 禁用win10自带的微软输入法 修改方法 Win键 i 快捷键进入设置页面&#xff0c;然后输入光标... 就会跳出修改鼠标大小与光标颜色的选项。 Win键是在计算机键盘左下角Ctrl和Alt键之间的按键 根据自己的需求…

SQL | 排序检索的数据

3-排序检索的数据 使用order by语句排序检索到的数据。 3.1-排序数据 使用SQL语句返回一个数据表的列。 select prod_id from products; --------------------- | prod_name | --------------------- | 8 inch teddy bear | | 12 inch teddy bear | | 18 inch teddy bear |…

高并发数据抓取实战:使用HTTP爬虫ip提升抓取速度

又到每天一期学习爬虫的时间了&#xff0c;作为一名专业的爬虫程序员&#xff0c;今天要跟你们分享一个超实用的技巧&#xff0c;就是利用HTTP爬虫ip来提升高并发数据抓取的速度。听起来有点高大上&#xff1f;别担心&#xff0c;我会用通俗易懂的话来和你们说&#xff0c;让你…

【论文阅读】基于深度学习的时序预测——FEDformer

系列文章链接 论文一&#xff1a;2020 Informer&#xff1a;长时序数据预测 论文二&#xff1a;2021 Autoformer&#xff1a;长序列数据预测 论文三&#xff1a;2022 FEDformer&#xff1a;长序列数据预测 论文四&#xff1a;2022 Non-Stationary Transformers&#xff1a;非平…

【C++】stack容器

1.stack基本概念 英stk 美stk n.&#xff08;整齐的&#xff09;一堆&#xff1b;<英> 垛&#xff0c;堆&#xff1b;大量&#xff0c;许多&#xff1b;&#xff08;尤指工厂的&#xff09;大烟囱&#xff1b;&#xff08;图书馆的&#xff09;藏书架&#xff0c;双面书架…

C#字符串占位符替换

using System;namespace myprog {class test{static void Main(string[] args){string str1 string.Format("{0}今年{1}岁&#xff0c;身高{2}cm&#xff0c;月收入{3}元&#xff1b;", "小李", 23, 177, 5000);Console.WriteLine(str1);Console.ReadKey(…

科大讯飞星火模型申请与chatgpt 3.5模型以及new bing的对比

科大讯飞星火模型 申请科大讯飞星火认知大模型账号科大讯飞星火认知大模型使用1.界面介绍2. 在编程能力上与chatgpt 3.5对比科大讯飞星火模型chatgpt 3.5模型 3. 在图片生成能力上与new bing对比 总结 申请科大讯飞星火认知大模型账号 注册网址&#xff1a; 科大讯飞星火认知大…

【C++11保姆级教程】delete和default关键字

文章目录 前言一、delete关键字1.1 什么是delete关键字&#xff1f;1.2delete关键字的语法和用法1.3delete关键字的作用和优势 二、default关键字2.1 什么是default关键字&#xff1f;2.2default关键字的语法和用法2.3 default关键字的作用和优势 总结 前言 欢迎来到本教程&am…