一:引入(主要介紹比例尺)
1.比例尺主要分爲兩類:定量比例尺和序數比例尺。
定量比例尺主要包括線性比例尺和序數比例尺。它們的主要區別在於定義域是否連續。
2.爲什麼要使用比例尺?
當遇到頁面較大而數據較小時,圖形效果較小並且顯示不明顯,使用比例尺,能在有限空間內最大程度地展示圖形效果。
3.爲什麼要繪製座標軸?
繪製座標軸有利於更直觀地比較數據之間的差異。
二:思路及代碼展示
要實現的效果圖:
思路:繪製帶座標軸的柱狀圖,大體上分爲兩部分:座標軸和柱狀圖。
(1)不含比例尺的柱狀圖和標籤,代碼如下:
<script>
//數據
var dataset=[50,43,120,87,99,167,142];
//svg
var width=500;
var height=500;
svg=d3.select("body").append("svg")
.attr("width",width)
.attr("height",height);
//邊界
var padding={left:50,right:50,top:50,bottom:50};
//添加矩形
var rects=svg.selectAll("rect").data(dataset).enter().append("rect")
.attr("x",function(d,i){
return padding.left+i*35;
})
.attr("y",function(d,i){
return heightScale-d;
})
.attr("width",30)
.attr("height",function(d,i){return d;})
.attr("fill","blue");
//添加標籤
var texts=svg.selectAll("text").data(dataset).enter()
.append("text")
.attr("x",function(d,i){
return padding.left+i*35;
})
.attr("y",function(d,i){
return heightScale-d;
})
.attr("dx",15)
.attr("dy","1em")
.attr("font-size",15)
.attr("text-anchor","middle")
.attr("fill","white")
.text(function(d){return d;});
</script>
結果:
(2)設置X軸和Y軸的比例尺:由效果圖顯示可知,X軸的值是離散的,選用序數比例尺;Y軸的值是連續的,選用線性比例尺。代碼如下:
var widthScale=300;
var heightScale=300;
var xScale=d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeBands([0,widthScale],0.2);
var yScale=d3.scale.linear()
.domain([0,d3.max(dataset)])
.range([0,heightScale]);
(3)繪製含比例尺的矩形(修改(1)中的部分位置即可),代碼如下:
<script>
var rects=svg.selectAll("rect").data(dataset).enter().append("rect")
.attr("x",function(d,i){
return padding.left+xScale(i);
})
.attr("y",function(d,i){
return heightScale-yScale(d);
})
.attr("width",xScale.rangeBand())
.attr("height",function(d,i){return yScale(d);})
.attr("fill","blue");
//添加標籤
var texts=svg.selectAll("text").data(dataset).enter()
.append("text")
.attr("x",function(d,i){
return padding.left+xScale(i);
})
.attr("y",function(d,i){
return heightScale-yScale(d);
})
.attr("dx",xScale.rangeBand()/2)
.attr("dy","1em")
.attr("font-size",15)
.attr("text-anchor","middle")
.attr("fill","white")
.text(function(d){return d;});
</script>
效果:
(4)繪製座標軸,代碼如下:
yScale.range([heightScale,0]);
xAxis=d3.svg.axis().scale(xScale).orient("bottom");
yAxis=d3.svg.axis().scale(yScale).orient("left");
//添加座標軸
svg.append("g")
.attr("transform","translate("+padding.left+","+heightScale+")")
.call(xAxis);
svg.append("g")
.attr("transform","translate("+padding.left+","+0+")")
.call(yAxis);
效果:
上面的座標軸是不是醜爆了?所以,要對座標軸進行美化啦。
(5)美化座標軸,設置並應用樣式,代碼如下:
<style>
.axis path,
.axis line{
stroke: black;
fill:none;
shape-rendering: crispedges;
}
.axis text{
font-family: sans-serif;
font-size: 11px;
}
</style>
<script>
svg.append("g")
.attr("class","axis")
.attr("transform","translate("+padding.left+","+heightScale+")")
.call(xAxis);
svg.append("g")
.attr("class","axis")
.attr("transform","translate("+padding.left+","+0+")")
.call(yAxis);
</script>
效果:
(6)添加交互,當鼠標移到柱形上時,對應的柱形變爲紅色,移除變爲藍色。
<script>
rects.on("mouseover",function(d,i){
d3.select(this)
.attr("fill","red");
})
.on("mouseout",function(d,i){
d3.select(this)
.attr("fill","blue");
});
</script>
至此,效果圖繪製完畢。
全部代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="d3.js"></script>
<style>
.axis path,
.axis line{
stroke: black;
fill:none;
shape-rendering: crispedges;
}
.axis text{
font-family: sans-serif;
font-size: 11px;
}
</style>
</head>
<body>
<script>
//數據
var dataset=[50,43,120,87,99,167,142];
//svg
var width=500;
var height=500;
svg=d3.select("body").append("svg")
.attr("width",width)
.attr("height",height);
//邊界
var padding={left:50,right:50,top:50,bottom:50};
//比例尺
var widthScale=300;
var heightScale=300;
var xScale=d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeBands([0,widthScale],0.2);
var yScale=d3.scale.linear()
.domain([0,d3.max(dataset)])
.range([0,heightScale]);
//添加矩形
var rects=svg.selectAll("rect").data(dataset).enter().append("rect")
.attr("x",function(d,i){
return padding.left+xScale(i);
})
.attr("y",function(d,i){
return heightScale-yScale(d);
})
.attr("width",xScale.rangeBand())
.attr("height",function(d,i){return yScale(d);})
.attr("fill","blue");
//交互
rects.on("mouseover",function(d,i){
d3.select(this)
.attr("fill","red");
})
.on("mouseout",function(d,i){
d3.select(this)
.attr("fill","blue");
});
//添加標籤
var texts=svg.selectAll("text").data(dataset).enter()
.append("text")
.attr("x",function(d,i){
return padding.left+xScale(i);
})
.attr("y",function(d,i){
return heightScale-yScale(d);
})
.attr("dx",xScale.rangeBand()/2)
.attr("dy","1em")
.attr("font-size",15)
.attr("text-anchor","middle")
.attr("fill","white")
.text(function(d){return d;});
//座標軸
yScale.range([heightScale,0]);
xAxis=d3.svg.axis().scale(xScale).orient("bottom");
yAxis=d3.svg.axis().scale(yScale).orient("left");
//添加座標軸
svg.append("g")
.attr("class","axis")
.attr("transform","translate("+padding.left+","+heightScale+")")
.call(xAxis);
svg.append("g")
.attr("class","axis")
.attr("transform","translate("+padding.left+","+0+")")
.call(yAxis);
</script>
</body>
</html>
三:總結
(1)繪製矩形和標籤時,一定不要忘了綁定數據。在第一次繪製時,需要使用enter進行添加。
(2)使用比例尺,要根據具體情況選擇合適的比例尺,注意各種比例尺之間的區別。
(3)在繪製矩形的時候,要事先想好矩形的位置座標,便於在加入比例尺時進行位置修改。