首页 > Web开发 > 详细

vue整合d3.v5.js制作折线图

时间:2019-04-10 17:48:38      阅读:362      评论:0      收藏:0      [点我收藏+]

先上效果图(x轴固定为时间轴):

技术分享图片

图中出现的悬浮框是鼠标悬停效果

 

1、环境说明:

vue版本:"vue": "^2.5.2"
d3版本:"d3": "^5.9.1"

2、Line.vue源码

  1 <template>
  2   <div class="line" :id="id">
  3   </div>
  4 </template>
  5 
  6 <script>
  7   import * as d3 from d3
  8   export default {
  9     name: line,
 10     props: {
 11       id: String,
 12       width: Number,
 13       height: Number,
 14       dataset: Array
 15     },
 16     mounted() {
 17       this.init();
 18     },
 19     methods: {
 20       init() {
 21         d3.select("#svg" + this.id).remove();
 22         let width = this.width ? this.width : 600;
 23         let height = this.height ? this.height : 600;
 24         let padding = {
 25           left: 80,
 26           right: 50,
 27           top: 50,
 28           bottom: 50
 29         }
 30         let colorZ = d3.scaleOrdinal(d3.schemeDark2)
 31         let parseTime = d3.timeParse("%Y-%m-%d")
 32         let xScale = d3.scaleTime().range([0, width - padding.left - padding.right])
 33         let dates = this.dataset.flatMap((d) => d.value.map(v => parseTime(v.key)))
 34         xScale.domain([d3.min(dates), d3.max(dates)])
 35         let yScale = d3.scaleLinear().range([height - padding.top - padding.bottom, 0])
 36         yScale.domain([0, d3.max(this.dataset.flatMap((d) =>  d.value.map( v => v.value) )) + 2])
 37         let xAxis = d3.axisBottom(xScale).tickFormat(d => d.getFullYear() + - + (d.getMonth() + 1) + - + d.getDate())
 38         let yAxis = d3.axisLeft(yScale)
 39         let svg = d3.select("#" + this.id).append("svg").attr("width", width).attr("height", height).attr("id", "svg" + this.id);
 40         svg.append(g) 42           .attr(transform, translate( + padding.left + , + (height - padding.bottom) + ))
 43           .call(xAxis)
 44           .selectAll(text)
 45           .attr(dx, -20)
 46           .attr(dy, 10)
 47           .attr(transform, rotate(-20))
 48           .style(font-weight, bold)
 49         svg.append(g) 51           .attr(transform, translate( + padding.left + , + padding.top + ))
 52           .call(yAxis)
 53           .selectAll(text)
 54           .style(font-weight, bold)
 55         let line = d3.line().x(d => xScale(parseTime(d.key))).y(d => yScale(d.value))
 56         this.dataset.forEach((v, vi) => {
 57           let tp_x = 0,
 58             tp_y =0;
 59           svg.append("path")
 60             .attr(d , line(v.value))
 61             .attr(transform, translate( + padding.left + , + padding.top + ))
 62             .attr(fill, none)
 63             .attr(stroke, (d, i) => colorZ(vi))
 64             .attr("stroke-width", 2)
 65             .style(stroke-dasharray, function(d, i) {
 66               return d3.select(this).node().getTotalLength();
 67             })
 68             .style(stroke-dashoffset, function(d, i) {
 69               return d3.select(this).node().getTotalLength();
 70             })
 71             .transition()
 72             .duration(2000)
 73             .ease(d3.easePolyOut)
 74             .delay((d, i) => i * 200)
 75             .style(stroke-dashoffset, 0)
 76           svg.selectAll(circle1)
 77             .data(v.value)
 78             .enter()
 79             .append(circle)
 80             .attr(cx, (d, i) => {
 81               let x = xScale(parseTime(d.key))
 82               if (i === v.value.length - 1) tp_x = x - 40
 83               return x
 84             })
 85             .attr(cy, (d, i) => {
 86               let y = yScale(d.value)
 87               if (i === v.value.length - 1) tp_y = y - 10
 88               return y
 89             })
 90             .attr(r, 2)
 91             .attr(transform, translate( + padding.left + , + padding.top + ))
 92             .style("fill", (d, i) => colorZ(vi))
 93             .on("mouseover", (d, i) => {
 94               let g = svg.append(g)
 95                 .attr(id, `hoverg${vi}${d.key}${d.value}`)
 96                 .attr("transform", "translate(" + (xScale(parseTime(d.key)) - 20) + "," + (yScale(d.value) + 30)  + ")" )
 97               g.append("rect")
 98                 .attr("x", function(d){ return this.parentNode.getBBox().x - 3;})
 99                 .attr("y", function(d, i){ return  this.parentNode.getBBox().y - 20})
100                 .attr("width", 110)
101                 .attr("height", 25)
102                 .style("fill", "#fffbf0")
103               g.append(text)
104                 .text(`${d.key}:${d.value}`)
105                 .style("fill", colorZ(vi))
106             })
107             .on("mouseout", (d) => d3.select(`#hoverg${vi}${d.key}${d.value}`).remove())
108             .transition()
109             .duration(1500)
110             .ease(d3.easePolyIn)
111             .delay((d, i) => i * 200)
112             .attr(r, 5)
113           // svg.selectAll(‘text1‘)
114           //   .data([v.name])
115           //   .enter()
116           //   .append(‘text‘)
117           //   .attr(‘dx‘, (d, i) => tp_x)
118           //   .attr(‘dy‘, (d, i) => tp_y)
119           //   .attr(‘transform‘, ‘translate(‘ + padding.left + ‘,‘ + padding.top + ‘)‘)
120           //   .text((d) => d)
121           //   .style("fill", (d, i) => colorZ(vi))
122           //   .style(‘font-weight‘, ‘bold‘)
123           svg.append(text)
124             .attr(dx, tp_x)
125             .attr(dy, tp_y)
126             .attr(transform, translate( + padding.left + , + padding.top + ))
127             .text(v.name)
128             .style("fill", colorZ(vi))
129             .style(font-weight, bold)
130         })
131       }
132     },
133     watch: {
134       dataset() {
135         this.init();
136       }
137     }
138   }
139 </script>
140 
141 <style>
142 
143 </style>

