# 折线图
## 需求
某小超市一周盈利统计如下。纯收入分别是:820, 932, 901, 934, 1290, 1330, 1320。绘制一个折线图来实现数据展示。
![](https://box.kancloud.cn/fd823f7ac8028fbc19f80a139dd3b091_749x511.png)
## 分析
拆分需要绘制哪些:
1. x轴为板块
2. y轴为收入值
3. 中心的折线
4. y轴刻度的水平线
根据柱状图的对比,这次只需要再分析线条:
线条实现思路有两种:
1. 两点之间用line连接,最终拼接而成。
2. 使用path实现整个线条,使用d3.line绘制。这个的好处是,后期可以修改连线时的形式,比如使用贝塞尔方式,等等
再细化思路:
1. 首先构建一个svg,确定图表应该绘制的大小。
2. 分析数据哪个是y轴数据哪个是X轴数据,
3. 计算x,y轴的domain范围,可以使用d3.max,d3.min,d3.range等等
4. 构建比例尺。
5. 由于坐标轴需要留白,所以使用g标签通过transform进行移动。之后调用axis,绘制坐标轴。
6. 绘制折线,创建g标签通过transform进行移动,让其正好偏移至绘制区域。
7. 通过data绑定数据,之后通过使用d3.line定义如何绘制
## 绘制
``` javascript
//创建svg
var svg = d3.select('#root')
.append('svg')
.attr('width', 600)
.attr('height', 600)
.style("background-color","rgb(142, 137, 137)");
var margin=[100,100,100,100]
//模拟数据:
var data1 = ['周一','周二','周三','周四','周五','周六','周日']
var data = [820, 932, 901, 934, 1290, 1330, 1320]
//构建y轴的比例尺
var ymax = d3.max(data,function(d){console.log(d);return d})+100 //为了增大图表y的上限
var y=d3.scaleLinear()
.domain([0,ymax]).range([400,0])
var axisY = d3.axisLeft(y);
var axisYG = svg.append('g')
.attr('class','axisY')
.attr('transform','translate(100,100)')
.call(axisY);
//绘制innerY
axisYG.selectAll('g.tick')
.selectAll('line')
.attr('x1',-5)
.attr('x2',400)
.attr('stroke-dasharray','5, 5');
//构建x轴比例尺
var x = d3.scalePoint().domain(data1).range([0,400])
var axisX = d3.axisBottom(x)
var axisXG = svg.append('g')
.attr('class','axisY')
.attr('transform','translate(100,500)')
.call(axisX);
//绘制line
//构建一个默认为直线的线条绘制器
var line = d3.line()
.x(function(d,i) { return x(data1[i]); })
.y(function(d) {return y(d) });
//构建g进行偏移处理,构建path绑定数据后,调用绘制器line
svg.append('g')
.attr('transform','translate(100,100)')
.append('path')
.style('fill','none') //此处需要将处理是为了折线只显示线条
.style('stroke',"rgb(51, 209, 243)")
.style('stroke-width',3)
.datum(data)
.attr('d',line)
```
实际效果如:直线实例
现在我们需要做成下图形式的折线图改怎么做呢?
![](https://box.kancloud.cn/0e287784b58d2954ff6c867f1e073f66_729x509.png)
很简单我们只需要替换掉绘制器d3.line为d3.area就行
``` javascript
//更换为area绘制
var area = d3.area()
.x(function(d,i) { return x(data1[i]); })
.y1(function(d) {return y(d) })
.y0(y(0))
//构建g进行偏移处理,构建path绑定数据后,调用绘制器line
svg.append('g')
.attr('transform','translate(100,100)')
.append('path')
.style('fill','rgba(48, 214, 50, 0.73)') //此处需要将处理是为了折线只显示线条
.style('stroke',"rgb(51, 209, 243)")
.style('stroke-width',1)
.datum(data)
.attr('d',area)
```
实际效果如:区域折线实例
接下来 直线的连接方式显示上要求平滑,类似这种
![](https://box.kancloud.cn/f52449dbfc15ca69c5864156588f11bc_711x520.png)
很简单我们只需要修改一下d3.line的参数就行
``` javascript
//构建一个默认为直线的线条绘制器
var line = d3.line()
.x(function(d,i) { return x(data1[i]); })
.y(function(d) {return y(d) })
.curve(d3.curveBundle.beta(0.5))
```
关于曲线需要配置不同曲折度可以参考[d3.shape#curves](https://github.com/xswei/d3-shape/blob/master/README.md#curves)
## 实例
直线实例:[line0](https://doter1995.github.io/d3-start-course/line/line-0.html)
![](https://box.kancloud.cn/b581406c7c2b87e5c937eaf9952eafcb_562x511.png)
区域折线实例:[line1](https://doter1995.github.io/d3-start-course/line/line-1.html)
![](https://box.kancloud.cn/08120df3ad872782fe5f56fd1f347d7f_530x505.png)
曲线实例:[line0](https://doter1995.github.io/d3-start-course/line/line-2.html)
![](https://box.kancloud.cn/9cf18afe53641c3b174147126e55bb48_526x504.png)