开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的26天,点击查看活动详情
使用 d3.max 和 d3.min 函数在数据集中查找最小值和最大值
介绍
D3 的 domain()
和 range()
方法根据数据设置比例尺的信息。 下面有几种更简单的方法。
通常当你设置域的时候,你会想用数据集中的最小值和最大值。 试图手动的找到这些值,尤其是在很大的数据集中,可能会出错。
D3 有两个方法——min()
和 max()
来返回这些值。 下面是一个例子:
const exampleData = [34, 234, 73, 90, 6, 52];
d3.min(exampleData)
d3.max(exampleData)
像在散点图的例子中的 [x, y]
坐标对一样,数据集有可能嵌套数组。 在这种情况下,你需要告诉 D3 怎么计算最大值和最小值。 幸运的是,min()
和 max()
都可以使用回调函数。 在下面这个例子中,回调函数的参数 d
是当前的内部数组。 回调函数需要从内数组中返回你想比较大小的元素(x
值或 y
值)。 下面是一个如何找到二维数组的最大值和最小值的例子:
const locationData = [[1, 7],[6, 3],[8, 3]];
const minX = d3.min(locationData, (d) => d[0]);
minX
的值应为 1
。
实操
positionData
数组的子数组元素为 x、y 和 z 坐标。 使用 D3 方法从数组中查找 z 坐标(第三个值)的最大值,并将其保存在 output
变量中。
h2
文本应为8
。- 应使用
max()
方法。
<body>
<script>
const positionData = [[1, 7, -4],[6, 3, 8],[2, 9, 3]]
const output = d3.max(positionData,d=>d[2]);
d3.select("body")
.append("h2")
.text(output)
</script>
</body>
使用动态比例
介绍
D3 的 min()
和 max()
方法在设置比例尺时十分有用。
对于一个复杂的数据集,首要是设置比例尺,这样可视化才能适合 SVG 容器的宽和高。 所有数据都应布局在 SVG 画布内部,这样它们在页面上才是可见的。
下面这个例子为散点图设置了 x 轴的比例尺。 domain()
方法给比例尺传递关于散点图原数据值的信息, range()
方法给出在页面上进行可视化的实际空间信息。
在这个例子中,domain 是从 0 到数据集中的最大值, 它使用 max()
方法和基于数组中 x 值的回调函数。 Range 使用 SVG 画布的宽(w
),并包含 padding, 这将在散点图和 SVG 画布边缘之间添加空隙。
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 = 30;
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
在一开始可能很难理解 padding。 想象 x 轴是一条从 0 到 500 (SVG 画布宽的值)的水平直线。 在 range()
方法中包含 padding 使散点图沿着这条直线从 30 (而不是 0)开始,在 470 (而不是 500)结束。
实操
使用 yScale
变量创建一个线性的 y 轴比例尺。 domain 应该从 0 开始到数据集中 y
的最大值, range 应该使用 SVG 的高(h
),并包含 padding。
注意: 记得保持绘图在右上角。 当你为 y 坐标设置 range 时,大的值(height 减去 padding)是第一个参数,小的值是第二个参数。
h2
的文本应为30
。- yScale 的
domain()
应该等于[0, 411]
。 - yScale 的
range()
应该等于[470, 30]
。
<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;
// 画布边线和图表之间的 padding
const padding = 30;
// 创建 x 和 y 轴
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 output = yScale(411); // 返回 30
d3.select("body")
.append("h2")
.text(output)
</script>
</body>