一起来学习D3吧!

D3(Data-Driven Documents)学习

被数据驱动的文档,其实就是一个JavaScript函数库,主要用来做数据可视化。

一.

1.选择集
  • d3.select():选择所有指定元素的第一个

  • d3.selectAll():选择指定全部元素

    <p class="myclass">Sun</p>
    <p id="moon">Moon</p>
    <p class="myclass">You</p>
    //选择第一个元素
    d3.select("body").select("p").style("color","red");
    //选择所有元素
    d3.select("body").selectAll("p").style("color","red");
    //选择第二个元素
    d3.select("#moon").style("color","red");
    //选择另外两个元素
    d3.selectAll(".myclass").style("color","red");
    
2.绑定数据
  • datum():绑定一个数据到选择集上

  • data():绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定

3.插入元素
  • append():在选择集末尾插入元素

  • insert():在选择集前面插入元素

    d3.select("body").append("p").text("Star");//在所有p前加入Star字段
    d3.select("body").insert("p","#moon").text("Star");//在id为moon前加入Star字段
    
4.删除元素
  • remove():删除元素

    d3.select("#moon").remove
    

二.做一个简单的图表

  • SVG绘制的是矢量图,对图像进行放大不会失真,每个图像均视为对象,在SVG中,x轴的正方向是水平向右,y轴的正方向是垂直向下的。

  • canvas中,一旦图形被绘制完成,如果位置发生变化,整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。

  • 使用D3在body元素中添加svg:

    添加画布
    var width = 300;//画布宽度
    var height = 300;//画布高度
    var svg = d3.select("body") //选择文档中的body元素
        .append("svg")     //添加一个svg元素
    		.attr("width",width)  //设定宽度
    		.attr("height",height);  //设定高度
    
    绘制矩形

    绘制一个横向的柱形图,只绘制矩形,不绘制文字和坐标轴,矩形的元素标签是rect

    <svg>
    <rect></rect>
    <rect></rect>
    </svg>
    

    矩形的属性:

    x:矩形左上角的x坐标
    y:矩形左上角的y坐标
    width:矩形的宽度
    height:矩形的高度
    

    给出一组数据,进行可视化

    //横向
    var dataset = [250,210,170,130,90]; //数据(表示矩形的宽度)
    var width = 300;//画布的宽度
    var height = 300;//画布的高度
    var svg = d3.select("body")
    		.append("svg")
    		.attr("width",width)
    		.attr("height",height)
    var rectHeight = 25; //每个矩形所占的像素高度
    svg.selectAll("rect")
    		.data(dataset)
    		.enter()
    		.append("rect")
    		.attr("x",20)
    		.attr("y",function(d,i){
      		return i*rectHeight;
    		})
    		.attr("width",function(d){
      		return d;
    		})
    		.attr("height",rectHeight-2)
    		.attr("fill","steelblue");
    //纵向
    svg.selectAll("rect")
    		.data(dataset)
    		.enter()
    		.append("rect")
    		.attr("x",function(d,i){
      		return i*rectHeight
    		})
    		.attr("y",function(d,i){
      		return height-d;
    		})
    		.attr("height",function(d){
      		return d;
    		})
    		.attr("width",rectHeight-2)
    		.attr("fill","steeblue");
    

三.比例尺

  • 线性比例尺(能将一个连续的区间,映射到另一区间)

    var dataset = [1.2,2.3,0.9,1.5,3.3]
    //将dataset中最小的值映射成0,最大的值映射成300
    var min = d3.min(dataset);
    var max = d3.max(dataset);
    var linear = d3.scale.linear() //线性比例尺
    				.domain([min,max])//定义域
    				.range([0,300]);//值域
    linear(0.9); //返回0
    linear(2.3);//返回175
    linear(3.3);//返回300
    
  • 序数比例尺(有时候定义域和值域不一定是连续的)

    var index = [0,1,2,3,4];
    var color = ["red","blue","green","yellow","black"];
    //希望0对应red,以此类推
    var ordinal = d3.scale.ordinal()
    					.domain(index)
    					.range(color);
    ordinal(0);//返回red
    ordinal(1);//返回blue
    
  • 给柱形图添加比例尺

    var dataset=[2.5,2.1,1.7,1.3,0.9];
    var linear = d3.scale.linear()
    				.domain([0,d3.max(dataset)])//定义域
    				.range([0,250]);//值域
    var rectHeight = 25; //每个矩形所占的像素高度
    svg.selectAll("rect")
    		.data(dataset)
    		.enter()
    		.append("rect")
    		.attr("x",20)
    		.attr("y",function(d,i){
      		return i*rectHeight;
    		})
    		.attr("width",function(d){
      		return linear(d); //这里使用比例尺
    		})
    		.attr("height",rectHeight-2)
    		.attr("fill","steelblue");
    

