D3入门学习

来源:互联网 发布:respawn linux 编辑:程序博客网 时间:2024/06/06 01:13

D3是一个数据可视化工具,都说挺好。但是我个人这两天的体验来看,D3想要入门不是太简单,至少至少都要有HTML和JavaScript基础才行,对JavaScript的DOM要求也有点高。
其实网上也能找到很多学习资源。下面是我搜集的一些教程:
这里写图片描述

D3呢就是一个js库,使用它主要是用来做数据可视化的,官网上有很多酷炫的例子。
D3的官网

我最近学习的教程:
慕课网:使用D3制作图表
极客学院:D3.js入门教程

这两个教程对于初学者还是比较友好的,我前两天对D3还是一无所知,现在已经可以get到用D3画线图,面积图,柱状图,饼状图的方法了。


下面是我对画这几种图表的笔记:

线性图表

线性图表应该是最简单的图表了,我们从小学起就会画了,它可以用来描述两个变量之间的对应关系。
这里写图片描述
在绘制线性图表之前先在HTML文档中添加一个container容器,不要忘了引入D3的库文件。

index.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>D3-test-1</title>    <link rel="stylesheet" href="css/style.css"></head><body>    <div id="container"></div>    <script src="http://d3js.org/d3.v3.js"></script>    <script src="js/index.js"></script></body></html>

index.js

var width = 500,height = 250,margin = {left:50, top:30, right:20, bottom:20},g_width = width - margin.left - margin.right,g_height = height - margin.top - margin.bottom;//svgvar svg = d3.select("#container")   //选择container容器.append("svg")  //添加svg元素//定义宽高.attr("width",width)    .attr("height",height);var g = d3.select("svg").append("g").attr("transform","translate("+margin.left+","+margin.top+")");//g元素偏移//数据var data = [1, 2, 4, 8, 3, 2, 5];// 缩放函数,X轴线性缩放var scale_x = d3.scale.linear().domain([0,data.length-1])  // 输入范围.range([0,g_width]);    //输出范围//Y轴缩放函数var scale_y = d3.scale.linear().domain([0,d3.max(data)]).range([g_height,0]);//倒着写是为了让纵坐标在显示的时候是从下往上增大的(因为浏览器的左边原点在左上而数学习惯是在左下)  //绘制函数,line_generator是我们指定的绘制函数var line_generator = d3.svg.line().x(function(d,i) { return scale_x(i);})//X轴的点用数据的下标来表示.y(function(d) { return scale_y(d);}).interpolate("cardinal");//指定拟合方式,如果没有它,图是折线形式的,有了它就很圆润了//添加path路径,就可以绘图啦d3.select("g").append("path").attr("d",line_generator(data));//绘制X轴和Y轴var x_axis = d3.svg.axis().scale(scale_x),y_axis = d3.svg.axis().scale(scale_y).orient("left");   //orient("left")确定左边方向g.append("g").call(x_axis).attr("transform","translate(0,"+g_height+")"); //偏移g.append("g").call(y_axis)//添加文字元素.append("text").text("Price($)").attr("transform","rotate(-90)")    //Y轴旋转-90°.attr("text-anchor","end").attr("dy","1em");

js文件我都写了详细的注释。
style样式文件用来定义container容器,path路径以及坐标轴的一些样式。

style.css

#container {    background-color: #ccc;    width: 500px;    height: 250px;}path {    fill: none;    stroke: #468284;    stroke-width: 2;}.domain, .tick line {    stroke: gray;    stroke-width: 1;}

我觉得比较重要的就是选择元素select()和插入元素append() 操作,还有缩放函数的方法和定义X轴、Y轴的方法。这些都是基础又基础的东西!


面积图表

面积图表是在线性图表的基础上绘制的
这里写图片描述

将绘制函数改为area()函数:

//绘制函数,面积图用D3的area()函数绘制var area_generator = d3.svg.area().x(function(d,i) { return scale_x(i);}).y0(g_height).y1(function(d) { return scale_y(d);}).interpolate("cardinal");

这个时候图表已经成为一个闭合的图形了:
这里写图片描述

在绘制图形后在添加一个填充样式.style("fill","#468284"):

d3.select("g").append("path").attr("d",area_generator(data)).style("fill","#468284");