3、使用示例

 1 <template>
 2   <div id="test">
 3     <!-- 一定要传进去一个id,随便传一个 -->
 4     <line id="line" :dataset="data1"></line>
 5   </div>
 6 </template>
 7 
 8 <script>
 9   import line from @/components/d3/Line
10   export default {
11     name: test,
12     data() {
13       return {
14         data1: [
15           {
16             name: 哈尔滨,
17             value: [{key: 2015-1-1, value: 10}, {key: 2015-1-2, value: 12}, {key: 2015-1-3, value: 13}, {key: 2015-1-17, value: 17}]
18           },
19           {
20             name: 海南,
21             value: [{key: 2015-1-1, value: 9}, {key: 2015-1-2, value: 48}, {key: 2015-1-3, value: 5}, {key: 2015-1-17, value: 49}]
22           },
23           {
24             name: 天津,
25             value: [{key: 2015-1-2, value: 30}, {key: 2015-1-3, value: 1}, {key: 2015-1-4, value: 32}, {key: 2015-1-5, value: 10}]
26           }
27         ]
28       }
29     },
30     components: {
31       line
32     },
33     methods: {
34 
35     }
36   }
37 </script>
38 
39 <style scoped>
40 </style>

4、参考资料

https://github.com/d3/d3-scale-chromatic/blob/master/README.md#schemeCategory10

https://github.com/d3/d3-time-format#format

https://jakearchibald.com/2013/animated-line-drawing-svg/

 

vue整合d3.v5.js制作折线图

原文:https://www.cnblogs.com/floud/p/10684839.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!