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

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

1、环境说明:

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

2、Line.vue源码

 <template>
<div class="d3line" :id="id">
</div>
</template> <script>
import * as d3 from 'd3'
export default {
name: 'd3line',
props: {
id: String,
width: Number,
height: Number,
dataset: Array
},
mounted() {
this.init();
},
methods: {
init() {
d3.select("#svg" + this.id).remove();
let width = this.width ? this.width : ;
let height = this.height ? this.height : ;
let padding = {
left: ,
right: ,
top: ,
bottom:
}
let colorZ = d3.scaleOrdinal(d3.schemeDark2)
let parseTime = d3.timeParse("%Y-%m-%d")
let xScale = d3.scaleTime().range([, width - padding.left - padding.right])
let dates = this.dataset.flatMap((d) => d.value.map(v => parseTime(v.key)))
xScale.domain([d3.min(dates), d3.max(dates)])
let yScale = d3.scaleLinear().range([height - padding.top - padding.bottom, ])
yScale.domain([, d3.max(this.dataset.flatMap((d) => d.value.map( v => v.value) )) + ])
let xAxis = d3.axisBottom(xScale).tickFormat(d => d.getFullYear() + '-' + (d.getMonth() + ) + '-' + d.getDate())
let yAxis = d3.axisLeft(yScale)
let svg = d3.select("#" + this.id).append("svg").attr("width", width).attr("height", height).attr("id", "svg" + this.id);
svg.append('g')
.attr('transform', 'translate(' + padding.left + ',' + (height - padding.bottom) + ')')
.call(xAxis)
.selectAll('text')
.attr('dx', -)
.attr('dy', )
.attr('transform', 'rotate(-20)')
.style('font-weight', 'bold')
svg.append('g')
.attr('transform', 'translate(' + padding.left + ',' + padding.top + ')')
.call(yAxis)
.selectAll('text')
.style('font-weight', 'bold')
let line = d3.line().x(d => xScale(parseTime(d.key))).y(d => yScale(d.value))
this.dataset.forEach((v, vi) => {
let tp_x = ,
tp_y =;
svg.append("path")
.attr('d' , line(v.value))
.attr('transform', 'translate(' + padding.left + ',' + padding.top + ')')
.attr('fill', 'none')
.attr('stroke', (d, i) => colorZ(vi))
.attr("stroke-width", )
.style('stroke-dasharray', function(d, i) {
return d3.select(this).node().getTotalLength();
})
.style('stroke-dashoffset', function(d, i) {
return d3.select(this).node().getTotalLength();
})
.transition()
.duration()
.ease(d3.easePolyOut)
.delay((d, i) => i * )
.style('stroke-dashoffset', )
svg.selectAll('circle1')
.data(v.value)
.enter()
.append('circle')
.attr('cx', (d, i) => {
let x = xScale(parseTime(d.key))
if (i === v.value.length - ) tp_x = x -
return x
})
.attr('cy', (d, i) => {
let y = yScale(d.value)
if (i === v.value.length - ) tp_y = y -
return y
})
.attr('r', )
.attr('transform', 'translate(' + padding.left + ',' + padding.top + ')')
.style("fill", (d, i) => colorZ(vi))
.on("mouseover", (d, i) => {
let g = svg.append('g')
.attr('id', `hoverg${vi}${d.key}${d.value}`)
.attr("transform", "translate(" + (xScale(parseTime(d.key)) - ) + "," + (yScale(d.value) + ) + ")" )
g.append("rect")
.attr("x", function(d){ return this.parentNode.getBBox().x - ;})
.attr("y", function(d, i){ return this.parentNode.getBBox().y - })
.attr("width", )
.attr("height", )
.style("fill", "#fffbf0")
g.append('text')
.text(`${d.key}:${d.value}`)
.style("fill", colorZ(vi))
})
.on("mouseout", (d) => d3.select(`#hoverg${vi}${d.key}${d.value}`).remove())
.transition()
.duration()
.ease(d3.easePolyIn)
.delay((d, i) => i * )
.attr('r', )
// svg.selectAll('text1')
// .data([v.name])
// .enter()
// .append('text')
// .attr('dx', (d, i) => tp_x)
// .attr('dy', (d, i) => tp_y)
// .attr('transform', 'translate(' + padding.left + ',' + padding.top + ')')
// .text((d) => d)
// .style("fill", (d, i) => colorZ(vi))
// .style('font-weight', 'bold')
svg.append('text')
.attr('dx', tp_x)
.attr('dy', tp_y)
.attr('transform', 'translate(' + padding.left + ',' + padding.top + ')')
.text(v.name)
.style("fill", colorZ(vi))
.style('font-weight', 'bold')
})
}
},
watch: {
dataset() {
this.init();
}
}
}
</script> <style> </style>

3、使用示例

 <template>
