【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.rhkb.cn/news/91573.html

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

相关文章

13.3 目标检测和边界框

锚框的计算公式 假设原图的高为H,宽为W 详细公式推导 以同一个像素点为锚框&#xff0c;可以生成 (n个缩放 m个宽高比 -1 )个锚框 锚框的作用&#xff1a; 不用直接去预测真实框的四个坐标&#xff0c;而是&#xff1a; 1.先生成多个锚框。 2.预测每个锚框里是否含有要预测…

【11】Redis学习笔记 (微软windows版本)【Redis】

注意:官redis方不支持windows版本 只支持linux 此笔记是依托微软开发windows版本学习 一、前言 Redis简介&#xff1a; Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的内存数据结构存储系统&#xff0c;它也被称为数据结构服务器。Redis以键值对&am…

使用Python统计字符内容的占比

说明&#xff1a;如果有自己动手做过字符动画&#xff0c;会知道字符动画的“灵动性”核心在于使用的字符集。 简单来说&#xff0c;动画转为字符动画&#xff0c;原理是将动画转为灰阶图&#xff0c;灰度范围是0~255&#xff0c;然后将对应灰度的像素点转为对应比值的字符。这…

轻松抽象JavaScript

上一期说了伪随机方法中有一个问题&#xff0c;那就是如何得到0.1这个值 理论上是可以的&#xff0c;但是实践缺有很大区别 大海捞针可信吗&#xff1f;可行吗&#xff1f; 当然可行&#xff0c;也可行&#xff0c;用一块超级大磁铁&#xff0c;磁力拉满&#xff0c;而且还具…

【论文阅读】基于深度学习的时序预测——Non-stationary Transformers

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

web-js

<html><head><title>基本语法</title></head><body><script>// window.alert("js");// document.write("js");// console.log("js");// function add(a,b){// return ab;// }var result functio…

商城-学习整理-高级-全文检索-ES(九)

目录 一、ES简介1、网址2、基本概念1、Index&#xff08;索引&#xff09;2、Type&#xff08;类型&#xff09;3、Document&#xff08;文档&#xff09;4、倒排索引机制4.1 正向索引和倒排索引4.2 正向索引4.3 倒排索引 3、相关软件及下载地址3.1 Kibana简介3.2 logstash简介…

【Go语言】go_session(超级详细)

目录 前言附件代码审计Index函数Admin函数Flask函数server.py问题 思路本地搭建环境admin绕过SaveUploadedFile方法payload 总结 前言 国赛初赛有一道题目go session&#xff0c;用go的Gin框架和pongo2模板引擎写的&#xff0c;是关于go的pongo2模板注入和flask的热加载&#…

分布式 - 服务器Nginx:一小时入门系列之代理缓冲与缓存

官方文档&#xff1a;https://nginx.org/en/docs/http/ngx_http_proxy_module.html 1. 代理缓冲 proxy_buffer 代理缓冲用于临时存储从后端服务器返回的响应数据。通过使用代理缓冲&#xff0c;Nginx可以在接收完整的响应后再将其发送给客户端&#xff0c;从而提高性能和效率…

智谷星图赵俊:让人才和区块链产业“双向奔赴”丨对话MVP

区块链产业需要什么样的人才&#xff1f;赵俊很有发言权。 赵俊是北京智谷星图科技有限公司的技术总监&#xff0c;也是FISCO BCOS官方认证讲师。他2017年接触区块链&#xff0c;随后选择人才培育领域深耕。“为区块链行业引进更多人才这件事很有价值&#xff0c;跟我的职业理…

【Java转Go】快速上手学习笔记(一)之环境安装篇

前言 前两天开始学习Go&#xff0c;需要写篇笔记记录总结一下。 Go它也是可以做web开发的&#xff0c;就像Java一样&#xff0c;做JavaWeb项目&#xff0c;Go也可以做GoWeb项目。当然Go的作用用处肯定不止这个&#xff0c;还有很多&#xff0c;只是因为我目前的话&#xff0c…

C进阶(2/7)前篇——指针进阶

前言&#xff1a;本文章讲解部分指针进阶内容。后续继续更新。 文章重点&#xff1a; 1. 字符指针 2. 数组指针 3. 指针数组 4. 数组传参和指针传参 目录 前言&#xff1a;本文章讲解部分指针进阶内容。后续继续更新。 指针初阶了解&#xff1a; 1.字符指针 1.1一道有关于字…

大模型基础:GPT家族与提示学习

大模型基础:GPT 家族与提示学习 从 GPT-1 到 GPT-3.5 GPT(Generative Pre-trained Transformer)是 Google 于2018年提出的一种基于 Transformer 的预训练语言模型。它标志着自然语言处理领域从 RNN 时代进入 Transformer 时代。GPT 的发展历史和技术特点如下: GPT-12018年6月…

java面试基础 -- 方法重载 方法重写

目录 重载 重写 重载 方法的重载是指在同一个类中定义多个方法, 他们具有相同的名称, 但是具有不同的参数列表, 例如: public void myMethod(int arg1) {// 方法体 }public void myMethod(int arg1, int arg2) {// 方法体 }public void myMethod(String arg1) {// 方法体 }…

软硬件免费,服务收费:网络安全商业模式正在被颠覆

大数据产业创新服务媒体 ——聚焦数据 改变商业 从元宇宙到造汽车&#xff0c;重回国内A股市场五年的360一路苦追热点。一直到大模型横空出世&#xff0c;360才算真正找到感觉&#xff0c;经历一次战略上的回归。 在8月9日的互联网安全大会上&#xff0c;一袭红衣的红衣教主周…

财务数据分析之现金流量表模板分享

现金流量表是我们常说的财务数据分析三表之一。它可以呈现一个企业的现金流情况&#xff0c;揭示企业经营管理健康状态&#xff0c;但在实际使用中却有总给人一种用不上、用不好的矛盾感。怎么才能把现金流量表做好&#xff1f;不如借鉴下大神的现金流量表模板。 下面介绍的是…

Docker 本地镜像发布到私有仓库

1. 本地镜像发布到私有库流程 2. 是什么 1 官方Docker Hub地址&#xff1a;https://hub.docker.com/&#xff0c;中国大陆访问太慢了且准备被阿里云取代的趋势&#xff0c;不太主流。 2 Dockerhub、阿里云这样的公共镜像仓库可能不太方便&#xff0c;涉及机密的公司不可能提供镜…

基于Gradio的GPT聊天程序

网上很多别人写的&#xff0c;要用账号也不放心。就自己写了一个基于gradio的聊天界面&#xff0c;部署后可以本地运行。 特点&#xff1a; 可以用openai的&#xff0c;也可以用api2d&#xff0c;其他api可以自己测试一下。使用了langchain的库 可以更改模型&#xff0c;会的…

使用插件实现pdf,word预览功能

效果 代码&#xff1a; 插件地址&#xff1a; https://github.com/501351981/vue-office <a-modalv-model:visible"visible":title"title"ok"handleOk":bodyStyle"bodyStyle":width"1200":maskClosable"false"…

MySQL卸载并重装指定版本

MySQL卸载并重装制定版本 学习新的项目&#xff0c;发现之前的Navicat已经失去了与现有MySQL的链接&#xff0c;而且版本也不适合&#xff0c;为了少走弯路&#xff0c;准备直接重装相应版本的MySQL 卸载现有MySQL 停止windows的MySQL服务&#xff0c;【windowsR】打开运行框…