1. D3中的比例尺
比例尺就是一个数据映射函数,比如线性比例尺可以实现类似y=ax+b的变换。D3一共有三类九种比例尺(其中4种颜色比例尺算序数比例尺的特例):
我们一般采用线性比例尺。
2. 定义域和值域
比例尺有两个最重要的函数:
- .domain([100, 500]) 定义域范围
- .range([10, 350]) 值域范围
下面就是定义比例尺的方法:
var scale = d3.scale.linear()
.domain([100, 500])
.range([10, 350]);
比例尺最终都会对定义域执行相应的函数变换,然后再把这个中间数据线性变换到值域范围上。
3. 坐标轴的缩放
- 最大的X
d3.max(dataset, function(d) { //返回 480
return d[0]; //返回每个子数组的第一个元素
});
- X轴缩放
var xScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[0]; })])
.range([0, w]);
- Y轴缩放
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([0, h]);
4. 设定圆心的坐标
注意要使用和轴一致的比例尺。
.attr("cx", function(d) {
return d[0];
})
缩放后的坐标X值
.attr("cx", function(d) {
return xScale(d[0]);
})
Y值同样如此:
.attr("cy", function(d) {
return d[1];
})
修改后就是:
.attr("cy", function(d) {
return yScale(d[1]);
})
5. 设定文本坐标值(同上)
.attr("x", function(d) {
return d[0];
})
.attr("y", function(d) {
return d[1];
})
变成:
.attr("x", function(d) {
return xScale(d[0]);
})
.attr("y", function(d) {
return yScale(d[1]);
})
6. 源码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>testD3-10-scale.html</title>
<script type="text/javascript" src="d3.js"></script>
<style type="text/css">
</style>
</head>
<body>
<script type="text/javascript">
//高宽
var w = 500;
var h = 100;
var dataset = [
[5, 20], [480, 90], [250, 50], [100, 33], [330, 95],
[410, 12], [475, 44], [25, 67], [85, 21], [220, 88]
];
//Create scale functions
var xScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[0]; })])
.range([0, w]);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([0, h]);
//创建SVG
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d) {
return xScale(d[0]);
})
.attr("cy", function(d) {
return yScale(d[1]);
})
.attr("r", function(d) {
return Math.sqrt(h - d[1]);
});
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d[0] + "," + d[1];
})
.attr("x", function(d) {
return xScale(d[0]);
})
.attr("y", function(d) {
return yScale(d[1]);
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "red");
</script>
</body>
</html>
7. 效果
注:点大小与圈大小成正比,想把大的放在下面,只要改变Y轴值域倒转即可: .range([h , 0]);
注:为了SVG边缘不被截断可以设置边距: .range([h - padding, padding]);
注:自定义半径比例尺:
var rScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([2, 5]);
然后,这样设置半径
.attr("r", function(d) {
return rScale(d[1]);
});