D3------繪製交互式帶座標軸的柱狀圖

一:引入(主要介紹比例尺)

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)在繪製矩形的時候,要事先想好矩形的位置座標,便於在加入比例尺時進行位置修改。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章