淘先锋技术网

首页 1 2 3 4 5 6 7

教程链接:data visualization with d3(freecodecamp.org)

1. 思维导图

在这里插入图片描述

2. 基础

2.1 select

选择一个DOM元素,const anchor = d3.select("a");
用法同document.querySelector()

2.2 selectAll

选择一组DOM元素,用法同document.querySelectorAll()

2.3 append

在选择的元素里添加新的DOM元素,返回新元素

2.4 text

返回结点文本或者设置结点文本,参数是字符串或者回调函数

d3.select("ul")
  .append("li")
  .text("Very important item");

2.5 data

将数据附加到选中的DOM元素

2.6 enter

为数据集中的每个数据创建一个新元素,当选中的DOM元素个数少于数据个数时,enter会创建缺少的元素

<body>
  <ul></ul>
  <script>
    const dataset = ["a", "b", "c"];
    d3.select("ul").selectAll("li")
      .data(dataset)
      .enter()
      .append("li")
      .text("New item");
  </script>
</body>

此处enter方法检查数据集并运行后面的代码三次,也就是对数组中的每个项运行一次

2.7 style

style方法能添加行内css样式,参数是逗号分隔的键值对或回调函数

selection.style("property", (d, i) => {
  /* 
  * d is the data point value
  * i is the index of the data point in the array
  */
});

参数i可以省略

2.8 attr

attr方法给元素添加html属性,包括class,用法同style

selection.attr("property", (d, i) => {
  /* 
  * d is the data point value
  * i is the index of the data point in the array
  */
})

参数i可以省略

2.9 示例

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];

    const w = 500;
    const h = 100;

    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);

    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => h - 3 * d)
       .attr("width", 25)
       .attr("height", (d, i) => 3 * d)
       .attr("fill", "navy");
  </script>
<body>

在这里插入图片描述

3. 进阶

3.1 labels

使用svg的text节点向图标中添加标签

3.2 hover effect

使用attr方法和css的:hover伪类实现悬停效果

3.3 tooltip

使用svg的title节点添加提示
SVG绘图中的每个窗口元素或图形元素都可以提供一个title描述性字符串,该描述只能是纯文本。如果当前的SVG文档片段在可视媒体中呈现为SVG,title元素不会呈现为绘图的一部分。然而,一些用户代理可能会,举个例子,把title显示为一个提示冒泡。

3.4 示例

<style>
	.bar:hover {
	fill: brown;
}
</style>
<body>
	<script>
		const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
		
		const w = 500;
		const h = 200;
		
		const svg = d3.select("body")
					  .append("svg")
					  .attr("width", w)
					  .attr("height", h);
		
		svg.selectAll("rect")
		   .data(dataset)
		   .enter()
		   .append("rect")
		   .attr("x", (d, i) => i * 30)
		   .attr("y", (d, i) => h - 3 * d)
		   .attr("width", 25)
		   .attr("height", (d, i) => d * 3)
		   .attr("fill", "navy")
		   .attr("class", "bar")
		   .append("title")
		   .text((d) => d)
		
		svg.selectAll("text")
		   .data(dataset)
		   .enter()
		   .append("text")
		   .text((d) => d)
		   .attr("x", (d, i) => i * 30)
		   .attr("y", (d, i) => h - (d * 3 + 3))
		
	</script>
</body>

在这里插入图片描述

3.5 scatter plot

使用svg的cicle节点画点

3.6 示例

<body>
	<script>
		const dataset = [
				[ 34, 78 ],
				[ 109, 280 ],
				[ 310, 120 ],
				[ 79, 411 ],
				[ 420, 220 ],
				[ 233, 145 ],
				[ 333, 96 ],
				[ 222, 333 ],
				[ 78, 320 ],
				[ 21, 123 ]
			];
		
		const w = 500;
		const h = 500;
		
		const svg = d3.select("body")
					  .append("svg")
					  .attr("width", w)
					  .attr("height", h);
		
		svg.selectAll("circle")
		   .data(dataset)
		   .enter()
		   .append("circle")
		   .attr("cx", (d, i) => d[0])
		   .attr("cy", (d, i) => h - d[1])
		   .attr("r", 5);
		
		svg.selectAll("text")
		   .data(dataset)
		   .enter()
		   .append("text")
		   .text((d) => "" + d[0] + ", " + d[1])
		   .attr("x", (d) => d[0] + 5)
		   .attr("y", (d) => h - d[1])
	</script>
</body>