四.坐标轴

坐标轴由一些列线段和刻度组成,坐标轴在SVG中是没有现成的图形元素的,需要用其他的元素组合构成,D3提供了坐标轴的组件,使在SVG中绘制坐标轴变得像添加一个普通元素一样简单。

定义坐标轴
var dataset = [2.5,2.1,1.7,1.3,0.9];
//定义比例尺
var linear = d3.scale.linear()
				.domain([0,d3.max(dataset)])
				.range([0,250]);
var axis = d3.svg.axis()//坐标轴组件
			.scale(linear) //指定比例尺
			.orient("bottom") //指定刻度的方向
			.ticks(7);   //指定刻度的数量
在SVG中添加坐标轴
svg.append("g").call(axis);
设定坐标轴的样式和位置
//下列是一个常用的样式
<style>
.axis path,
.axis line{
    fill: none;
    stroke:black;
    shape-rendering:crispEdges;
}
.axis text{
	font-family:sans-serif;
  font-size:11px;
}
</style>
//将坐标轴的类设定为axis,坐标轴的位置通过transform来设定
svg.append("g")
	.attr("class","axis")
	.attr("transform","translate(20,130)")
	.call(axis)//改变this指向,指向axis

五.完整的柱形图

制作一个完整的柱形图,包括矩形,文字,坐标轴(内容包括:选择集,数据绑定,比例尺,坐标轴)

添加SVG画布
//画布大小
var width = 400;
var height = 400;
//在body里添加一个svg画布
var svg = d3.select("body")
	.append("svg")
	.attr("width",width)
	.attr("height",height);
//画布周围的空白
var padding = {left:30,right:30,top:20,bottom:20};
定义数据和比例尺
//定义一个数组
var dataset = [10,20,30,40,33,24,12,5];
//x轴的比例尺
var xScale = d3.scale.ordinal()
		.domain(d3.range(dataset.length))
		.rangeRoundBands([0,width-padding.left-padding.right]);
//y轴的比例尺
var yScale = d3.scale.linear()
		.domain([0,d3.max(dataset)])
		.range([height-padding.top-padding.bottom,0]);
定义坐标轴
//定义x轴
var xAxis = d3.svg.axis()
		.scale(xScale)
		.orient("bottom");
//定义y轴
var yAxis = d3.svg.axis()
		.scale(yScale)
		.orient("left");
添加矩形和文字
//矩形之间的空白
var rectPadding = 4;
//添加矩形元素
var rects = svg.selectAll(".MyRect")
				.data(dataset)
				.enter()
				.append("rect")
				.attr("class","MyRect")
				.attr("transform","translate("+padding.left+","+padding.top+")")
				.attr("x",function(d,i){
          return xScale(i)+rectPadding/2
        })
				.attr("y",function(d){
          return yScale(d);
        })
				.attr("width", xScale.rangeBand() - rectPadding )
        .attr("height", function(d){
            return height - padding.top - padding.bottom - yScale(d);
        })
        .attr("fill","steelblue");
//添加文字元素
//添加文字元素
var texts = svg.selectAll(".MyText")
        .data(dataset)
        .enter()
        .append("text")
        .attr("class","MyText")
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .attr("x", function(d,i){
            return xScale(i) + rectPadding/2;
        } )
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("dx",function(){
            return (xScale.rangeBand() - rectPadding)/2;
        })
        .attr("dy",function(d){
            return 20;
        })
        .text(function(d){
            return d;
        })			
        .style({
          "fill":"#FFF",
          "text-anchor":"middle"
        });
添加坐标轴元素
//添加x轴
svg.append("g")
	.attr("class","axis")
	.attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
  .call(xAxis); 

//添加y轴
svg.append("g")
  .attr("class","axis")
  .attr("transform","translate(" + padding.left + "," + padding.top + ")")
  .call(yAxis);

六.动态图表

  • transition()启动过渡效果
