vue项目中基于D3.js实现桑基图功能
前端实现数据可视化的方案有很多种,以前都是使用百度的echarts,使用起来很方便,直接按照特定的数据格式输入,就能实现相应的效果,虽然使用方便,但是缺点就是无法自定义一些事件操作,可自由发挥的功能很少,对于一些特殊要求的需求就无能为力了,而d3.js很好地解决了这个问题;
1、安装d3
npm install d3 --save
2、安装d3-sankey
npm install d3-sankey --save
3、引入对应的模块
import * as d3 from 'd3'
import * as d3Sankey from 'd3-sankey'
4、桑基图核心代码实现
methods: {
initHandle() {
let data = [
{
Survived: "Perished",
Sex: "Male",
Age: "Child",
Class: "Second Class",
value: 67
},
{
Survived: "Perished",
Sex: "Male",
Age: "Adult",
Class: "Crew",
value: 270
},
{
Survived: "Perished",
Sex: "Male",
Age: "Adult",
Class: "Crew",
value: 170
},
{
Survived: "Perished",
Sex: "Male",
Age: "Child",
Class: "Crew",
value: 610
},
{
Survived: "Perished",
Sex: "Male",
Age: "Adult",
Class: "Second Class",
value: 870
},
{
Survived: "Perished",
Sex: "Male",
Age: "Adult",
Class: "Crew",
value: 1670
},
{
Survived: "Perished",
Sex: "Male",
Age: "Child",
Class: "Crew",
value: 6370
},
{
Survived: "Perished",
Sex: "Male",
Age: "Adult",
Class: "Crew",
value: 10
},
{
Survived: "Perished",
Sex: "Male",
Age: "Adult",
Class: "Crew",
value: 370
}
]
data['columns'] = [
"Survived",
"Sex",
"Age",
"Class",
"value"
]
const keys = data.columns.slice(0, -1)
const sankey = d3Sankey.sankey()
.nodeSort(null)
.linkSort(null)
.nodeWidth(4)
.nodePadding(20)
.extent([[0, 5], [this.width, this.height - 5]])
function graph() {
let index = -1;
const nodes = [];
const nodeByKey = new Map;
const indexByKey = new Map;
const links = [];
for (const k of keys) {
for (const d of data) {
const key = JSON.stringify([k, d[k]]);
if (nodeByKey.has(key)) continue;
const node = {name: d[k]};
nodes.push(node);
nodeByKey.set(key, node);
indexByKey.set(key, ++index);
}
}
for (let i = 1; i < keys.length; ++i) {
const a = keys[i - 1];
const b = keys[i];
const prefix = keys.slice(0, i + 1);
const linkByKey = new Map;
for (const d of data) {
const names = prefix.map(k => d[k]);
const key = JSON.stringify(names);
const value = d.value || 1;
let link = linkByKey.get(key);
if (link) { link.value += value; continue; }
link = {
source: indexByKey.get(JSON.stringify([a, d[a]])),
target: indexByKey.get(JSON.stringify([b, d[b]])),
names,
value
};
links.push(link);
linkByKey.set(key, link);
}
}
return {nodes, links};
}
const color = d3.scaleOrdinal(["Perished"], ["#da4f81"]).unknown("#ccc")
const svg = d3.select("#box")
.append('svg')
.attr("width", this.width)
.attr("height", this.height);
const {nodes, links} = sankey({
nodes: graph().nodes.map(d => Object.assign({}, d)),
links: graph().links.map(d => Object.assign({}, d))
});
svg.append("g")
.selectAll("rect")
.data(nodes)
.join("rect")
.attr("x", d => d.x0)
.attr("y", d => d.y0)
.attr("height", d => d.y1 - d.y0)
.attr("width", d => d.x1 - d.x0)
.append("title")
.text(d => `${d.name}\n${d.value.toLocaleString()}`);
svg.append("g")
.attr("fill", "none")
.selectAll("g")
.data(links)
.join("path")
.attr("d", d3Sankey.sankeyLinkHorizontal())
.attr("stroke", d => color(d.names[0]))
.attr("stroke-width", d => d.width)
.style("mix-blend-mode", "multiply")
.append("title")
.text(d => `${d.names.join(" → ")}\n${d.value.toLocaleString()}`);
svg.append("g")
.style("font", "10px sans-serif")
.selectAll("text")
.data(nodes)
.join("text")
.attr("x", d => d.x0 < this.width / 2 ? d.x1 + 6 : d.x0 - 6)
.attr("y", d => (d.y1 + d.y0) / 2)
.attr("dy", "0.35em")
.attr("text-anchor", d => d.x0 < this.width / 2 ? "start" : "end")
.text(d => d.name)
.append("tspan")
.attr("fill-opacity", 0.7)
.text(d => ` ${d.value.toLocaleString()}`);
return svg.node();
}
}
其中的data数据暂时为固定数据,实际开发中可以调取后台接口获取。
html部分为:
<template>
<div class="app-container">
<div id="box"></div>
</div>
</template>
5、预览效果

