数据可视化D3&SVG学习笔记

245 阅读10分钟

「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战」。

数据可视化

什么是数据可视化

近年来,可视化越来越流行,许多报刊杂志、门户网站、新闻、媒体都大量, 使用可视化技术,使得复杂的数据和文字变得十分容易理解,有一句谚语, “一张图片价值于一千个字”,的确是名副其实。各种数据可视化工具也如井喷式地发, d3JS 正是其中的佼佼者。

为什么学习数据可视化

例如: 这里有一个数组, 请马上找出最大值的位置在哪里: [4 , 32 , 15 , 16 , 42 , 25]

d3

什么是d3

D3 的全称是(Data-Driven Documents), 是一个可以基于数据来操作文档的 JavaScript 库。可以帮助你使用 HTML, CSS, SVG 以及 Canvas 来展示数据。D3 遵循现有的 Web 标准,可以不需要其他任何框架独立运行在现代浏览器中,它结合强大的可视化组件来驱动 DOM 操作

d3的优势

例如: 原生DOM修改p标签 var pList = document.getElementsByTagName("p"); for (var i = 0; i < pList.length; i++) {    var theP = pList[i]; } 例如: d3实现上面同样的效果  theP.style.color = "red"; d3.selectAll("p").style("color", "red");

d3的标签使用

select_标签获取

注意: 获取的每个结果都是一个数组, 而且所有d3的方法和属性, 都会自动进行遍历

  • d3.selection() : 选择器根元素, 相当于 document.documentElement , 获取html标签
  • d3.select(): 获取符合选择器的 第一个元素
  • d3.selectAll(): 获取符合选择器的 所有元素
  • d3.select(".my_two").selectAll("span"); 选择一个元素后, 再选取它下面所有标签

select_相关方法

  • d3.selectAll().filter(函数): 过滤, 选中的标签集合中符合条件的元素, 函数this代表集合中每个元素标签, 要return索引值, 就会在filter调用后的结果中筛选出来的元素结果
    • 注意: 因为函数里面要使用this来指向标签, 所以不要使用箭头函数
  • d3.select().style(样式名, 值): 选中标签后, 获取它身上的样式的值, 千万注意, CSS属性名不要驼峰标示,如果不给值是获取样式, 如果给值了, 则是设置样式
  • d3.select().attr(属性名, 值): 如果只给属性名, 则获取属性的值, 如果都给了, 就是赋值
  • d3.selectAll().classed("my_three_p", false); 第二个参数为true, 则添加, 为false, 则移除
  • d3.selectAll(".my_five>p").html(); 获取第一个非空内容标签的, innerHTML的值, 写内容就是赋值(多个)
  • d3.selectAll().each() 遍历集合, 拿到里面的每个元素, this就代表每个元素
  • d3.selectAll().append(); 可以传入要添加的标签名/函数, 在函数中返回DOM结构
  • d3.selectAll().remove() 删除选中的结合中, 每个标签

标签和数据绑定

  • d3.selectAll().data(); 把标签集合和data中的数组中的每个元素绑定在一起, 页面没什么变化, 但是会在标签上扩展属性data指向数据
  • d3.selectAll.data().html(): html中还可以接受一个内置函数, 函数中第一个参数, 就是绑定的数据
  • d3.selectAll.data().enter(): 数据个数大于元素个数的占位符.enter()只是进行选择,并未实际添加所需DOM元素。因此在enter()之后一般都会配合append()来进行DOM元素的实际创建。
  • enter()后面的append() 会加在前面选择器的子元素中, 所以注意开头的选择器是谁
  • d3.selectAll().data().exit(): 跟enter相反, 获取多余的元素的选择集(数据个数小于元素个数).
    • 一般配合remove()使用, 直接在后面调用remove()方法即可
  • d3.selectAll().datum(): data接收数组, 这个接收对, 不进行数据与元素个数的对比, 用于给标签扩展属性(但是不是明显的向data绑定属性)

事件使用

  • on() 绑定事件, 多个事件用空格隔开
  • d3.event, 代表当前触发事件的 ,事件对象

注意: 可以使用d3.select(this), 把原生的标签, 转换成d3的对象, (类似于JQ里的$(this))

d3的工具使用

比例尺的使用

比例尺就是把一组输入域映射到输出(值)域的函数。映射就是两个数据集之间元素相互对应的关系。比如输入是1,输出是100,输入是5,输出是10000,那么这其中的映射关系就是你所定义的比例尺。

  • 线性比例尺

