版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
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]);
-
});