先上效果图(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. 异想家Win7系统安装的软件与配置

    C盘推荐一个硬盘,256G以上,安装好驱动,激活Win7,备份一次系统(纯净)! 1.Mac.Linux时间同步(双系统时配置): 开始->运行->CMD,打开命令行程序(以管理员方式打开 ...

  2. ThreeJS 物理材质shader源码分析(像素着色器)

    再此之前推荐一款GLTF物理材质在线编辑器https://tinygltf.xyz/ 像素着色器(meshphysical_frag.glsl) #define PHYSICAL uniform ve ...

  3. Python使用requests发送post请求的三种方式

    1.我们使用postman进行接口测试的时候,发现POST请求方式的编码有3种,具体的编码方式如下: A:application/x-www-form-urlencoded ==最常见的post提交数 ...

  4. RAID磁盘冗余阵列

    RAID阵列分类 **一.RAID 0** 1.优点: 充分利用 I/O 总线性能使其带宽翻倍,读/写速度翻倍: 充分利用磁盘空间,利用率为 100%.2.缺点: 不提供数据冗余: 无数据检验,不能保 ...

  5. Leetcode 题目整理-6 Swap Nodes in Pairs & Remove Duplicates from Sorted Array

    24. Swap Nodes in Pairs Given a linked list, swap every two adjacent nodes and return its head. For ...

  6. springboot之整合基本的jdbc并操作Mysql数据库

    对于数据访问层,无论是SQL还是NOSQL,springboot默认采用整合spring data方式进行统一处理,添加大量自动配置,屏蔽了许多设置,引入各种xxxTemplate,xxxReposi ...

  7. IntelliJ IDEA 2020 的Debug功能也太好用了,真香!

    写在前边 作为一个有点强迫症的程序员来说,所有的应用软件.开发工具都必须要升级到最高版本,否则就会很难受到坐立不安.日思夜想.茶饭不思.至于什么时候得的这种病我也记不清了,哈哈哈 IntelliJ I ...

  8. LIBCMTD.lib与libcpmtd冲突的解决方法。

    error: 1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int) ...

  9. LeetCode 664. Strange Printer 奇怪的打印机(C++/Java)

    题目: There is a strange printer with the following two special requirements: The printer can only pri ...

  10. POJ_1376_bfs

    题目描述: 给定一个黑白格子的图,黑格子是障碍物,一个线段交点的起点,一个线段交点的终点和初始方向,机器人从起点开始,只能沿着线段,走到终点,期间不能沿着障碍物边缘和墙边缘. 一次操作可以向当前方向走 ...