码迷,mamicode.com
首页 > 其他好文 > 详细

D3入门系列(2)--简单的条形图、折线图

时间:2017-12-22 17:02:15      阅读:803      评论:0      收藏:0      [点我收藏+]

标签:常用   颜色   dba   区间   asc   jpg   pen   关系   返回值   

SVG画布

HTML 5 提供两种强有力的“画布”:SVG 和 Canvas。

SVG的特点:

  • SVG 绘制的是矢量图,因此对图像进行放大不会失真
  • 基于 XML,可以为每个元素添加 JavaScript 事件处理器
  • 每个图形均视为对象,更改对象的属性,图形也会改变
  • 不适合游戏应用

Canvas特点:

  • 绘制的是位图,图像放大后会失真
  • 不支持事件处理器
  • 能够以 .png 或 .jpg 格式保存图像
  • 适合游戏应用

那么,对于数据可视化,SVG的优势就显而易见了,而且D3中很多图形生成器也是只支持SVG的

注意,在 SVG 中,x 轴的正方向是水平向右,y 轴的正方向是垂直向下的

Step1  添加SVG画布

 1  var width = 400;  //画布的宽度
 2  var height = 400;   //画布的高度
 3  
 4  var svg = d3.select("body")     //选择文档中的body元素
 5      .append("svg")          //添加一个svg元素
 6      .attr("width", width)       //设定宽度
 7      .attr("height", height);    //设定高度
 8 
 9 //画布周边的空白
10  var padding = {left:30, right:30, top:20, bottom:20};

如此,便可以在画布上作图了

比例尺

利用比例尺的目的主要是将某一区域的值映射到另一区域,其大小关系不变,也就是说,让图形自适应画布的大小。

在数学中,x 的范围被称为定义域,y 的范围被称为值域。D3 中的比例尺,也有定义域和值域,分别被称为 domain 和 range。开发者需要指定 domain 和 range 的范围,如此即可得到一个计算关系。

D3中的比例尺最常用的有两种:

线性比例尺

d3.scale.linear() 返回一个线性比例尺。domain() 和 range() 分别设定比例尺的定义域和值域

 1 var dataset = [1.2, 2.3, 0.9, 1.5, 3.3];
 2 
 3 var min = d3.min(dataset);
 4 var max = d3.max(dataset);
 5 
 6 var linear = d3.scale.linear()
 7         .domain([min, max])
 8         .range([0, 300]);
 9 
10 linear(0.9);    //返回 0
11 linear(2.3);    //返回 175
12 linear(3.3);    //返回 300

注意:d3.scale.linear() 的返回值,是可以当做函数来使用的。因此,才有这样的用法:linear(0.9)。

序数比例尺

d3.scale.ordinal() 返回一个线性比例尺。domain() 和 range() 分别设定比例尺的定义域和值域

 1 var index = [0, 1, 2, 3, 4];
 2 var color = ["red", "blue", "green", "yellow", "black"];
 3 
 4 var ordinal = d3.scale.ordinal()
 5         .domain(index)
 6         .range(color);
 7 
 8 ordinal(0); //返回 red
 9 ordinal(2); //返回 green
10 ordinal(4); //返回 black

 0 对应颜色 red,1 对应 blue,依次类推

Step2  定义数据和比例尺

 1  var dataset=[10, 20, 30, 40, 33, 24, 12, 5];
 2  
 3  //x轴
 4  var xScale=d3.scale.ordinal()
 5               .domain(d3.range(dataset.length))
 6               .rangeRoundBands([0,width-padding.left-padding.right]);
 7  
 8  //y轴
 9  var yScale=d3.scale.linear()
10               .domain([0,d3.max(dataset)])
11               .range([height-padding.top-padding.bottom,0]);//y轴正方向向下

ordinal.rangeRoundBands - 用几个离散区间来分割一个连续的区间,区间边界和宽度会取整

 坐标轴