.attr("fill","red")//初始颜色为红色
.transition() //启动过渡
.attr("fill","steelblue")//终止颜色为铁蓝色
  • duration()指定过渡的持续时间,单位为毫秒。如duration(2000),指持续2000毫秒,即2秒。

  • ease()指定过渡的方式,常用的有:

    linear:普通的线性变化

    circle:慢慢地达到变换的最终状态

    elastic:带有弹跳的到达最终状态

    bounce:在最终状态处弹跳几次

    调用时格式如:ease(“bounce”)

  • delay()指定延迟的时间,表示一定时间后才开始转变,此函数可以对整体指定延迟,也可以对个别指定延迟

    //整体指定
    .transition()
    .duration(1000)
    .delay(500)
    //个别指定
    .transition()
    .duration(1000)
    .delay(function(d,i){
      return 200*i;
    }) 
    
一些动画效果
var circle1 = svg.append("circle")
				.attr("cx",100)
				.attr("cy",100)
				.attr("r",45)
				.style("fill","green");
circle1.transition()
		.duration(1500)
		.attr("cx",300) //移动x轴
		.style("fill","red")//改变圆颜色
		.attr("r",25)//改变半径

七.理解update(),enter(),exit()

处理当选择集和数据的数量关系不确定的情况。

  • update():当对应的元素正好满足时(绑定数据量 = 对应元素),实际上并不存在这样的一个函数,只是为了要与之后的enter和exit一起说明才想象有这样一个函数。但对应元素正好满足时,直接操作即可,后面直接跟text,style等操作即可。
  • enter():当对应的元素不足时(绑定数据量>对应元素),通常要添加元素,使之与绑定数据的数量相等。后面通常先跟append操作。
  • exit():当对应元素过多时(绑定数据量<对应元素),通常要删除元素,使之与绑定数据的数量相等。后面通常要跟remove操作。

八.交互式操作

与图表的交互,指在图形元素上设置一个或多个监听器,当事件发生时,作出相应的反应。

添加交互
var circle = svg.append("circle");
circle.on("click",function(){ //通过on添加了一个监听器
  //在这里添加交互内容
})

鼠标事件

  • click:鼠标单击某元素时,相当于mousedown和mouseup组合在一起
  • mouseover:光标放在某元素上
  • mouseout:光标从某元素上移出来
  • mousemove:鼠标被移动的时候
  • mousedown:鼠标按钮被按下
  • mouseup:鼠标按钮被松开
  • dblclick:鼠标双击

键盘事件

  • keydown:当用户按下任意键时触发,按住不放会重复触发此事件。该事件不会区分字母的大小,例如A和a被视为一致。
  • keypress:当用户按下字符键(大小写字母,数字,加号,等号,回车等)时触发,按住不放会重复触发此事件。该事件分字母大小写。
  • keyup:当用户释放键时触发,不区分大小写。

九.布局

layout,作用时:将不适合用于绘图等数据转换成了适合用于绘图的数据,可以理解成数据转化。

D3提供了12个布局:饼状图(Pie),力导向图(Force),弦图(Chord),树状图(Tree),集群图(Cluster),捆图(Bundle),打包图(Pack),直方图(Histogram),分区图(Partition),堆栈图(Stack),矩阵树图(Treemap),层级图(Hierarchy),其中层级图不能直接使用。集群图,打包图,分区图,树状图,矩阵树图是由层级图扩展来的。

十.绘制饼状图

var dataset = [30,10,43,55,13];
//定义一个布局
var piedata = pie(dataset);
//绘制图形
var outerRadius = 150;//外半径
var innerRadius = 100;//内半径,为0则中间没有空白
var arc = d3.svg.arc;//弧生成器
		.innerRadius(innerRadius)  //设置内半径
		.outerRadius(outerRadius) //设置外半径
var arcs = svg.selectAll("g")
    .data(piedata)
    .enter()
    .append("g")
    .attr("transform","translate("+ (width/2) +","+ (width/2) +")");
arcs.append("path")
		.attr("fill",function(d,i){
  		return color(i);
		})
		.attr("d",function(d){
  		return arc(d);//调用弧生成器,得到路径值
		})
//在每一个弧线中心添加文本
arcs.append("text")
    .attr("transform",function(d){
        return "translate(" + arc.centroid(d) + ")"; //arc.centroid(d)能算出弧线的中心
    })
    .attr("text-anchor","middle")
    .text(function(d){
        return d.data;
    });
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值