一个面积图表就完成了。


柱状图表

这里写图片描述

柱状图的要点是添加矩形元素。这里跟上面线性图表的代码风格不太一样,是因为我觉得这个demo更直观,更清晰。

<html>  <head>      <meta charset="utf-8">      <title>完整的柱形图</title>  </head> <style>    .axis path,    .axis line{        fill: none;        stroke: black;        shape-rendering: crispEdges;    }    .axis text {        font-family: sans-serif;        font-size: 11px;    }    .MyRect {        fill: steelblue;    }    .MyText {        fill: white;        text-anchor: middle;    }</style><body>      <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>      <script>    //画布大小    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);    });    //添加文字元素    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;    });    //添加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);</script>  </body>  </html>  

要特别注意的地方是理解enter() 的用法,在极客学院的教程上是这样讲的:

有数据,而没有足够图形元素的时候,使用此方法可以添加足够的元素。
如果数组为 [3, 6, 9, 12, 15],将此数组绑定到三个 p 元素的选择集上。可以想象,会有两个数据没有元素与之对应,这时候 D3 会建立两个空的元素与数据对应,这一部分就称为 Enter。而有元素与数据对应的部分称为 Update。如果数组为 [3],则会有两个元素没有数据绑定,那么没有数据绑定的部分被称为 Exit。示意图如下所示。

这里写图片描述

外部数据文件的读取

慕课网的教程讲到了外部数据文件的读取,我觉得挺有用的
值得注意的一点是浏览器读取本地文件,它有一个跨域请求的问题,会报如下的错误:
这里写图片描述
解决办法是使用server提供的一种访问机制,用Python启用服务器,你要是想运行呢,首先你要安装python,下面是python2.到3以下版本执行的命令

python -m SimpleHTTPServer 8888 &

3以上用下面的命令

python -m http.server 8888 &

启用服务是在当前图表文件内运行的,启用服务后在浏览器中输入localhost:8888 就可以访问自己写的图表了
我们要读取的数据文件名为data.csv

year,population1953,5.941964,6.951982,10.081990,11.342000,12.662010,13.40

6次人口普查的数据,这里用到了D3的d3.csv(url[,accessor][,callback])函数,以下面的函数为例,第一个参数是必选的,是我们要读取的csv文件的路径;第二个参数是数据的处理,定义一个type函数将字符串转换为数值的形式;第三个参数用一个函数调用的方式使用数据,把最终的数据放到data数组当中。

d3.csv("data.csv",type,function(data) {    console.log(data);    ···});function type(d) {    d.population =+ d.population;    return d;}

这里写图片描述

饼状图表

这里写图片描述

饼状图表的要点就是:第一我们要用d3.svg.arc() 画圆的函数;第二就是起始角度的设置:
HTML还是像线性图表一样定义一个container容器即可

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>饼状图表</title>    <link rel="stylesheet" href="css/style.css"></head><body>    <div id="container"></div>    <script src="http://d3js.org/d3.v3.js"></script>    <script src="js/index.js"></script></body></html>

数据文件data.csv

education,population大专及以上,11964高中和中专,18799初中,51966小学,35876文盲人口,5466

index.js

d3.csv("data.csv",type,function(data) {    var width = 400,    height = 400;    // 添加svg画布    var svg = d3.select("#container")    .append("svg")    .attr("width",width)    .attr("height",height);    // 添加g元素    var g = svg.append("g")    .attr("transform","translate(200,200)");    // 定义一个饼状图    var arc_generator = d3.svg.arc()    .innerRadius(0)    .outerRadius(200);    // 起始角度    var angle_data = d3.layout.pie()    .value(function(d) {return d.population;});    // 颜色    var color = d3.scale.category10();    // 绑定数据    g.selectAll("path")    .data(angle_data(data))    .enter()    // 添加path元素    .append("path")    .attr("d",arc_generator)    .style("fill",function(d,i){return color(i);});    // 添加文字标签    g.selectAll("text")    .data(angle_data(data))    .enter()    // 添加text元素    .append("text")    .text(function(d) {return d.data.education;})    .attr("transform", function(d){return "translate("+arc_generator.centroid(d)+")";})    .attr("text-anchor","middle");});function type(d) {    d.population = +d.population;    return d;}
0 0
原创粉丝点击