html如何绘制面积图,Learning D3.js(7) 面积(area)图与缩放查看(1)

这一次我们要做一个实用性比较强的图表:带缩略图拖拽查看的面积图。

面积图强调数量随时间而变化的程度,是非常常用的可视化图表

最终demohttp://www.d3js.cn/demo/brush.html

本次的demohttp://www.d3js.cn/demo/brush2.html

首先我们观察下效果图

上面的效果图是由两个面积图组成的。我们首先要绘制出这两个静态的图表,然后根据d3js提供的强大工具来制作缩略拖拽查看的效果.

首先定义好图表尺寸

var margin = {top: 10, right: 10, bottom: 100, left: 40},

//上图位置

margin2

= {top: 430, right: 10, bottom: 20, left:

40},//下图位置

width

= 960 - margin.left - margin.right,//总宽

height

= 500 - margin.top - margin.bottom,//总高

height2

= 500 - margin2.top - margin2.bottom;//下图宽度

之后我们建立一个工具函数,来格式化时间

var parseDate = d3.time.format("%b %Y").parse;

//format

d3.time.format方法是非常有用的一个函数。可以通过设置一定的传入格式来格式化时间。注意,若要返回转换后的时间对象,需要使用parse函数。

此处%b表示月份的缩写,%Y表示一个带有世纪的年份 (比如2012年,而不是12年)

这一类的参数详解可以参考apihttps://github.com/mbostock/d3/wiki/Time-Formatting

比如我的原始数据源是Jan 2000

可以使用

d3.time.format("%b %Y").parse('Jan 2000')

来得到时间对象.那么这个时间对象是啥呢,他是javascript标准的时间对象。通过这个对象,可以非常方便的取得各种想要的时间单位。

比如

d3.time.format("%b %Y").parse('Jan

2000').getFullYear()//返回2000

具体可以参考http://www.w3cschool.cn/jsref_obj_date.html

之后因为出现了坐标轴,我们需要绘制坐标轴。绘制坐标轴需要使用axis系列api。大家可以复习下第三篇

axis

http://www.civn.cn/p/12474.html注意绘制坐标轴的步骤一定要掌握

1.规定数据范围

利用x.scale.linear之类api配合range

2.构造坐标轴

var xAxis = d3.svg.axis()

.scale(数据范围)

.orient(排列方式)

3.把坐标轴插入到图表中

图表.append("g")

.attr("class",

"坐标轴class")

.call(坐标轴);

遵循以上的步骤,就可以轻松绘制坐标轴了。

var x = d3.time.scale().range([0, width]), //建立数据容器

把数值转为时间标度再转为宽度

x2

= d3.time.scale().range([0, width]),

y

= d3.scale.linear().range([height, 0]),//直线标度 Learning

D3.js(1)学习制作一个柱形图/直方图

y2

= d3.scale.linear().range([height2, 0]);

var xAxis =

d3.svg.axis().scale(x).orient("bottom"),//制作上图的X轴

xAxis2

=

d3.svg.axis().scale(x2).orient("bottom"),//制作下图的X轴

yAxis

= d3.svg.axis().scale(y).orient("left");//制作上图的Y轴

之后我们要开始绘制area(面积)了。上期教程大家应该已经明白chord的形状绘制也是通过path进行的。d3的area方法,同样返回的是path。大家可以复习下上期教程http://www.civn.cn/p/12629.html

area的api可以参考https://github.com/mbostock/d3/wiki/SVG-Shapes#wiki-area

官方推荐的一个一般写法

var x = d3.scale.linear().range([0, w]),

y

= d3.scale.linear().range([h, 0]);

var area = d3.svg.area()

.x(function(d)

{ return x(d.x); })

.y0(h)

.y1(function(d)

{ return y(d.y); });

x表示数据在横坐标的位置,y0可以认为是总高度,y1表示数据在纵坐标的高度

现在我们来生成这个area的path

var area = d3.svg.area()//生成上图area

注意这个area是一个path,要利用attr(d)加载进去

.x(function(d)

{ return x(d.date); })

.y0(height)

//https://github.com/mbostock/d3/wiki/SVG-Shapes#wiki-area

.y1(function(d)

{ return y(d.price); });

var area2 = d3.svg.area()//生成下图area

.x(function(d)

{ return x2(d.date); })

.y0(height2)

.y1(function(d)

{ return y2(d.price); });

之后给这两个area图造空间,扔进去。

var svg = d3.select("body").append("svg")//主容器

.attr("width",

width margin.left margin.right)

.attr("height",

height margin.top margin.bottom);

var focus = svg.append("g")//制作上图容器

.attr("transform",

"translate(" margin.left "," margin.top ")");

var context = svg.append("g")//制作下图容器

.attr("transform",

"translate(" margin2.left "," margin2.top ")");

注意属性设置的跟开始设置好的边距一致。

现在图表的结构基本制作好了。我们需要引入数据。数据文件:http://www.d3js.cn/demo/data.csv

D3js提供了非常多的方法来加载外部数据,这里我们使用d3.csv方法来加载数据

api可以参考https://github.com/mbostock/d3/wiki/CSV

这个方法会发起一个HTTP

GET请求,去请求指定的url下以逗号分隔的(CSV)文件。这个文件的内容被认为是符合RFC4180-compliant规范的。请求是异步处理的。当CSV数据有效后,会调用回调函数,传入数据作为参数。如果一个错误发生时,回调函数也会被调用,这时候可以在回调函数里捕获error。传入后的数据会调用d3.csv.parse函数。例如:

Year,Make,Model,Length

1997,Ford,E350,2.34

2000,Mercury,Cougar,2.38

解析后

[

{"Year": "1997", "Make":

"Ford", "Model": "E350", "Length": "2.34"},

{"Year": "2000", "Make":

"Mercury", "Model": "Cougar", "Length": "2.38"}

]

变为数组。因此我们可以利用foreach等方法来遍历之,也可以循环遍历

d3.csv("data.csv", function(error, data)

{//利用csv方法读取数据

data.forEach(function(d)

{//遍历数据

d.date

= parseDate(d.date);//读取date并转换为时间对象

d.price

= d.price;

});

x.domain(d3.extent(data.map(function(d)

{ return d.date; })));//利用domain方法给数据容器匹配上数据

y.domain([0,

d3.max(data.map(function(d) { return d.price;

}))]);

x2.domain(x.domain());

y2.domain(y.domain());

//添加上面图的图表

focus.append("path")

.datum(data)

.attr("d",

area);

//添加上面图的XY坐标轴

focus.append("g")

.attr("class",

"x axis")

.attr("transform",

"translate(0," height ")")

.call(xAxis);

focus.append("g")

.attr("class",

"y axis")

.call(yAxis);

//添加下面图的图表

context.append("path")

.datum(data)

.attr("d",

area2);

//添加下面图的X坐标轴

context.append("g")

.attr("class",

"x axis")

.attr("transform",

"translate(0," height2 ")")

.call(xAxis2);

});

之后我们利用call方法绑定两个坐标轴,再把两个绘制好的area利用attr的d属性添加进去,就大功告成了。

本次的demohttp://www.d3js.cn/demo/brush2.html

作者:新浪微博

Learning D3.js 系列

原文链接:http://www.civn.cn/p/13322.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值