页面设计图标浙江seo
参考:
【D3.js】基础教程-CSDN博客
https://blog.csdn.net/weixin_39085822/article/details/119755130
D3 by Observable | The JavaScript library for bespoke data visualization
https://d3js.org/
目录
- 安装
- 基础知识
- 选择元素
- 绑定数据
- 插入和删除元素
- 绘图
- 绑定数据的水平条形图
- 比例尺
- 坐标轴
d3的优点是比较底层,代码简洁,操作灵活(相比echarts)。
安装
去github下载最新包:https://github.com/d3/d3/releases
也可以引用:(目前最新是v7.9)
<!-- 压缩版本 -->
<script src="https://d3js.org/d3.v7.min.js"></script>
<!-- 完整版本 -->
<script src="https://d3js.org/d3.v7.js"></script>
基础知识
选择元素
// 选择所有指定元素的第一个
var body = d3.select("body"); //选择文档中的body元素
var svg = body.select("svg"); //选择body中的svg元素// 选择所有指定元素
var rects = svg.selectAll("rect"); //选择svg中所有的rect元素// 根据id选择元素,id前面要加#
var p2 = body.select("#pear-id");// 根据class选择元素,class名称前加.
var p = body.selectAll(".myclass");
绑定数据
datum()
是绑定一个数据,data()
是绑定一组数据。
// 选中body下所有的p元素
var body = d3.select("body");
var p = body.selectAll("p");// datum()
var str = "World";
// 把数据绑定到选择集上
p.datum(str);
// 把选择集的每个p元素的text属性(文字内容)都改成str
// function(d, i)是一个无名函数,d是数据,i是index
// 因为datum只绑了一个数据,所以所有的d都是World
p.text(function(d, i){return "第 "+ i + " 个元素绑定的数据是 " + d;
});// data()
var dataset = ["I like dog","I like cat","I like snake"];
p.data(dataset).text(function(d, i){return d;}); // 这样3个p元素会依次显示对应的字符串
插入和删除元素
// 在末尾增加元素
body.append("p").text("append p element");// 在某个元素之前增加元素,需要id
body.insert("p","#pear-id") // 在pear-id元素前增加一个p元素.text("insert p element"); // 指定p元素的内容// 删除元素需要指定id
var p = body.select("#pear-id");
p.remove();
绘图
绑定数据的水平条形图
代码:
<svg width="1000" height="1000"></svg><script src="https://d3js.org/d3.v7.min.js"></script><script>var dataset = [ 250 , 210 , 170 , 130 , 90 ]; //数据(表示矩形的宽度)var rectHeight = 25; //每个矩形所占的像素高度(包括空白)const svg = d3.select("svg"); // 选择svg元素svg.selectAll("rect") // 选择所有矩形.data(dataset) // 绑定数组.enter().append("rect") // 添加足够数量的矩形元素.attr("x", 20) // 矩形的x坐标设为20,左上顶点的坐标.attr("y", function(d, i){ // d代表数据,i是索引return i * rectHeight;}).attr("width",function(d){ // d其实是dataset里每个数据return d;}).attr("height",rectHeight - 2).attr("fill","steelblue"); // 颜色</script>
关于enter()
的说明:
d3在处理数据集和选择集(待绑定的元素)数量不符合的情况时提出了3个概念,分别是enter
、update
和exit
。
假设选择集是3个p元素,
- 当数据集也是3个数据时,这3个p元素称为
update
,update
可以更新属性值; - 当数据集有5个元素时,会有2个数据绑定不上,此时d3会建立两个空元素与数据对应,这俩空的就是
enter
。所以enter()
后可以跟append
去添加元素; - 当数据集只有1个元素时,另外俩元素没有数据绑定,被称为
exit
,此时可以修改属性,但是大部分时候都是要删除它。进入的方法跟.enter()
一样,就是比如.exit().remove()
。
比例尺
d3中引入比例尺可以更容易地放缩图形,不必写死像素数目。在数学中,x的范围是定义域,y的范围是值域,d3中对应的是domain和range,我们需要指定这俩。
- 线性比例尺
就是将domain等比例地映射到range。
var dataset = [1.2, 2.3, 0.9, 1.5, 3.3];
var min = d3.min(dataset); // 最小值
var max = d3.max(dataset); // 最大值var scaleLinear = d3.scaleLinear().domain([min, max]).range([0, 300]);
scaleLinear(0.9); //返回 0. 闭区间的
scaleLinear(2.3); //返回 175
scaleLinear(3.3); //返回 300
上面水平条形图可以用scaleLinear()修改,效果是一样的。
- 序数比例尺
domain和range是离散的情况,使用序数一一对应。
var index = [0, 1, 2, 3, 4];
var color = ["red", "blue", "green", "yellow", "black"];
var scaleOrdinal = d3.scaleOrdinal().domain(index).range(color);
scaleOrdinal (0); //返回 red
scaleOrdinal (2); //返回 green
坐标轴
直接用实例。效果如下:
<svg width="500" height="300"></svg><script>// 1. 定义 SVG 画布的宽度和高度const width = 500;const height = 300;const margin = { top: 20, right: 20, bottom: 30, left: 40 };// 2. 创建一个线性比例尺,用于将数据映射到 SVG 画布的宽度const xScale = d3.scaleLinear() .domain([0, 10]) // 数据范围.range([margin.left, width - margin.right]); // 画布范围// 3. 创建一个比例尺,用于将数据映射到 SVG 画布的高度const yScale = d3.scaleLinear().domain([0, 100]) // 数据范围.range([height - margin.bottom, margin.top]); // 画布范围// 4. 创建 X 轴生成器const xAxis = d3.axisBottom(xScale);// 5. 创建 Y 轴生成器const yAxis = d3.axisLeft(yScale);const svg = d3.select("svg");// 6. 选择 SVG 元素并添加 X 轴svg.append("g").attr("transform", `translate(0, ${height - margin.bottom})`) // 将 X 轴移动到画布底部.call(xAxis);// 7. 选择 SVG 元素并添加 Y 轴svg.append("g").attr("transform", `translate(${margin.left}, 0)`) // 将 Y 轴移动到画布左侧.call(yAxis);</script>
说明:
- d3提供4种坐标轴生成器:
d3.axisBottom(scale)
是刻度向下的,d3.axisLeft()
是刻度向左的,d3.axisTop()
和d3.axisRight()
同理 - 坐标轴默认是从(0, 0)点开始绘制的,所以需要移动
.attr("transform", "translate(x, y)")
表示平移svg元素,x
和y
表示在x轴和y轴移动的距离call()
是将当前选择集作为参数传递给一个函数,所以svg.append("g").call(xAxis)
就是将x轴生成器应用到g元素上(等价于xAxis(svg.append(g))
)- 如果要修改axis的格式,可以在
<style>
里定义,然后引用,比如下面这种:
<style>.axis path,.axis line{fill: none;stroke: black;shape-rendering: crispEdges;}.axis text {font-family: sans-serif;font-size: 11px;}</style>...
<script>
//添加y轴
svg.append("g").attr("class","axis") // 这句.attr("transform", `translate(${margin.left}, 0)`).call(yAxis);
</script>