在这里插入图片描述

3.7 Scales

Scales函数将一组原始数据点映射到SVG画布的像素上

3.7.1 scaleLinear

scaleLinear用于定量数据

3.7.2 domain, range

domain 和 range 分别设置输入输出的数据范围

// Set a domain
// The domain covers the set of input values
scale.domain([50, 480]);
// Set a range
// The range covers the set of output values
scale.range([10, 500]);
scale(50) // Returns 10
scale(480) // Returns 500
scale(325) // Returns 323.37
scale(750) // Returns 807.67

3.7.3 min, max

min和max 分别找出数据集中的最小值和最大值

const exampleData = [34, 234, 73, 90, 6, 52];
d3.min(exampleData) // Returns 6
d3.max(exampleData) // Returns 234
const locationData = [[1, 7],[6, 3],[8, 3]];
// Returns the smallest number out of the first elements
const minX = d3.min(locationData, (d) => d[0]);// minX compared 1, 6, and 8 and is set to 1

3.8 示例

<body>
	<script>
		const dataset = [
				[ 34, 78 ],
				[ 109, 280 ],
				[ 310, 120 ],
				[ 79, 411 ],
				[ 420, 220 ],
				[ 233, 145 ],
				[ 333, 96 ],
				[ 222, 333 ],
				[ 78, 320 ],
				[ 21, 123 ]
			];
		
		const w = 500;
		const h = 500;
		const padding = 60;
		
		const xScale = d3.scaleLinear()
						 .domain([0, d3.max(dataset, (d) => d[0])])
						 .range([padding, w - padding]);
		
		const yScale = d3.scaleLinear()
						 .domain([0, d3.max(dataset, (d) => d[1])])
						 .range([h - padding, padding]);
		
		const svg = d3.select("body")
					  .append("svg")
					  .attr("width", w)
					  .attr("height", h);
		
		svg.selectAll("circle")
		   .data(dataset)
		   .enter()
		   .append("circle")
		   .attr("cx", (d) => xScale(d[0]))
		   .attr("cy", (d) => yScale(d[1]))
		   .attr("r", 5)
		
		svg.selectAll("text")
		   .data(dataset)
		   .enter()
		   .append("text")
		   .text((d) => (d[0] + ", "+ d[1]))
		   .attr("x", (d) => xScale(d[0] + 10))
		   .attr("y", (d) => yScale(d[1]))
		
	</script>
</body>

在这里插入图片描述

3.9 axes

axesLeft()生成 y 轴
axesBottom()生成 x 轴

const xAxis = d3.axisBottom(xScale);

svg.append("g")
   .attr("transform", "translate(0, " + (h - padding) + ")")
   .call(xAxis);

3.10 示例

<body>
	<script>
		const dataset = [
				[ 34, 78 ],
				[ 109, 280 ],
				[ 310, 120 ],
				[ 79, 411 ],
				[ 420, 220 ],
				[ 233, 145 ],
				[ 333, 96 ],
				[ 222, 333 ],
				[ 78, 320 ],
				[ 21, 123 ]
			];
		
		const w = 500;
		const h = 500;
		const padding = 60;
		
		const xScale = d3.scaleLinear()
						 .domain([0, d3.max(dataset, (d) => d[0])])
						 .range([padding, w - padding]);
		
		const yScale = d3.scaleLinear()
						 .domain([0, d3.max(dataset, (d) => d[1])])
						 .range([h - padding, padding]);
		
		const svg = d3.select("body")
					  .append("svg")
					  .attr("width", w)
					  .attr("height", h);
		
		svg.selectAll("circle")
		   .data(dataset)
		   .enter()
		   .append("circle")
		   .attr("cx", (d) => xScale(d[0]))
		   .attr("cy",(d) => yScale(d[1]))
		   .attr("r", (d) => 5);
		
		svg.selectAll("text")
		   .data(dataset)
		   .enter()
		   .append("text")
		   .text((d) => (d[0] + "," + d[1]))
		   .attr("x", (d) => xScale(d[0] + 10))
		   .attr("y", (d) => yScale(d[1]))
		
		const xAxis = d3.axisBottom(xScale);
		const yAxis = d3.axisLeft(yScale);
		
		svg.append("g")
		   .attr("transform", "translate(0," + (h - padding) + ")")
		   .call(xAxis);
		
		svg.append("g")
		   .attr("transform", "translate(" + padding +",0)")
		   .call(yAxis);
		
	</script>
</body>

在这里插入图片描述