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)在绘制矩形的时候,要事先想好矩形的位置座标,便于在加入比例尺时进行位置修改。

 

 

 

 

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