D3JS可视化入门

文章目录

  • 安装和配置
    • 安装d3js
    • 本地服务器调试
  • 基本操作
    • 数据
      • 加载数据
      • 绑定数据
    • SVG
      • 条形图
      • 散点图
    • 定义坐标轴
    • 更新视图
    • 增加数据
    • 字典绑定
    • 事件监听
    • 自动排序
    • 提示条
  • 布局
    • 饼图
    • 堆叠柱状图
    • 力图
  • 地图

安装和配置

安装d3js

在d3js的官网上可以直接下载d3js的文件,其中包含一个完整版和mini版,差别并不是很大。调试的时候可以使用完整版,发布的时候可以使用mini版,提高加载速度

本地服务器调试

可以利用python创建本地服务器进行调试,也可以安装Apache软件进行调试。使用python进行本地调试注意:

  • python2.0 python -m SimpleHTTPServer 8888
  • python3.0 python -m Http.server 8888

基本操作

数据

加载数据

  • 加载csv数据,可以通过d3.csv(data,function) 进行操作
  • 加载json数据,跟上面是一样的,只需要将csv改为json就行

d3.csv('winemag-data-130k-v2.csv',function(data) {console.log(data)})
d3.json('winemag-data-130k-v2.json',function(data){console.log(data)})

绑定数据

b326a19f9b0d58bac1377e8b55c29c4b.png
上述操作将数组的数据和段落进行绑定
591deb049f246e1f5dd2c2b8089e1824.png

将上述代码最后一段修改,可以将传入的数据输出
image.png
80f3438f22a8d1a177f335922f615e29.png

SVG

条形图

绘制SVG并将数据绑定到图形上

//Width and height
var w = 500;
var h = 50;

//Data
var dataset = [ 5, 10, 15, 20, 25 ];

//Create SVG element
var svg = d3.select("body")
            .append("svg")
            .attr("width", 500)
            .attr("height", 50);

var circles = svg.selectAll("circle")
    .data(dataset)
    .enter()
    .append("circle");

circles.attr("cx", function(d, i) {
            return (i * 50) + 25;
        })
       .attr("cy", h/2)
       .attr("r", function(d) {
            return d;
       });

a6b566767c76e8717d829d2910a48549.png

绘制条形图,并且根据数组的大小和长度调整柱形图的宽度