后续可封装为通用组件,只需传入数据即可实现效果~~~
vue项目中基于D3.js实现桑基图功能的更多相关文章
- 1.在项目中使用D3.js
在项目中使用D3.js D3.js(全称:Data-Driven Documents)是一个基于数据操作文档的JavaScript库.D3帮助您使用HTML.SVG和CSS使数据生动起来.D3对web ...
- 在Vue项目里面使用d3.js
之前写一个 Demo里面 有些东西要使用d3实现一些效果 但是在很多论坛找资源都找不到可以在Vue里面使用D3.js的方法,npm 上面的D3相对来说 可以说是很不人性化了 完全没有说 在webpac ...
- 在vue项目中使用canvas-nest.js,报parameter 1 is not of type 'Element'
canvas-nest.js是一款轻量的网页特效,如图: github地址:https://github.com/hustcc/canvas-nest.js 在普通的html项目中,只要将<sc ...
- 在vue项目中的main.js中直接使用element-ui中的Message 消息提示、MessageBox 弹框、Notification 通知
需求来源:向后台请求数据时后台挂掉了,后台响应就出现错误,不做处理界面就卡住了,这时需要在main.js中使用axios的响应拦截器在出现相应错误是给出提示.项目使用element-ui,就调用里面的 ...
- vue项目中使用md5.js及base64.js
一.在项目根目录下安装 npm install --save js-base64 npm install --save js-md5 二.在项目文件中引入 import md5 from 'js-md ...
- vue项目中,main.js,App.vue,index.html如何调用
1.main.js是我们的入口文件,主要作用是初始化vue实例,并引入所需要的插件 2.App.vue是我们的主组件,所有页面都是在App.vue下进行切换的.其实你也可以理解为所有的路由也是App. ...
- 在vue项目中使用Nprogress.js进度条
NProgress是一款在网页顶部添加细长进度条的工具,非常轻巧,使用起来也非常便捷,灵感来源于Google, YouTube. 1.安装 $ npm install --save nprogress ...
- 如何在vue项目中使用md5.js及base64.js
一.在项目根目录下安装 npm install --save js-base64 npm install --save js-md5 二.在项目文件中引入 import md5 from 'js-md ...
- 【土旦】vue项目中 使用 pako.js 解密 gzip加密字符串
前言 今天跟后台对接一个接口,接受到一个加密的值,说是通过gzip加密过的,然后就蒙蔽了, 赶紧上百度找了一下资料,通过一篇文章(原文在底部)发现有个js库可以解密,就下载轻松解密了 实现代码 pok ...
随机推荐
- OneBlog开源博客-详细介绍如何实现freemarker自定义标签
前言 OneBlog中使用到了springboot + freemarker的技术,同时项目里多个controller中都需要查询一个公有的数据集合,一般做法是直接在每个controller的方法中通 ...
- spark:distinct算子实现原理
distinct的底层使用reducebykey巧妙实现去重逻辑 //使用reduceByKey或者groupbykey的shuffle去重思想rdd.map(key=>(key,null)). ...
- 编写 Dockerfile 生成自定义镜像
一般情况下我们可以从公共渠道诸如 DockerHub 获取镜像上获取镜像,但是在实际生产过程中,往往需要定制化的镜像,例如修改一些配置文件,增加一些特殊的命令或软件等需求,这时就需要通过编写 Dock ...
- 【渲染教程】使用3ds Max和ZBrush制作卡通风格的武器模型(上)
克里斯蒂娜·马丁(CristinaMartín)介绍了她的项目灵剑(Spirit Sword)的制作过程,并详细的展示了使用3ds Max和ZBrush制作模型,纹理绘画和最终展示的过程. 介绍 克里 ...
- vue 深度作用选择器
使用 scoped 后,父组件的样式将不会渗透到子组件中 如果想在使用scoped,不污染全局的情况下,依然可以修改子组件样式,可以使用深度作用选择器 .tree{ width: 100%; floa ...
- Docker Java 镜像基础(四)
基于官方提供的centos 7.2.1511 基础镜像构建JDK 和tomcat 镜像,先构建JDK镜像,然后在基于JDK镜像构建tomcat镜像 构建 centos:latest 基础镜像: # 下 ...
- Mac安装homebrew,postman,charles
Homebrew是一款Mac OS平台下的软件包管理工具,拥有安装.卸载.更新.查看.搜索等很多实用的功能.简单的一条指令,就可以实现包管理,而不用你关心各种依赖和文件路径的情况,十分方便快捷. 1. ...
- kali中安装漏洞靶场Vulhub
一.什么是vulhub? Vulhub是一个基于docker和docker-compose的漏洞环境集合,进入对应目录并执行一条语句即可启动一个全新的漏洞环境,让漏洞复现变得更加简单,让安全研究者更加 ...
- linux硬盘分区和fdisk命令
分区的几个概念 硬盘分区有三种,主分区.扩展分区.逻辑分区.一个硬盘主分区至少有1个,最多4个,扩展分区可以没有,最多1个.且主分区+扩展分区总共不能超过4个.逻辑分区可以有若干个.在windows下 ...
- 【MySQL】centos6中/etc/init.d/下没有mysqld启动文件,怎么办
如果/etc/init.d/下面没有mysqld的话,service mysqld start也是不好使的,同样,chkconfig mysqld on也是不能用 解决办法: 将mysql的mysql ...