d3.scaleLinear().domain([1, 5]).range([0, 100]); domain()是输入域,range()是输出域

例如:

let linear = d3.scaleLinear().domain([1, 5]).range([0, 100]); linear(2); // 25

输入域: [范围, 范围] 输出域: [范围, 范围]

  • 恒等比例尺

d3.scaleIdentity().domain([10, 50]).range([10, 50]); 输入域和输出域是完全一致的

例如:

let identiy = d3.scaleIdentity().domain([10, 50]); console.log(identiy(20));

输入域: [范围, 范围] 输出域: 跟上面一致

  • 序数比例尺

d3.scaleOrdinal().domain(["jack", "rose", "john"]).range([10, 20, 30]); , 每个输入域, 对应序号对应的值域

例如:

let ordi = d3.scaleOrdinal().domain(["jack", "rose", "john"]).range([10, 20, 30]); console.log(ordi("john")) 输入域: [值1, 值2, 值3] 输出域: [出1, 出2, 出3]

  • 序数比例尺(临界值)

d3.scaleBand().domain([1, 2, 3, 4, 5]).range([0,100]): , 输入域对应输出域的每个左边临界点

例如:

let band = d3.scaleBand().domain([1, 2, 3, 4]).range([0, 100]); console.log(band(2)) 输入域: [值1, 值2, 值3, 值4] 输出域: [范围, 范围] (不包括最大范围)

  • 点坐标比例尺

d3.scalePoint().domain([0, 1, 2, 3, 4]).range([0, 500]) 获取每个点的坐标 例如:

 let x = d3.scalePoint().domain([0, 1, 2, 3, 4]).range([0, 500]); console.log(x(0)) 输入域: [值1, 值2, 值3, 值4, 值5] 输出域: [范围, 范围] (值5对应最后的范围)

d3动画使用

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

  • d3.select("body").transition().style("background-color", "red") 过渡动画到另外一个样式状态
  • d3.select("body").transition().duration(3000).style("background-color", "red") 设置动画持续时间
  • d3.select("body").transition().delay(2000).duration(3000).style("background-color": "red") 动画延迟2秒以后执行

SVG

SVG的简介

SVG是一种可缩放矢量图形(英语:Scalable Vector Graphics,SVG)是基于可扩展标记语言(XML),用于描述二维矢量图形的图形格式。它是图形的另一种格式, 它和常见的图片格式.png、.jpg、.gif等是一类。用户可以直接用代码来描绘图像

示例: www.subway.com.cn/development… (加盟流程->联系加盟)

SVG对比图片

  1. 可以任意放大图形显示,但绝不会以牺牲图像质量为代价
  2. 可在SVG图像中保留可编辑和可搜寻的状态
  3. 比JPEG和GIF格式的文件要小很多,因而下载也很快 (从服务器, 下载到浏览器)

SVG对比字体样式图标

  1. 可以随意修改某一块颜色信息, 而iconFont只能是单一颜色
  2. 可读性比iconFont强很多, iconFont都是unicode编码
  3. 放大后, iconFont有锯齿, 而svg锯齿不明显

SVG使用

教程地址: www.w3school.com.cn/svg/svg_rec…

SVG标签介绍

  1. svg默认大小 300*150, 可以设置宽高
  2. svg标签类似于canvas, 指的绘制区域标签 3. 每个svg内的图形坐标, 相对于当前所在的svg标签的左上角为原点进行计算

矩形绘制

  • fill: rgb(0,0,255) 填充颜色 (默认是黑色)
  • fill-opacity: 0.9 填充透明度
  • stroke: rgb(0,0,0) 描边的颜色
  • stroke-width: 10 描边的宽度
  • stroke-opacity: 0.9 描边的透明度
  • x: 矩形左上角的x坐标
  • y: 矩形左上角的y坐标
  • width: 矩形的宽度
  • height: 矩形的高度

圆形绘制

  • cx: 100 圆心所在x坐标
  • cy: 100 圆心所在y坐标
  • r: 50 圆的半径

椭圆绘制

  • cx: 100 圆心所在x坐标
  • cy: 100 圆心所在y坐标
  • rx: 100 横向圆的半径
  • ry: 50 纵向圆的半径

