数据可视化对比
- echarts
百度开源项目,学习门槛较低,国内应用领域十分广泛,apache孵化器,主要是修改配置options
缺点:定制性较差,代码复用率低,因为此类库封装程度已非常高,所以很难对其进一步抽象和封装。
- highCharts
学习可以,商用需要授权,09年发布,使用纯js编写的图表库。highCharts和echarts的区别类似于office和wps的区别。
- D3(Data-Driven Documents)
更接近底层,与 g2、echarts 不同,d3 能直接操作 svg,所以拥有极大的自由度,几乎可以实现任何 2d 的设计需求。
缺点:学习门槛较高,对用户的 web 技术、可视化理论、数学逻辑都一定要求。
导入依赖
- 本地导入(推荐)
<script src="./package/dist/d3.js"></script>
- 网络好得话,可以不用下载
<script src="https://d3js.org/d3.v7.min.js"></script>
选择器
在 D3 中,用于选择元素的函数有两个,这两个函数返回的结果称为选择集。
d3.select():选择所有指定元素的第一个
d3.selectAll():选择指定全部元素
例如,选择集的常见用法如下。
var body = d3.select("body"); //选择文档中的body元素
var p1 = body.select("p"); //选择body中的第一个p元素
var p = body.selectAll("p"); //选择body中的所有p元素
var svg = body.select("svg"); //选择body中的svg元素
var rects = svg.selectAll("rect"); //选择svg中所有的rect元素
var id = body.select("#id"); //选择body中id元素
var class = body.select(".class");//选择body中class类元素
与jQuery类似的链式操作:
d3.select("#container").text("lxc").attr("font-size","12px");
绑定数据
选择集和绑定数据通常是一起使用的,D3中是通过以下两个函数来绑定数据的:
- datum():绑定一个数据到选择集上
- data():绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定
假设现在有三个段落元素如下:
<body>
<p>张三</p>
<p>李四</p>
<p>王五</p>
</body>
- datum()
假设有一个字符串“China”,可将其分别与三个段落p元素绑定:
var str = "China";
var body = d3.select("body");
var p = body.selectAll("p");
p.datum(str);
p.text(function(d, i){
return i + ":" + d;
})
绑定数据后,使用此数据来修改三个段落元素的内容,其结果如下:
0:China
1:China
2:China
上面代码也用到了一个匿名函数 function(d, i),其对应的情况如下:
d ------- data 数据
i ------- index 索引
- data()
使用data绑定数据。有一个数组
var arr = ["a", "b", "c"]
分别将数组的各元素绑定到三个段落元素上。
绑定后,其对应关系为张三-a,李四-b,王五-c。
var arr = ["a", "b", "c"];
var body = d3.select("body");
var p = body.selectAll("p");
p.data(arr).text(function (d, i) {
return i + ':' + d;
})
// 0:a
// 1:b
// 2:c
选择、插入、删除元素
- 选择元素
<p>10</p>
<p>20</p>
<p>30</p>
选择第一个元素
d3.select("body").select("p").style("color","red");
选择所有元素
d3.select("body").selectAll("p").style("color","red");
使用id选择第二个元素
<p id="second">20</p>
d3.select("#second").style("color","red");
使用class选择后两个元素
<p class="myclass">Moon</p>
<p class="myclass">You</p>
由于需要选择多个元素,要用 selectAll。
d3.selectAll(".myclass").style("color","red")
- 插入元素
插入元素涉及的函数有两个:
- append()
在选择集末尾插入元素
- insert()
在选择集前面插入元素
<body>
<p>张三</p>
<p id="lable">李四</p>
<p>王五</p>
</body>
var body = d3.select("body");
// body.append("p").text("赵六");
// 在id为label的元素前插入文字
body.insert("p", "#label").text("insert here")
// 张三
// insert here
// 李四
// 王五
- 删除元素
d3.select("#second").remove();
动态设置元素属性
var datalist = [10, 20, 30]
container.selectAll('p').data(datalist).text((d, i) => {
return d;
}).style('color', (d, i) => {
if (d > 10) {
return 'red'
} else {
return 'blue'
}
}).style('font-size',(d, i)=>{
return d + 'px';
})
理解 update()、enter()、exit()
Update、Enter、Exit 是 D3 中三个非常重要的概念,数据绑定的时候可能出现 DOM 元素与数据元素个数不匹配的问题,那么 enter 和 exit 就是用来处理这个问题的。enter 操作用来添加新的 DOM 元素,exit 操作用来移除多余的 DOM 元素
- update()
当对应的元素正好满足时 ( 绑定数据数量 = 对应元素 ),实际上并不存在这样一个函数,只是为了要与之后的 enter 和 exit 一起说明才想象有这样一个函数。但对应元素正好满足时,直接操作即可,后面直接跟 text ,style 等操作即可。
- enter()
当对应的元素不足时 ( 绑定数据数量 > 对应元素),当对应的元素不足时,通常要添加元素,使之与绑定数据的数量相等。后面通常先跟 append 操作。
- exit()
当对应的元素过多时 ( 绑定数据数量 < 对应元素 ),当对应的元素过多时,通常要删除元素,使之与绑定数据的数量相等。后面通常要跟 remove 操作。
enter.png如果数组为 [3, 6, 9, 12, 15],将此数组绑定到三个 p 元素的选择集上。可以想象,会有两个数据没有元素与之对应,这时候 D3 会建立两个空的元素与数据对应,这一部分就称为 Enter。而有元素与数据对应的部分称为 Update。如果数组为 [3],则会有两个元素没有数据绑定,那么没有数据绑定的部分被称为 Exit。示意图如下所示。
在实际使用过程中,如果 SVG 里没有 rect 元素,即元素数量为 0。有一数组 dataset,将数组与元素数量为 0 的选择集绑定后,选择其 Enter 部分(请仔细看上图),然后添加(append)元素,也就是添加足够的元素,使得每一个数据都有元素与之对应。
svg.selectAll("rect") //选择svg内所有的矩形
.data(dataset) //绑定数组
.enter() //指定选择集的enter部分
.append("rect") //添加足够数量的矩形元素
一、Update和Enter的使用
<div>
<p></p>
<p></p>
<p></p>
</div>
var dataset = [3, 6, 9, 12, 15]
//选择body中的P元素
var p = d3.select('body').selectAll('p');
//获取update部分
var update = p.data(dataset);
//获取update部分,更新属性值
update.text(function (d) {
return "update " + d;
})
//获取enter部分
var enter = update.enter()
enter.append('p').text(function (d) {
return "enter " + d;
})
二、Update和Exit的使用
<div>
<p></p>
<p></p>
<p></p>
</div>
var dataset = [3]
//选择body中的P元素
var p = d3.select('body').selectAll('p');
//获取update部分
var update = p.data(dataset);
//获取update部分,更新属性值
update.text(function (d) {
return "update " + d;
})
//获取enter部分
var enter = update.enter()
enter.append('p').text(function (d) {
return "enter " + d;
})
var exit = update.exit()
exit.text(function (d) {
return "exit"
})
// exit.remove();
- min()和max()
下面的代码会循环数组中的每个 x 值,返回其中最大的那个
var dataset = [
[5, 20], [480, 90], [250, 50], [100, 33], [330, 95],
[410, 12], [475, 44], [25, 67], [85, 21], [220, 88]
];
let min = d3.min(dataset, function (d) {
return d[0]
})
let max = d3.max(dataset, function (d) {
return d[0]
})
console.log(min, max)//5,480
网友评论