本文主要是介绍基于echarts桑基图改造的数据流向,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近出了个需求,要求做一个数据流向的图表。
根据数据结构特点:数据可以通过多个节点开始流入,最终可以流向多个节点。根据这个特点,满足要求的有两个:一个是关系图,另一个是桑基图。再根据各节点的排列位置来看,桑基图是最接近的了
但是设计师觉得桑基图的样式不好看,所以要基于桑基图来调整。
一般的桑基图是这样的
在阅读echarts的桑基图的文档之后,节点的高度是自动的,宽度可以设置,但是只能统一设置,不能对节点单独设置。这样的比较麻烦了,不太好自定义了。
但是,echarts还有个label属性,我们可以通过echarts的label的富文本属性来自定义节点的样式【太妙了】
下面直接上代码:
(这里的代码的主要终点就是对node的label的设置,已经link的lineStyle的设置,其他的根绝自己的需求调整即可)
使用的技术栈:vue3.0 + ts
function handleInitEchart(data: any[], links: any[]) {const nodesMap: any = {}, linksCountMap: any = {};const colors: any = ["#1C4BA0","#F99F46","#F4654E","#5A2EF7","#0086FF","#FF6600","#FF6666",];const bigColor: any = ["#336699","#FF6600","#990033","#FF6666","#009966","#CC6600","#003366","#CC3333","#006699","#FFCCCC",];for (let i = 0; i < links.length; i++) {let item = links[i];if (!linksCountMap[item.target]) {linksCountMap[item.target] = [item.source];} else {linksCountMap[item.target].push(item.source);}}links.forEach((item: any) => {if (linksCountMap[item.target].includes(item.source)) {item.value = parseInt((60 / linksCountMap[item.target].length) as any);} else {item.value = 10;}if (item.value > 10) {item.value = 10;}Object.assign(item, {lineStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{offset: 0,color: colors[item.level - 1],},{offset: 1,color: colors[item.level],},]),},});});for (let i = 0; i < data.length; i++) {data[i].count = data[i].value;}data.forEach((item: any, idx: number) => {if (!nodesMap[item.level]) {nodesMap[item.level] = [item];} else {nodesMap[item.level].push(item);}item.value = 30;item.name = "节点名称" + idx;let offsetY = 8;let padding = [4, 10],color = colors[item.level - 1];if (item.level == "1") {if (item.count > 5000000) {item.value = 28;padding = [10, 10];offsetY = 8;let colori = parseInt((Math.random() * 7) as any);color = bigColor[colori];} else {item.value = 16;padding = [4, 10];offsetY = 4;}} else {item.value = 60;padding = [17, 10];offsetY = 20;if (linksCountMap[item.id].length > 3) {offsetY = 0;}}Object.assign(item, {level: item.level,nodeWidth: 270,label: {offset: [0, -offsetY],width: 247,show: true,position: "inside",padding: padding,borderColor: color,borderWidth: 1,borderRadius: 4,borderType: "solid",backgroundColor: color,fontSize: item.level == "1" ? 12 : 20,formatter(e: any) {if (item.level == "1") {return `{a|${e.data.name}}{b|${e.data.count}}`;} else {return `{c|${e.data.name}}\n{d|${e.data.count}}`;}},},});});const option = {series: [{type: "sankey",left: 20,top: 20,right: 20,bottom: 20,data: data,links: links,nodeWidth: 270,draggable: false,focusNodeAdjacency: "allEdges",lineStyle: {color: "source",curveness: 0.5,},itemStyle: {color: "transparent",borderColor: "transparent",},label1: {position: "inside",fontSize: 12,color: "#666",formatter: function (params: any) {let { data } = params;return data.name;},},label: {position: "inside",show: true,color: "#fff",fontSize: 12,rich: {a: {width: 200,align: "left",color: "#fff",},b: {color: "#fff",align: "right",},c: {width: 200,fontSize: 24,align: "center",},d: {fontSize: 24,align: "center",},},},},],tooltip: {trigger: "item",},};echartsOptions.value = option;}
最终的效果图:
这篇关于基于echarts桑基图改造的数据流向的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!