线段绘制

  • x1: 0 起点x坐标
  • y1: 0 起点y坐标
  • x2: 200 终点x坐标
  • y2: 200 终点y坐标

注意: 需要给颜色(默认是transparent色)

多边形绘制

  • 注意: 不能少于3个边(所以最少是3个点)
  • points: "220,100 300,210 170,250" (每一对x, y)组成, 中间空格隔开

折线绘制

  • 注意, 每个点之间会连接一条直线
  • points: "0,0 0,20 20,20 20,40 40,40 40,60" (每一对x, y)组成,
  • 会自动填充相邻点包裹的区域, 我们可以设置填充颜色为背景色, 即可只查看线段颜色

路径绘制

  • d: "M250 150 L150 350 L350 350 Z" (每一对都用空格隔开)
  • 路径配置的参数数据如下:
    • M = moveto 将画笔移动到指定坐标
    • L = lineto 画直线到指定坐标
    • H = horizontal lineto 画水平直线到指定坐标
    • V = vertical lineto 画垂直直线到指定坐标
    • C = curveto 画三阶贝塞尔曲线经两个指定控制点到达终点坐标
    • S = smooth curveto 与前一条贝塞尔曲线相连,控制点为前一条二阶贝塞尔曲线控制点的对称点,只需输入第二个控制点和终点,即可绘制一个三阶贝塞尔曲线。
    • Q = quadratic Belzier curve 画二阶贝塞尔曲线经一个指定控制点到达终点坐标
    • T = smooth quadratic Belzier curveto 与前一条二阶贝塞尔曲线相连,控制点为前一条二阶贝塞尔曲线控制点的对称点,只需输入终点,即可绘制一个二阶贝塞尔曲线
    • A = elliptical Arc 画椭圆曲线到指定坐标
    • Z = closepath 绘制一条直线链接终点和起点,用来封闭图形

文字绘制

文字

  • x: 绘制文字起点x坐标
  • y: 绘制文字起点y坐标
  • 注意: 因为文字baseline以底部对齐, 所以文字以左下角为起点

分组控制

  • 没有实际意义, 用于在svg里分快, 嵌套以上的标签

echarts

echarts.baidu.com/

简介

ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖轻量级的矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制数据可视化图表。

使用

教程: echarts.baidu.com/tutorial.ht…

  1. 引用资源
  2. 为 ECharts 准备一个具备大小(宽高)的 DOM
  1. 基于准备好的dom,初始化echarts实例

var myChart = echarts.init(document.getElementById('main'))

  1. 指定图表的配置项和数据

参考配置: echarts.baidu.com/option.html…

  1. 使用刚指定的配置项和数据显示图表

myChart.setOption(option)

注意

准备好数据, 放入对应的配置项中, 多查文档多看文档即可

Highcharts

www.highcharts.com.cn/

简介

Highcharts 是一个用纯 JavaScript 编写的一个图表库, 能够很简单便捷的在 Web 网站或是 Web 应用程序添加有交互性的图表,并且免费提供给个人学习、个人网站和非商业用途使用。Highcharts 支持的图表类型有直线图、曲线图、区域图、柱状图、饼状图、散状点图、仪表图、气泡图、瀑布流图等多达 20 种图表,其中很多图表可以集成在同一个图形中形成混合图

使用

  1. 引入资源
  1. 准备容器DOM标签

id="container" style="width: 600px;height:400px;">

  1. 指定配置项和数据

api.highcharts.com.cn/highcharts

  1. 配置绑定数据项

Highcharts.chart('container', options)

其他资料

官方文档(英文)

d3js.org/

中文文档

d3js.org.cn/

方法和中文对照: github.com/d3/d3/wiki/…中文手册

贝塞尔曲线可视化

cubic-bezier.com/

SVG可视化编辑器

c.runoob.com/more/svgedi…

HTMLCollection和NodeList比较

相同点

  1. 都是类数组对象,都有length属性
  2. 都可以用索引值, 拿到集合中的每个元素
  3. HTMLCollection 会实时变动, NodeLIst 是不会实时变动

区别

  1. NodeList可以包含任何节点类型,HTMLCollection只包含元素节点(elementNode),elementNode就是HTML中的标签
  2. HTMLCollection比NodeList多一项方法:namedItem,可以通过传递id或name属性来获取节点信息

使用

document.getElementsByTagName("span") 获取的结果是HTMLCollection

document.querySelectorAll(".my_one>span") 获取的结果是 NodeList