前言
此功能利用echarts的關(guān)系力圖,達到節(jié)點和邊的展示。
請在讀此文章前閱讀echarts官方文檔、echarts gallery的簡單示例附源碼
產(chǎn)出結(jié)果
核心功能
- 節(jié)點分類渲染
- 線段分類渲染以及不同方向展示
- 兩個節(jié)點間多線段渲染
依賴
- vue
- node
- $ npm install echarts
核心文件
- RelationGraph.js 數(shù)據(jù)處理、折線圖渲染 注:目的是后續(xù)可以復用,往這個趨勢修改此文件
- RelationGraph.vue 數(shù)據(jù)獲取、除折線圖的渲染
一、RelationGraph.vue的數(shù)據(jù)
統(tǒng)一存儲到名為dataInput的對象中。
dataInput中各項的含義
dataInput: {
style: { //存放樣式
height: 800 //canvas高度,以像素為單位
},
node: [ //節(jié)點數(shù)組,可以單獨設(shè)置任意一個節(jié)點的樣式
{
name: '李瑞冬', //節(jié)點名稱,注意要唯一
category: '男性', //節(jié)點類別
draggable: false //是否可拖拽
}, ...
],
relation: [ //邊數(shù)組,可以單獨設(shè)置任意一條邊的樣式
{
source: '李瑞冬', //節(jié)點數(shù)組的index或者名稱,出發(fā)節(jié)點
target: 1, //節(jié)點數(shù)組的index或者名稱,到達節(jié)點
value: '朋友', //關(guān)系
symbol: ['none', 'arrow'] //線段兩端的圖形形狀
}, ...
],
node_category: [ //節(jié)點分類樣式
{
name: '男性', //分類。對應的節(jié)點數(shù)組的category
itemStyle: { //節(jié)點樣式
normal: {
color: "blue" //顏色,可16進制,可rgb,可rgba
},
emphasis: { //hover時效果
}
}
}, ...
],
relation_category: { //邊分類樣式
'朋友': { //關(guān)系,對應邊數(shù)組的value
lineStyle: {
normal: { //正常樣式
opacity: 0.9, //透明度
width: 2, //寬度
curveness: 0.4, //彎曲度
type: 'solid', //線段樣式,'solid' 'dashed' 'dotted'
color: 'rgba(0, 0, 0, 0.6)' //顏色
},
emphasis: { //hover時效果
color: 'rgba(0, 0, 0, 1)'
}
}
}, ...
},
legend: ['男性', '女性'] //分類的圖標,可隱藏部分分類
}
??注:節(jié)點和線段更多的樣式可參考echarts官方文檔
二、RelationGraph.js
具體可以看源代碼注釋,已足夠詳細
/** 外部引入方法 */
import echarts from 'echarts'
export {drawChart}
/** 獲取父組件元素 */
var chart
// 基于準備好的dom,初始化echarts實例
var myChart
/** 全局變量 */
var dataInput //輸入數(shù)據(jù)
var option //全局Option配置
var legend //圖標
var node //節(jié)點
var relation //線段
var category //類別樣式
/** 核心方法 */
var drawChart = function(data) {
dataInput = data;
//dataInput數(shù)據(jù)處理
handle_dataInput()
//初始化option
initOption()
//初始化折線圖
initChart()
// 繪制圖表
setTimeout(() => {
myChart.setOption(option);
},300)
}
/** 數(shù)據(jù)處理 */
var handle_dataInput = function() {
legend = {
x: "center",
show: true,
data: dataInput.legend
}
node = dataInput.node
//關(guān)系
relation = dataInput.relation
for (var i in relation) {
for (var j in dataInput.relation_category) {
if (relation[i].value == j) {
relation[i].lineStyle = dataInput.relation_category[j].lineStyle
break
}
}
}
category = dataInput.node_category
}
/** 初始化option */
var initOption = function() {
option = {
title: {
text: ''
},
tooltip: {
show: true
},
animationDurationUpdate: 1500,
animationEasingUpdate: 'quinticInOut',
label: {
normal: {
show: true,
textStyle: {
fontSize: 12
},
}
},
legend: legend,
series: [
{
type: 'graph',
layout: 'force',
symbolSize: 45,
categories: category, //類別樣式
force: {
repulsion: 1000
},
data: node, //點
links: relation, //邊
draggable: true, //默認是否可拖動
label: { //默認節(jié)點樣式
normal: {
show: true,
textStyle: {
fontSize: 12
}
}
},
edgeSymbol:['none','none'],
edgeSymbolSize: [20, 20],//邊兩端的標記大小
edgeLabel: {
normal: {
show: true,
textStyle: {
fontSize: 10
},
formatter: "{c}"
}
},
lineStyle: {
normal: {
opacity: 0.9,
width: 1,
curveness: 0
}
},
force:{
repulsion: 800,//節(jié)點之間的斥力因子
gravity: 0.4,//節(jié)點受到中心的引力因子
edgeLength: 300,//節(jié)點之間的距離
// layoutAnimation:true,//迭代動畫
},
focusNodeAdjacency: true,//是否在鼠標移到節(jié)點上的時候突出顯示節(jié)點以及節(jié)點的邊和鄰接節(jié)點。
roam: true,//如果只想要開啟縮放或者平移,可以設(shè)置成 'scale' 或者 'move'。設(shè)置成 true 為都開啟
nodeScaleRatio: 0.6//鼠標縮放比例
}
],
animation: false,
animationThreshold: 2000,//是否開啟動畫的閾值,當單個系列顯示的圖形數(shù)量大于這個閾值時會關(guān)閉動畫。
animationDuration: 1000, //初始動畫的時長,支持回調(diào)函數(shù),可以通過每個數(shù)據(jù)返回不同的 delay 時間實現(xiàn)更戲劇的初始動畫效果
animationEasing: 'cubicOut', //初始動畫的緩動效果。
animationDelay: 0, //初始動畫的延遲,支持回調(diào)函數(shù),可以通過每個數(shù)據(jù)返回不同的 delay 時間實現(xiàn)更戲劇的初始動畫效果
animationDurationUpdate: 1500,//數(shù)據(jù)更新動畫的時長。
animationEasingUpdate: 'quinticInOut',//數(shù)據(jù)更新動畫的緩動效果。
animationDelayUpdate: 0 //數(shù)據(jù)更新動畫的延遲,支持回調(diào)函數(shù),可以通過每個數(shù)據(jù)返回不同的 delay 時間實現(xiàn)更戲劇的更新動畫效果。
}
}
/** 初始化折線圖 */
var initChart = function() {
var height = dataInput.style.height
document.getElementById('echarts').innerHTML =
'<div id="myChart" style="width:100%;height:'
+ height +'px;"></div>'
chart = document.getElementById('myChart')
myChart = echarts.init(chart)
chart.style.height = height + 'px'
}