<div id="test">
<!-- 一定要传进去一个id,随便传一个 -->
<d3line id="line" :dataset="data1"></d3line>
</div>
</template> <script>
import d3line from '@/components/d3/Line'
export default {
name: 'test',
data() {
return {
data1: [
{
'name': '哈尔滨',
'value': [{key: '2015-1-1', value: }, {key: '2015-1-2', value: }, {key: '2015-1-3', value: }, {key: '2015-1-17', value: }]
},
{
'name': '海南',
'value': [{key: '2015-1-1', value: }, {key: '2015-1-2', value: }, {key: '2015-1-3', value: }, {key: '2015-1-17', value: }]
},
{
'name': '天津',
'value': [{key: '2015-1-2', value: }, {key: '2015-1-3', value: }, {key: '2015-1-4', value: }, {key: '2015-1-5', value: }]
}
]
}
},
components: {
d3line
},
methods: { }
}
</script> <style scoped>
</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制作--折线图(line)的更多相关文章

  1. Vue整合d3.v5.js制作--柱状图(rect)

    先上效果图: 图中柱状图变成纯蓝色是鼠标滑动过的颜色(颜色可改,本人配色能力十分的强,建议直接用默认设置即可 ( ᖛ ̫ ᖛ )ʃ)) 1.环境说明 Vue版本:"vue": &q ...

  2. chart.js制作折线图

    <!DOCTYPE html> <html> <head> <title></title> </head> <script ...

  3. JFreeChart在制作折线图

    JFreeChart在制作折线图的时候可以使用两种不同的方式 package Line; import java.awt.Color; import java.awt.Font; import org ...

  4. Microsoft Excel Sheet/表格 制作折线图

    Microsoft Excel Sheet/表格 制作折线图 虽然比较简单,但是仍然需要稍微花一点功夫. 1.制作好表格数据 2.先将数据选定(不包括 横座标的 年月日或其他的刻度 的那一列) 3.插 ...

  5. 使用d3.v5实现饼状图

    效果图: 饼状图: 目录结构: <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  6. excel制作折线图太麻烦?试试这些折线图在线生成工具

    折线图是以折线的上升或下降来表示统计数量的增减变化的统计图,叫作折线统计图.用折线的起伏表示数据的增减变化情况,不仅可以表示数量的多少,而且可以反映数据的增减变化情况.并且折线图也是目前最方便的一种统 ...

  7. Python制作折线图

    利用python的第三方包Pygal制作简单的折线图. 申明:本文仅供学习交流使用.源码大部分来自<python编程从入门到实践>:如有侵权,请联系我删除. 1 #!usr/bin/env ...

  8. d3.js制作蜂巢图表带动画效果

    以上是效果图,本图表使用d3.js v4制作.图表主要功能是在六边形格子中显示数据,点击底部图标可以切换指定格子高亮显示,图表可以随浏览器任意缩放. 1.图表的主体结构是由正六边形组成,使用d3生成六 ...

  9. d3.js画折线图

    下载d3.zip,并解压到网页文件所在的文件夹 windows下,在命令行进入网页文件夹,输入 python -m http.server 在浏览器中输入127.0.0.1:8000/xxx.html ...

随机推荐

  1. 19_08_26校内训练[Max]

    题意 求$max_{l \leq r}{\{min{\{a_l,a_{l+1},...,a_r\}}*(r-l+1)\}}$ 思考 分治,考虑一个区间跨过某个点的贡献即可. 代码 #include&l ...

  2. android开发实战-记账本APP(二)

    继昨天的开发,继续完成今天的内容. (一)开始构建一些业务逻辑,开始构建记账本的添加一笔记账的功能. ①对fab按钮的click时间进行修改,创建一个AlertDialog.Builder对象,因此我 ...

  3. java操作数组转list集合删除元素报错ConcurrentModificationException

    public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>( ...

  4. 微信小程序如何创建云函数并安装wx-server-sdk依赖

    时间:2020/01/23 步骤 1.在微信开发者工具中云函数所在的文件夹的图标与其他文件夹是不同的,如下(第一个是云函数): 如果需要使一个普通文件变为云函数文件夹,需要在project.confi ...

  5. 004-OSI参考模型和分层思想

    OSI参考模型 应用层 所有能产生网络流量的程序 表示层 在传输之前是否进行加密或者压缩处理 涉及安全问题 会话层 Session 是建立在传输层之上,利用传输层提供的服务,使应用建立和维持会话,并能 ...

  6. mybatis缓存,从一个“灵异”事件说起

    刚准备下班走人,被一开发同事叫住,让帮看一个比较奇怪的问题:Mybatis同一个Mapper接口的查询方法,第一次返回与第二次返回结果不一样,百思不得其解! 问题 Talk is cheap. Sho ...

  7. HDU_5729_rmq+二分

    http://acm.hdu.edu.cn/showproblem.php?pid=5726 rmq修改成gcd的,关键是找个数,用二分来找,刚开始理解了好久,因为每个区间内gcd是递减的,所以可以优 ...

  8. 微信小程序开发技巧总结(二) -- 文件的选取、移动、上传和下载

    微信小程序开发技巧总结(二) -- 文件的选取.移动.上传和下载 1.不同类型文件的选取 1.1 常用的图片 视频 对于大部分开发者来说,需要上传的文件形式主要为图片,微信为此提供了接口. wx.ch ...

  9. 春招必问的redis持久化(RDB AOF),你能答上来么?

    春招面试模拟,如同雷同,纯属巧合!!! 面试的大体流程: 第一步:一般会有笔试题,也可能没有.有笔试题就要好好答了,因为会重视笔试结果,为了节约面试官时间,HR可能先会看,不合格直接让你走人了. 第二 ...

  10. kendo ui - core

    通过CDN 引入kendo-ui-core git地址:http://www.telerik.com/kendo-ui<link href="http://kendo.cdn.tele ...