//Width and heightvar 
w = 500;var h = 100;var dataset = [];                                                      
//Initialize empty array
for (var i = 0; i < 25; i++) {                               //Loop 25 times    var newNumber = Math.random() * 20;  //New random number (0-30)    
dataset.push(newNumber);                       //Add new number to array}
/Create SVG elementvar 
svg = d3.select("body").append("svg")            
        .attr("width", 500)           
        .attr("height", 100)
        
        var bar = svg.selectAll("rect")    
                        .data(dataset)    
                        .enter()   
                        .append("rect")    
                        .attr('x',0)   
                        .attr('y',0)    
                        .attr('height',50)    
                        .attr('width',20)
       bar.attr("x", function(d, i) {           
            return (i *(w/dataset.length))       
            })       
            .attr('y',function(d) {           
                return h-d*4       
                })        
            .attr('width',function(d){           
                     return w/dataset.length-2       
                })      
             .attr("height", function(d) {           
                return d*4;       });
                
      //加标签
      svg.selectAll('text').data(dataset)    
      .enter()    
      .append('text')   
      .text(function(d)    {       
      return d    })
      .attr("x", function(d,i) { return i* (w/dataset.length)+2})
      .attr("y",function(d) {return h-(d*4)+10})   
      .attr('font-family','sans-serif')   
      .attr('font-size','11px')    .attr('fill','white')

cc1907a12d42d36fcc1f53085fc46a9e.png

散点图

散点图的画法实际上与前面的是一致的,只是需要更改的是circle和设置x,y以及半径

var dataset_2 = [[5, 20], [480, 90], [250, 50], [100, 33], [330, 95],[410, 12], [475, 44], [25, 67], [85, 21], [220, 88] ];
var svg2=d3.selectAll('body').append('svg')    
.attr("height",h)
.attr("width",w) 

svg2.selectAll('circle').data(dataset_2)
.enter().append('circle') 
.attr("cx", function(d) {return d[0]})
.attr("cy", function(d) {return d[1]})
.attr('r',function(d){return Math.sqrt(h-d[1])}) 

svg2.selectAll('text').data(dataset_2).enter().append('text').text(function(d) {return d[0]+','+d[1]}) 
.attr('x',function(d){return d[0]+3}) .attr('y',function(d) {return d[1]+3}) .attr('font_size','2px')

15690af663b2b0b83862212ce1b4a107.png

定义坐标轴

d3中的call函数会取得代码链中传递过来的元素,然后再把它交给其他函数(括号里面的函数)

//Width and height
ar w = 500;
var h = 300;
var padding = 20
;var dataset = [                                        [5, 20], [480, 90], [250, 50], [100, 33], [330, 95],                                        [410, 12], [475, 44], [25, 67], [85, 21], [220, 88],                                        [600, 150]                                ];
//Create scale functions
var xScale = d3.scaleLinear()                                                   .domain([0, d3.max(dataset, function(d) { return d[0]; })])                                                   
.range([padding, w - padding * 2]);

var yScale = d3.scaleLinear()                                                   .domain([0, d3.max(dataset, function(d) { return d[1]; })])                                                  
.range([h - padding, padding]);

var rScale = d3.scaleLinear()                                                   .domain([0, d3.max(dataset, function(d) { return d[1]; })])                                                   
.range([2, 5]);//Define X axis

var xAxis = d3.axisBottom()                                          .scale(xScale)                                         
.ticks(5);

var yAxis = d3.axisLeft()                                          .scale(yScale)                                         
.ticks(5);



//Create SVG element

var svg = d3.select("body")                             
.append("svg")                              
.attr("width", w)                             
.attr("height", h);

//Create circles

svg.selectAll("circle")   
.data(dataset)  
.enter()  
.append("circle")  
.attr("cx", function(d) {                    return xScale(d[0]);   })   .attr("cy", function(d) {                    return yScale(d[1]);   })   .attr("r", function(d) {                    return rScale(d[1]);   });

//Create labels

svg.selectAll("text")  
.data(dataset)  
.enter()  
.append("text")   
.text(function(d) {                    return d[0] + "," + d[1];   })   .attr("x", function(d) {                    return xScale(d[0]);   })   
.attr("y", function(d) {                    return yScale(d[1]);   })   .attr("font-family", "sans-serif")  
.attr("font-size", "11px")  
.attr("fill", "red")
;//Create X axis
svg.append("g")         
.attr("class", "axis")         
.attr("transform", "translate(0," + (h - padding) + ")")          
call(xAxis);

svg.append("g")          
.attr("class", "axis")          
.attr("transform", "translate("+padding+ ",0)")         
.call(yAxis);

1fdddc56180b932c24d26b9be4a32fd6.png

更新视图

对于视图的更新书中所讲的是d3.v3的使用,v5的版本貌似对此有过更改,此代码只能更新数据,但是更新过程中缺少动画效果。

对于常见的更新数据主要有以下常规步骤

  1. 设置图像基本信息
  2. 生成初始数据
  3. 生成比例尺
  4. 生成坐标轴
  5. 生成绘图元素(圆或者矩阵和标签
  6. 设置监听器或者定时器
  7. 将获取数据和设置比例尺,标签部分重写一遍
//Width and height
			var w = 1000;
			var h = 300;
			var padding = 20;
		// 生成随机数
		valueNum=100
		var dataset=[]
		for (var i=0;i < 100;i++){
		    var num=Math.floor(Math.random()*100)
		    dataset.push(num)
		   }
		// 生成比例尺
		var xScale=d3.scaleOrdinal().domain(d3.range(dataset.length))
		            .range([0,w],0.05)
		var yScale=d3.scaleLinear().domain([0,d3.max(dataset)])
		            .range([h-padding,padding])

		//生成坐标轴
		var xAxis=d3.axisBottom().scale(xScale).ticks(5)
		var yAxis=d3.axisLeft().scale(yScale).ticks(5)

		//生成svg
		var svg=d3.select('body').append('svg').attr('width',w).attr('height',h)
		//生成柱形图并绑定数据
		svg.selectAll('rect').data(dataset).enter().append('rect')
		    .attr('x',function(d,i){return xScale.domain()[i]*10})
		    .attr('y',function(d) {return h-yScale(d)})
		    .attr('width',10)
		    .attr('height',function(d){return yScale(d)})
		    .attr('fill','black')
		 //生成标签
		 svg.selectAll('text').data(dataset).enter().append('text').text(function(d){return d})
		    .attr('x',function(d,i) {return xScale.domain()[i]*10+2})
		    .attr('y',function(d) {return h-yScale(d)+14})
		    .attr('font-size','8px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')

		 // 设置监听
		 d3.select('p').on('click', function(){
		    // 生成随机数
		var valueNum=100
		var dataset=[]
		for (var i=0;i<100;i++){
		    var num=Math.floor(Math.random()*100)
		    dataset.push(num)}
		 //更新比例尺
		var xScale=d3.scaleOrdinal().domain(d3.range(dataset.length))
		            .range([0,w],0.05)
		var yScale=d3.scaleLinear().domain([0,d3.max(dataset)])
		            .range([h-padding,padding])
		  // 更新数据

		svg.selectAll('rect').data(dataset).transition().duration(1000)
		.each(function(d,i){
		    d3.select(this)
		    .attr('x',xScale.domain()[i]*10)
		    .attr('y',h-yScale(d))
		    .attr('width',10)
		    .attr('height',yScale(d))
		    .attr('fill','black')
		    })
        		 svg.selectAll('text').data(dataset).enter().append('text').text(function(d){return d})
		    .attr('x',function(d,i) {return xScale.domain()[i]*10+2})
		    .attr('y',function(d) {return h-yScale(d)+14})
		    .attr('font-size','8px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')
		   })

增加数据

在这个过程中需要注意的是设置新增加的那个数据的位置,已经设置总体更新的过渡函数。注意选择器的使用,不要用错了主体,从而导致新增的数据无法显示

这个方法虽然能够更新数据,但是在删除的时候会出现数据与标签对不上的问题,因此在更新数据时,更应该尝试使用键值对(字典)的形式来绑定数据

//生成数据
    var dataset=[]
    var maxvalue=25
	for (var i=0;i < maxvalue;i++){
		    var num=Math.floor(Math.random()*maxvalue)
		    dataset.push(num)
		   }

    //宽高
    var w = 1000;
    var h = 300;
    var padding = 20;
   //生成比例尺
    var xScale=d3.scaleOrdinal().domain(d3.range(dataset.length))
                .range([0,w],0.05)
    var yScale=d3.scaleLinear().domain([0,d3.max(dataset)])
                .range([h-padding,padding])
    //生成svg
		var svg=d3.select('body').append('svg').attr('width',w).attr('height',h)
		//生成柱形图并绑定数据
		svg.selectAll('rect').data(dataset).enter().append('rect')
		    .attr('x',function(d,i){return  xScale.domain()[i]*(w/dataset.length)})
		    .attr('y',function(d) {return h-yScale(d)})
		    .attr('width',w/dataset.length-2)
		    .attr('height',function(d){return yScale(d)})
		    .attr('fill','black')
		 //生成标签
		svg.selectAll('text').data(dataset).enter().append('text').text(function(d){return d})
		    .attr('x',function(d,i) {return  xScale.domain()[i]*(w/dataset.length)+(w/dataset.length)/2})
		    .attr('y',function(d) {return h-yScale(d)+20})
		    .attr('font-size','10px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')

      //增加数据
      d3.select('p').on('click',function(){
            var num=Math.floor(Math.random()*maxvalue)
		    dataset.push(num)
		   xScale.domain(d3.range(dataset.length))
		   yScale.domain([0,d3.max(dataset)])


           var bars=svg.selectAll('rect').data(dataset)

           bars.enter().append('rect').attr('x',w-(w/dataset.length)).attr('y',function(d){return h-yScale(d)}).attr('width',(w/dataset.length)-2).attr('height',function(d){return yScale(d)})
           .attr('fill','black')

           bars.transition().duration(1000).attr('x',function(d,i){return  xScale.domain()[i]*(w/dataset.length)})
		    .attr('y',function(d) {return h-yScale(d)})
		    .attr('width',w/dataset.length-2)
		    .attr('height',function(d){return yScale(d)})
		    .attr('fill','black')
        var text=svg.selectAll('text').data(dataset)
        text.enter().append('text').text(function(d){return d})
		    .attr('x',w-(w/dataset.length))
		    .attr('y',function(d){return h-yScale(d)+20})
		    .attr('font-size','12px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')


		 text.transition().duration(1000).attr('x',function(d,i) {return  xScale.domain()[i]*(w/dataset.length)+(w/dataset.length)/2})
		    .attr('y',function(d) {return h-yScale(d)})
		    .attr('font-size','10px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')
 //删除数据
      d3.select('#delete').on('click',function(){
            dataset.shift()
            xScale.domain(d3.range(dataset.length))
		   yScale.domain([0,d3.max(dataset)])


           var bars=svg.selectAll('rect').data(dataset)

           bars.enter().append('rect').attr('x',w-(w/dataset.length)).attr('y',function(d){return h-yScale(d)}).attr('width',(w/dataset.length)-2).attr('height',function(d){return yScale(d)})
           .attr('fill','black')

           bars.transition().duration(1000).attr('x',function(d,i){return  xScale.domain()[i]*(w/dataset.length)})
		    .attr('y',function(d) {return h-yScale(d)})
		    .attr('width',w/dataset.length-2)
		    .attr('height',function(d){return yScale(d)})
		    .attr('fill','black')

		 bars.exit().transition().duration(1000).attr('x',w-(w/dataset.length)).remove()
        var text=svg.selectAll('text').data(dataset)
        text.enter().append('text').text(function(d){return d})
		    .attr('x',w-(w/dataset.length))
		    .attr('y',function(d){return h-yScale(d)+20})
		    .attr('font-size','12px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')


		 text.transition().duration(1000).attr('x',function(d,i) {return  xScale.domain()[i]*(w/dataset.length)+(w/dataset.length)/2})
		    .attr('y',function(d) {return h-yScale(d)})
		    .attr('font-size','10px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')
         text.exit().transition().duration(1000).attr('x',w-(w/dataset.length)/2).remove()
      })

字典绑定

这里可能是版本的问题,代码运行还是会存在一些问题:

  • 增加值标签不会出现问题,但是在删除值时,标签数据不会同步更新
  • 增加再删除,会出现新增加的标签直接偏移到最左边

<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>D3: Adding and removing values from a chart (dynamic labels included)title>
		 <script src="d3/d3.min.js">script>
		<style type="text/css">
			/* No style rules here yet */
		style>
	head>
	<body>

		<p id="add">Add a new data valuep>
		<p id="remove">Remove a data valuep>

		<script type="text/javascript">

			//Width and height
			var w = 600;
			var h = 250;

			var dataset = [ { key: 0, value: 5 },		//dataset is now an array of objects.
							{ key: 1, value: 10 },		//Each object has a 'key' and a 'value'.
							{ key: 2, value: 13 },
							{ key: 3, value: 19 },
							{ key: 4, value: 21 },
							{ key: 5, value: 25 },
							{ key: 6, value: 22 },
							{ key: 7, value: 18 },
							{ key: 8, value: 15 },
							{ key: 9, value: 13 },
							{ key: 10, value: 11 },
							{ key: 11, value: 12 },
							{ key: 12, value: 15 },
							{ key: 13, value: 20 },
							{ key: 14, value: 18 },
							{ key: 15, value: 17 },
							{ key: 16, value: 16 },
							{ key: 17, value: 18 },
							{ key: 18, value: 23 },
							{ key: 19, value: 25 } ];

			var xScale = d3.scaleOrdinal()
							.domain(d3.range(dataset.length))
							.range([0, w], 0.05);

			var yScale = d3.scaleLinear()
							.domain([0, d3.max(dataset, function(d) { return d.value; })])
							.range([0, h]);

			//Define key function, to be used when binding data
			var key = function(d) {
				return d.key;
			};

			//Create SVG element
			var svg = d3.select("body")
						.append("svg")
						.attr("width", w)
						.attr("height", h);

			//Create bars
			svg.selectAll("rect")
			   .data(dataset, key)
			   .enter()
			   .append("rect")
			   .attr("x", function(d, i) {
			   		return  xScale.domain()[i]*(w/dataset.length);
			   })
			   .attr("y", function(d) {
			   		return h - yScale(d.value);
			   })
			   .attr("width", (w/dataset.length)-2)
			   .attr("height", function(d) {
			   		return yScale(d.value);
			   })
			   .attr("fill", function(d) {
					return "rgb(0, 0, " + (d.value * 10) + ")";
			   });

			//Create labels
			svg.selectAll("text")
			   .data(dataset, key)
			   .enter()
			   .append("text")
			   .text(function(d) {
			   		return d.value;
			   })
			   .attr("text-anchor", "middle")
			   .attr("x", function(d, i) {
			   		return  xScale.domain()[i]*(w/dataset.length)+(w/dataset.length)/2;
			   })
			   .attr("y", function(d) {
			   		return h - yScale(d.value) + 14;
			   })
			   .attr("font-family", "sans-serif")
			   .attr("font-size", "11px")
			   .attr("fill", "red");




			//On click, update with new data
			d3.selectAll("p")
				.on("click", function() {

					//See which p was clicked
					var paragraphID = d3.select(this).attr("id");

					//Decide what to do next
					if (paragraphID == "add") {
						//Add a data value
						var maxValue = 25;
						var newNumber = Math.floor(Math.random() * maxValue);
						var lastKeyValue = dataset[dataset.length - 1].key;
						console.log(lastKeyValue);
						dataset.push({
							key: lastKeyValue + 1,
							value: newNumber
						});
					} else {
						//Remove a value
						dataset.shift();	//Remove one value from dataset
					}

					//Update scale domains
					xScale.domain(d3.range(dataset.length));
					yScale.domain([0, d3.max(dataset, function(d) { return d.value; })]);

					//Select…
					var bars = svg.selectAll("rect")
						.data(dataset, key);

					//Enter…
					bars.enter()
						.append("rect")
						.attr("x", w)
						.attr("y", function(d) {
							return h - yScale(d.value);
						})
						.attr("width", (w/dataset.length)-2)
						.attr("height", function(d) {
							return yScale(d.value);
						})
						.attr("fill", function(d) {
							return "rgb(0, 0, " + (d.value * 10) + ")";
						});

					//Update…
					bars.transition()
						.duration(500)
						.attr("x", function(d, i) {
							return xScale.domain()[i]*(w/dataset.length)+(w/dataset.length);
						})
						.attr("y", function(d) {
							return h - yScale(d.value);
						})
						.attr("width", (w/dataset.length))
						.attr("height", function(d) {
							return yScale(d.value);
						});

					//Exit…
					bars.exit()
						.transition()
						.duration(500)
						.attr("x", -(w/dataset.length))
						.remove();



					//Update all labels

					//Select…
					var labels = svg.selectAll("text")
						.data(dataset, key);

					//Enter…
					<!--labels.enter()-->
						<!--.append("text")-->
						<!--.text(function(d) {-->
							<!--return d.value;-->
						<!--})-->
						<!--.attr("text-anchor", "middle")-->
						<!--.attr("x", w)-->
						<!--.attr("y", function(d) {-->
							<!--return h - yScale(d.value) + 14;-->
						<!--})-->
					   <!--.attr("font-family", "sans-serif")-->
					   <!--.attr("font-size", "11px")-->
					   <!--.attr("fill", "black");-->

					<!--//Update…-->
					<!--labels.transition()-->
						<!--.duration(500)-->
						<!--.attr("x", function(d, i) {-->
							<!--return xScale.domain()[i]+ (w/dataset.length) / 2;-->
						<!--});-->
labels.enter().append('text').text(function(d){return d.value})
		    .attr('x',w)
		    .attr('y',function(d){return h-yScale(d.value)+20})
		    .attr('font-size','12px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')


		 labels.transition().duration(1000).attr('x',function(d,i) {return  xScale.domain()[i+1]*(w/dataset.length)+(w/dataset.length)/2})
        labels.exit().transition().duration(1000).attr('x',-(w/dataset.length)/2).remove()
					<!--//Exit…-->
					<!--labels.exit()-->
						<!--.transition()-->
						<!--.duration(500)-->
						<!--.attr("x", -(w/dataset.length))-->
						<!--.remove();-->

				});


		script>
	body>
html>

事件监听

  • 使用CSS实现悬停高亮

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>时间监听title>
    <script src="d3/d3.min.js">script>
    <style type="text/css">

			rect:hover {
				fill: orange;
			}

		style>
head>
<body>
<script type="text/javascript">

    var w = 1000;
    var h = 300;
    padding = 10
var dataset = [ { key: 0, value: 5 },		//dataset is now an array of objects.
							{ key: 1, value: 10 },		//Each object has a 'key' and a 'value'.
							{ key: 2, value: 13 },
							{ key: 3, value: 19 },
							{ key: 4, value: 21 },
							{ key: 5, value: 25 },
							{ key: 6, value: 22 },
							{ key: 7, value: 18 },
							{ key: 8, value: 15 },
							{ key: 9, value: 13 },
							{ key: 10, value: 11 },
							{ key: 11, value: 12 },
							{ key: 12, value: 15 },
							{ key: 13, value: 20 },
							{ key: 14, value: 18 },
							{ key: 15, value: 17 },
							{ key: 16, value: 16 },
							{ key: 17, value: 18 },
							{ key: 18, value: 23 },
							{ key: 19, value: 25 } ];
     var key=function(d){return d.key}
    //定义比例尺
    var xScale=d3.scaleOrdinal().domain(d3.range(dataset.length))
                .range([0,w],0.05)
     var yScale=d3.scaleLinear().domain([0,d3.max(dataset,function(d){return d.value})])
                .range([0,h])

     //生成svg
		var svg=d3.select('body').append('svg').attr('width',w).attr('height',h)
		//生成柱形图并绑定数据
		svg.selectAll('rect').data(dataset,key).enter().append('rect')
		    .attr('x',function(d,i){return  xScale.domain()[i]*(w/dataset.length)})
		    .attr('y',function(d) {return h-yScale(d.value)})
		    .attr('width',w/dataset.length-2)
		    .attr('height',function(d){return yScale(d.value)})
		    .attr('fill','black')
		 //生成标签
		svg.selectAll('text').data(dataset,key).enter().append('text').text(function(d){return d.value})
		    .attr('x',function(d,i) {return  xScale.domain()[i]*(w/dataset.length)+(w/dataset.length)/2})
		    .attr('y',function(d) {return h-yScale(d.value)+20})
		    .attr('font-size','10px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')
script>
body>
html>
  • 使用d3实现悬停高亮

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>d3悬停title>
    <script src="d3/d3.min.js">script>
head>
<body>
<script type="text/javascript">

    var w = 1000;
    var h = 300;
    padding = 10
var dataset = [ { key: 0, value: 5 },		//dataset is now an array of objects.
							{ key: 1, value: 10 },		//Each object has a 'key' and a 'value'.
							{ key: 2, value: 13 },
							{ key: 3, value: 19 },
							{ key: 4, value: 21 },
							{ key: 5, value: 25 },
							{ key: 6, value: 22 },
							{ key: 7, value: 18 },
							{ key: 8, value: 15 },
							{ key: 9, value: 13 },
							{ key: 10, value: 11 },
							{ key: 11, value: 12 },
							{ key: 12, value: 15 },
							{ key: 13, value: 20 },
							{ key: 14, value: 18 },
							{ key: 15, value: 17 },
							{ key: 16, value: 16 },
							{ key: 17, value: 18 },
							{ key: 18, value: 23 },
							{ key: 19, value: 25 } ];
     var key=function(d){return d.key}
    //定义比例尺
    var xScale=d3.scaleOrdinal().domain(d3.range(dataset.length))
                .range([0,w],0.05)
     var yScale=d3.scaleLinear().domain([0,d3.max(dataset,function(d){return d.value})])
                .range([0,h])

     //生成svg
		var svg=d3.select('body').append('svg').attr('width',w).attr('height',h)
		//生成柱形图并绑定数据
		svg.selectAll('rect').data(dataset,key).enter().append('rect')
		    .attr('x',function(d,i){return  xScale.domain()[i]*(w/dataset.length)})
		    .attr('y',function(d) {return h-yScale(d.value)})
		    .attr('width',w/dataset.length-2)
		    .attr('height',function(d){return yScale(d.value)})
		    .attr('fill','#81D4FA').on('mouseover',function(){return d3.select(this).attr('fill','#FF9100')})
        .on('mouseout',function(d){return d3.select(this).transition().duration(1000).attr('fill','#81D4FA')})
		 //生成标签
		svg.selectAll('text').data(dataset,key).enter().append('text').text(function(d){return d.value})
		    .attr('x',function(d,i) {return  xScale.domain()[i]*(w/dataset.length)+(w/dataset.length)/2})
		    .attr('y',function(d) {return h-yScale(d.value)+20})
		    .attr('font-size','10px')
		    .attr('font-family','san-serif')
		    .attr('fill','white')

script>
body>
html>

自动排序


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自动排序title>
    <script src="d3/d3.min.js">script>
head>
<body>
<script type="text/javascript">
    //生成数据
    var dataset=[]
    var maxvalue=25
	for (var i=0;i < maxvalue;i++){
		    var num=Math.floor(Math.random()*maxvalue)
		    dataset.push(num)
		   }

    //宽高
    var w = 1000;
    var h = 300;
    var padding = 20;
   //生成比例尺
    var xScale=d3.scaleOrdinal().domain(d3.range(dataset.length))
                .range([0,w],0.05)
    var yScale=d3.scaleLinear().domain([0,d3.max(dataset)])
                .range([h-padding,padding])
    //生成svg
		var svg=d3.select('body').append('svg').attr('width',w).attr('height',h)
		//生成柱形图并绑定数据
		svg.selectAll('rect').data(dataset).enter().append('rect')
		    .attr('x',function(d,i){return  xScale.domain()[i]*(w/dataset.length)})
		    .attr('y',function(d) {return yScale(d)})
		    .attr('width',w/dataset.length-2)
		    .attr('height',function(d){return h-yScale(d)})
		    .attr('fill','#81D4FA')
		    .on('mouseover',function(){return d3.select(this).attr('fill','#FF9100')})
            .on('mouseout',function(d){return d3.select(this).transition().duration(1000).attr('fill','#81D4FA')})
            .on('click',function(){return sortby(),sortbytext()})
		 //生成标签
		svg.selectAll('text').data(dataset).enter().append('text').text(function(d){return d})
		    .attr('x',function(d,i) {return  xScale.domain()[i]*(w/dataset.length)+(w/dataset.length)/2})
		    .attr('y',function(d) {return yScale(d)+20})
		    .attr('font-size','10px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')
        var sortby=function(){
        svg.selectAll('rect').sort(function(a,b){return d3.ascending(a,b)}).transition().duration(1000).attr('x',function(d,i){return xScale.domain()[i]*(w/dataset.length)})}
        var sortbytext=function(){
        svg.selectAll('text').sort(function(a,b){return d3.ascending(a,b)}).transition().duration(1000).attr('x',function(d,i){return xScale.domain()[i]*(w/dataset.length)})}
script>
body>
html>

D3JS可视化入门_第1张图片

提示条


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>div提示框title>
    <script src="d3/d3.min.js">script>
    <style type="text/css">

			rect:hover {
				fill: orange;
			}

			#tooltip {
				position: absolute;
				width: 200px;
				height: auto;
				padding: 10px;
				background-color: white;
				-webkit-border-radius: 10px;
				-moz-border-radius: 10px;
				border-radius: 10px;
				-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
				-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
				box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
				pointer-events: none;
			}

			#tooltip.hidden {
				display: none;
			}

			#tooltip p {
				margin: 0;
				font-family: sans-serif;
				font-size: 16px;
				line-height: 20px;
			}
	style>

head>
<body>
		<div id="tooltip" class="hidden">
			<p><strong>Important Label Headingstrong>p>
			<p><span id="value">100p>
		div>
    <script type="text/javascript">
    //生成数据
    var dataset=[]
    var maxvalue=25
	for (var i=0;i < maxvalue;i++){
		    var num=Math.floor(Math.random()*maxvalue)
		    dataset.push(num)
		   }

    //宽高
    var w = 1000;
    var h = 300;
    var padding = 20;
   //生成比例尺
    var xScale=d3.scaleOrdinal().domain(d3.range(dataset.length))
                .range([0,w],0.05)
    var yScale=d3.scaleLinear().domain([0,d3.max(dataset)])
                .range([h-padding,padding])
    //生成svg
		var svg=d3.select('body').append('svg').attr('width',w).attr('height',h)
		//生成柱形图并绑定数据
		svg.selectAll('rect').data(dataset).enter().append('rect')
		    .attr('x',function(d,i){return  xScale.domain()[i]*(w/dataset.length)})
		    .attr('y',function(d) {return yScale(d)})
		    .attr('width',w/dataset.length-2)
		    .attr('height',function(d){return h-yScale(d)})
		    .attr('fill','#81D4FA')
		    .on('mouseover',function(d){
		    var xPosition = parseFloat(d3.select(this).attr("x")) + (w/dataset.length) / 2;
					var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + h / 2;

					//Update the tooltip position and value
					d3.select("#tooltip")
						.style("left", xPosition + "px")
						.style("top", yPosition + "px")
						.select("#value")
						.text(d);

					//Show the tooltip
					d3.select("#tooltip").classed("hidden", false);
		    return d3.select(this).attr('fill','#FF9100')})
            .on('mouseout',function(d){
            d3.select("#tooltip").classed("hidden", true);
            return d3.select(this).transition().duration(1000).attr('fill','#81D4FA')})
            .on('click',function(){return sortby(),sortbytext()}).append('title').text(function(d){return d})
		 //生成标签
		svg.selectAll('text').data(dataset).enter().append('text').text(function(d){return d})
		    .attr('x',function(d,i) {return  xScale.domain()[i]*(w/dataset.length)+(w/dataset.length)/2})
		    .attr('y',function(d) {return yScale(d)+20})
		    .attr('font-size','10px')
		    .attr('font-family','san-serif')
		    .attr('fill','red')
        var sortby=function(){
        svg.selectAll('rect').sort(function(a,b){return d3.ascending(a,b)}).transition().duration(1000).attr('x',function(d,i){return xScale.domain()[i]*(w/dataset.length)})}
        var sortbytext=function(){
        svg.selectAll('text').sort(function(a,b){return d3.ascending(a,b)}).transition().duration(1000).attr('x',function(d,i){return xScale.domain()[i]*(w/dataset.length)})}
script>
body>
html>

D3JS可视化入门_第2张图片

布局

D3的全部布局方法如下:

  • Bundle:把霍尔顿(Holten)的分层捆绑算法应用到连线(edge)上
  • Chord: 根据矩阵关系生成弦形图(chord diagram)
  • Cluster:聚集实体生成系统树图(dendrogram)
  • Force :根据物理模拟链接定位的节点
  • Hierarchy :派生自定义的系统(分层的)布局实现
  • Histogram:基于量化的分组计算数据分布
  • Pack:基于递归圆形填充(circle packing)产生分层布局
  • Partition:递归细分节点树,呈射线或冰挂状
  • Pie:计算饼图或圆环图中弧形的起止角度
  • Stack:计算一系列堆叠的条形或者面积图的基线
  • Tree : 整齐的定位树节点
  • Treemap:基于递归空间细分来显示节点树

饼图

  1. 建立pie布局
  2. 创建svg并传入pie给g元组
  3. 设置内外圆半径
  4. 绘制路径
  5. 绘制文本标签

<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>D3: Pie layouttitle>
		<script type="text/javascript" src="../d3/d3.v3.js">script>
		<style type="text/css">

			text {
				font-family: sans-serif;
				font-size: 12px;
				fill: white;
			}

		style>
	head>
	<body>
		<script type="text/javascript">

			//Width and height
			var w = 300;
			var h = 300;

			var dataset = [ 5, 10, 20, 45, 6, 25 ];

			var outerRadius = w / 2;
			var innerRadius = 0;
			var arc = d3.svg.arc()
							.innerRadius(innerRadius)
							.outerRadius(outerRadius);
			
			var pie = d3.layout.pie();
			
			//Easy colors accessible via a 10-step ordinal scale
			var color = d3.scale.category10();

			//Create SVG element
			var svg = d3.select("body")
						.append("svg")
						.attr("width", w)
						.attr("height", h);
			
			//Set up groups
			var arcs = svg.selectAll("g.arc")
						  .data(pie(dataset))
						  .enter()
						  .append("g")
						  .attr("class", "arc")
						  .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");
			
			//Draw arc paths
			arcs.append("path")
			    .attr("fill", function(d, i) {
			    	return color(i);
			    })
			    .attr("d", arc);
			
			//Labels
			arcs.append("text")
			    .attr("transform", function(d) {
			    	return "translate(" + arc.centroid(d) + ")";
			    })
			    .attr("text-anchor", "middle")
			    .text(function(d) {
			    	return d.value;
			    });
						
		script>
	body>
html>

168a9ca3ec27c0ff34c51b811084ffa2.png

堆叠柱状图

  1. 创建stack布局
  2. 计算堆叠
  3. 设置高度与基准值

<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>D3: Stack layout stacked bar charttitle>
		<script type="text/javascript" src="../d3/d3.v3.js">script>
		<style type="text/css">
			/* No style rules here yet */
		style>
	head>
	<body>
		<script type="text/javascript">

			//Width and height
			var w = 500;
			var h = 300;

			//Original data
			var dataset = [
				[
					{ x: 0, y: 5 },
					{ x: 1, y: 4 },
					{ x: 2, y: 2 },
					{ x: 3, y: 7 },
					{ x: 4, y: 23 }
				],
				[
					{ x: 0, y: 10 },
					{ x: 1, y: 12 },
					{ x: 2, y: 19 },
					{ x: 3, y: 23 },
					{ x: 4, y: 17 }
				],
				[
					{ x: 0, y: 22 },
					{ x: 1, y: 28 },
					{ x: 2, y: 32 },
					{ x: 3, y: 35 },
					{ x: 4, y: 43 }
				]
			];

			//Set up stack method
			var stack = d3.layout.stack();

			//Data, stacked
			stack(dataset);

			//Set up scales
			var xScale = d3.scale.ordinal()
				.domain(d3.range(dataset[0].length))
				.rangeRoundBands([0, w], 0.05);
		
			var yScale = d3.scale.linear()
				.domain([0,				
					d3.max(dataset, function(d) {
						return d3.max(d, function(d) {
							return d.y0 + d.y;
						});
					})
				])
				.range([0, h]);
				
			//Easy colors accessible via a 10-step ordinal scale
			var colors = d3.scale.category10();
		
			//Create SVG element
			var svg = d3.select("body")
						.append("svg")
						.attr("width", w)
						.attr("height", h);
	
			// Add a group for each row of data
			var groups = svg.selectAll("g")
				.data(dataset)
				.enter()
				.append("g")
				.style("fill", function(d, i) {
					return colors(i);
				});
	
			// Add a rect for each data value
			var rects = groups.selectAll("rect")
				.data(function(d) { return d; })
				.enter()
				.append("rect")
				.attr("x", function(d, i) {
					return xScale(i);
				})
				.attr("y", function(d) {
					return yScale(d.y0);
				})
				.attr("height", function(d) {
					return yScale(d.y);
				})
				.attr("width", xScale.rangeBand());
						
		script>
	body>
html>

7f70683ed64746c661606f6966a86336.png

力图


<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>D3: Force layouttitle>
		<script type="text/javascript" src="../d3/d3.v3.js">script>
		<style type="text/css">
			/* No style rules here yet */
		style>
	head>
	<body>
		<script type="text/javascript">

			//Width and height
			var w = 500;
			var h = 300;

			//Original data
			var dataset = {
				nodes: [
					{ name: "Adam" },
					{ name: "Bob" },
					{ name: "Carrie" },
					{ name: "Donovan" },
					{ name: "Edward" },
					{ name: "Felicity" },
					{ name: "George" },
					{ name: "Hannah" },
					{ name: "Iris" },
					{ name: "Jerry" }
				],
				edges: [
					{ source: 0, target: 1 },
					{ source: 0, target: 2 },
					{ source: 0, target: 3 },
					{ source: 0, target: 4 },
					{ source: 1, target: 5 },
					{ source: 2, target: 5 },
					{ source: 2, target: 5 },
					{ source: 3, target: 4 },
					{ source: 5, target: 8 },
					{ source: 5, target: 9 },
					{ source: 6, target: 7 },
					{ source: 7, target: 8 },
					{ source: 8, target: 9 }
				]
			};

			//Initialize a default force layout, using the nodes and edges in dataset
			var force = d3.layout.force()
								 .nodes(dataset.nodes)
								 .links(dataset.edges)
								 .size([w, h])
								 .linkDistance([50])
								 .charge([-100])
								 .start();

			var colors = d3.scale.category10();

			//Create SVG element
			var svg = d3.select("body")
						.append("svg")
						.attr("width", w)
						.attr("height", h);
			
			//Create edges as lines
			var edges = svg.selectAll("line")
				.data(dataset.edges)
				.enter()
				.append("line")
				.style("stroke", "#ccc")
				.style("stroke-width", 1);
			
			//Create nodes as circles
			var nodes = svg.selectAll("circle")
				.data(dataset.nodes)
				.enter()
				.append("circle")
				.attr("r", 10)
				.style("fill", function(d, i) {
					return colors(i);
				})
				.call(force.drag);
			
			//Every time the simulation "ticks", this will be called
			force.on("tick", function() {

				edges.attr("x1", function(d) { return d.source.x; })
					 .attr("y1", function(d) { return d.source.y; })
					 .attr("x2", function(d) { return d.target.x; })
					 .attr("y2", function(d) { return d.target.y; });
			
				nodes.attr("cx", function(d) { return d.x; })
					 .attr("cy", function(d) { return d.y; });
	
			});


		script>
	body>
html>

c52ab746ede185191e299a9fedbf2e6a.png

地图



<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>D3: Setting path fills dynamically to generate a choroplethtitle>
		<script type="text/javascript" src="../d3/d3.v3.js">script>
		<style type="text/css">
			/* No style rules here yet */		
		style>
	head>
	<body>
		<script type="text/javascript">

			//Width and height
			var w = 500;
			var h = 300;

			//Define map projection
			var projection = d3.geo.albersUsa()
								   .translate([w/2, h/2])
								   .scale([500]);

			//Define path generator
			var path = d3.geo.path()
							 .projection(projection);
							 
			//Define quantize scale to sort data values into buckets of color
			var color = d3.scale.quantize()
								.range(["rgb(237,248,233)","rgb(186,228,179)","rgb(116,196,118)","rgb(49,163,84)","rgb(0,109,44)"]);
								//Colors taken from colorbrewer.js, included in the D3 download

			//Create SVG element
			var svg = d3.select("body")
						.append("svg")
						.attr("width", w)
						.attr("height", h);

			//Load in agriculture data
			d3.csv("us-ag-productivity-2004.csv", function(data) {

				//Set input domain for color scale
				color.domain([
					d3.min(data, function(d) { return d.value; }), 
					d3.max(data, function(d) { return d.value; })
				]);

				//Load in GeoJSON data
				d3.json("us-states.json", function(json) {

					//Merge the ag. data and GeoJSON
					//Loop through once for each ag. data value
					for (var i = 0; i < data.length; i++) {
				
						//Grab state name
						var dataState = data[i].state;
						
						//Grab data value, and convert from string to float
						var dataValue = parseFloat(data[i].value);
				
						//Find the corresponding state inside the GeoJSON
						for (var j = 0; j < json.features.length; j++) {
						
							var jsonState = json.features[j].properties.name;
				
							if (dataState == jsonState) {
						
								//Copy the data value into the JSON
								json.features[j].properties.value = dataValue;
								
								//Stop looking through the JSON
								break;
								
							}
						}		
					}

					//Bind data and create one path per GeoJSON feature
					svg.selectAll("path")
					   .data(json.features)
					   .enter()
					   .append("path")
					   .attr("d", path)
					   .style("fill", function(d) {
					   		//Get data value
					   		var value = d.properties.value;
					   		
					   		if (value) {
					   			//If value exists…
						   		return color(value);
					   		} else {
					   			//If value is undefined…
						   		return "#ccc";
					   		}
					   });
			
				});
			
			});
			
		script>
	body>
html>
$
\frac{\partial C}{\partial \theta} 
&=& 
\frac{1}{m} \sum_{i=1}^m 
\left[ \sigma\left(\theta^{\rm T} x^{(i)} \right) - y^{(i)} \right]
x^{(i)}\\
&=&
\frac{1}{m} 
X^{\rm T}
\left[ \sigma\left(X \theta \right) - y \right]
$

你可能感兴趣的:(可视化)