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

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值