D3中用于定义坐标轴的组件:d3.svg.axis()

 1 //数据
 2 var dataset = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];
 3 //定义比例尺,其中使用了数组dataset
 4 var linear = d3.scale.linear()
 5       .domain([0, d3.max(dataset)])
 6       .range([0, 250]);
 7 //定义坐标轴,其中使用了线性比例尺linear
 8 var axis = d3.svg.axis()
 9      .scale(linear)      //指定比例尺
10      .orient("bottom")   //指定刻度的方向
11      .ticks(7);          //指定刻度的数量

 追加到画布上:

1 svg.append("g")
2   .attr("class","axis")
3   .attr("transform","translate(20,130)")
4   .call(axis);  

注意: svg.append("g").call(axis); 与 axis(svg.append(g)); 是相等的。

为axis设定样式(y也是常用的样式了)

<style>
.axis path,
.axis line{
    fill: none;
    stroke: black;
    shape-rendering: crispEdges;
}

.axis text {
    font-family: sans-serif;
    font-size: 11px;
}
</style>

Step3  定义坐标轴

1 //定义x轴
2 var xAxis = d3.svg.axis()
3     .scale(xScale)
4     .orient("bottom");
5         
6 //定义y轴
7 var yAxis = d3.svg.axis()
8     .scale(yScale)
9     .orient("left");

Step4  添加矩形和文字元素

//矩形之间的空白
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; });

Step5  添加坐标轴元素

 1 //添加x轴
 2 svg.append("g")
 3   .attr("class","axis")
 4   .attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
 5   .call(xAxis); 
 6         
 7 //添加y轴
 8 svg.append("g")
 9   .attr("class","axis")
10   .attr("transform","translate(" + padding.left + "," + padding.top + ")")
11   .call(yAxis);

 

折线图

 1     //定义画布
 2     var width=400;
 3     var height=400;
 4 
 5     var svg=d3.select("body")
 6               .append("svg")
 7               .attr("width",width)
 8               .attr("height",height);
 9     //定义内边距
10     var padding={left:20,right:20,top:10,bottom:10};
11     
12     //数据
13     var dataset=[11,35,23,78,55,18,98,100,22,65]
14     //定义比例尺
15     var xscale=d3.scale.linear()
16                  .domain([0,dataset.length-1])
17                  .range([0,width-padding.left-padding.right])
18     var yscale=d3.scale.linear()
19                  .domain([0,d3.max(dataset)])
20                  .range([height-padding.top-padding.bottom,0])
21     //绘制坐标轴
22     var xAxis=d3.svg.axis()
23                 .scale(xscale)
24                 .orient("bottom")
25     var yAxis=d3.svg.axis()
26                 .scale(yscale)
27                 .orient("left")
28     d3.select("svg")
29      .append("g")
30      .attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
31      .call(xAxis)
32      .attr("class","axis")
33      
34     d3.select("svg")
35      .append("g")
36      .attr("transform","translate("+padding.left+","+padding.top+")")
37      .call(yAxis)
38      .attr("class","axis")
39 
40     
41     //绘制图形
42     var line_generator=d3.svg.line()
43                          .x(function(d,i){
44                              return xscale(i)//x轴的点用数据下标表示
45                          })
46                          .y(function(d){
47                              return yscale(d)
48                          });
49                          //.interpolate("linear")
50     var g=svg.append("g")
51             .attr("transform","translate("+padding.left+","+padding.top+")")
52 
53     
54     g.append("path")
55       .attr("d",line_generator(dataset))
56       .attr(‘stroke‘, ‘black‘)
57       .attr(‘stroke-width‘, 1)
58       .attr("fill","none")

 

D3入门系列(2)--简单的条形图、折线图

标签:常用   颜色   dba   区间   asc   jpg   pen   关系   返回值   

原文地址:http://www.cnblogs.com/Hyacinth-Yuan/p/8059734.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!