Echarts 5 瞎入门指南 - 9

本章学习下Graph流程关系图, 这里以郭宝坤身边的关系图为例!!markdown

//建立郭宝坤人际圈
const GuoBaoKun = [
    { name: '郭攸之', x: 100, y: 200 },
    { name: '太子', x: 200, y: 200 },
    { name: '范闲', x: 300, y: 200 },
]

复制代码
//封装链接线label
function formatLineLabel(relation={}) { //relation:人物关系
    return {
        show: true,
        formatter: function (m) {
            return relation[m.data.target]
        }
    }
}

复制代码

//建立optionecharts

const options = {
    tooltip: {},
    series: [
        {
            type: 'graph', //关系图
            symbolSize: 70,
            label: {show: true}, //显示节点文字
            edgeSymbol: ['none', 'arrow'], // 链接线两端形状,这里设置箭头
            data: [
                { name: '郭宝坤',  x: 200,  y: 100 },
                ...GuoBaoKun
            ],
            links: GuoBaoKun.map(item => {
                return  {
                    source: '郭宝坤', //起点
                    target: item.name,  //终点
                    symbolSize: 20,  //箭头大小
                    label: formatLineLabel({
                        '太子': '效忠',
                        '郭攸之': '父亲',
                        '范闲': '仇人',
                    })
                }
            })
        }
    ]
}

复制代码
//渲染图形
import * as echarts from 'echarts'

let myChart = null

myChart = echarts.init(dom)
myChart.setOption(options)

复制代码

这样一个简单的郭宝坤人物关系图就完成了dom

f7114a3f2e8d70ca10be31afd0818432.png

能够看到默认是圆形节点, 咱们能够根据需求设置成长方形函数

设置各类形状的节点

series: [
        {
            type: 'graph',
            symbol: 'rect',  //设置成长方形 
            //symbol: 'diamond', 设置成菱形◇
            //symbol: 'triangle', 设置成三角形
            //symbolSize: [100, 50], //设置长宽
            ...
        }
    ]
复制代码

来看下不一样的效果图学习

2c9ec43add7ac286ced08aea3eeb0ca3.png

1d84d9c17f7a67ed2fb006767fc527cb.png

接下来拓展下人际关系, 咱们就以范闲为例好了flex

拓展三级节点

//建立范闲人际圈
const FanXian = [
    { name: '陈萍萍', x: 100, y: 300 },
    { name: '林婉儿', x: 200, y: 300 },
    { name: '五竹', x: 300, y: 300 },
]
复制代码

有了人际关系,接下来咱们只要在links 扩展下就能够了ui

links: GuoBaoKun.map(item => {
    return  {
        source: '郭宝坤',  
        target: item.name, 
        symbolSize: 20,  
        label: formatLineLabel({
            '太子': '效忠',
            '郭攸之': '父亲',
            '范闲': '仇人',
        })
    }
}).concat(FanXian.map(item => {   //这里拓展下链接线便可
    return {
        source: '范闲',
        target: item.name,
        symbolSize: 20,
        label: formatLineLabel({
            '陈萍萍': '恩师',
            '林婉儿': '爱人',
            '五竹': '叔叔',
        })
    }
}))
复制代码

效果图lua

47dd195dc14f1a977d503d3f833d16f7.png

有须要能够继续拓展下去,这里我就再也不写了, 不过咱们能够修改下链接线样式url

设置链接线

series: [
    {
        ...
        lineStyle: {
            type: 'dashed',
            color: '#201ba1',
            curveness: 0.2,  //曲线 弯曲度 0~1 固然也支持负的, 只是弯曲的方向不一样
        },
        
        //设置 节点文字样式
        label: {}, 
        
        //设置链接线上文字样式
        edgeLabel: {
            color: 'red',
            fontSize: 16,
        },
    }
]
复制代码

参考图spa

链接线.png

接下来咱们试下让虚线动起来, 这样从哪到哪的可视化效果就比较明显些

动态虚线图

所先讲下原理: 经过不断改变dashOffset 实现
    let dashOffset = 5
    
    options = {
        ...
        series: [
            {
                ...
                lineStyle: {
                    ...
                    type: [5, 10],
                    dashOffset: dashOffset,
                }  
            }
        ]
    } 
    
    
    function move() {
        dashOffset++
        if(dashOffset > 15) {
            dashOffset = 0
        }
        myChart.setOption(options)  
        setTimeout(move, 20)
    }
    
复制代码

效果图

虚线动图.gif 比较细的人可能以为虚线逆流了, 咱们只要让 dashOffset-- 便可

动态伸缩节点

可能这时候又来了个需求须要节点可伸缩展现, 点击一下展开子节点, 再点一下关闭子节点那种, 因而乎咱们又要继续拓展了, 所先点击咱们就想到了echarts的点击事件, 可是怎么给每一个节点绑定,而且怎么知道点击的是哪一个节点呢, 让咱们一块儿来看下

这里咱们仍是以范闲为例

//首先建立个开关, 由于咱们只给范闲添加事件, 因此只要一个开关
//若是添加多个节点事件能够根据需求建立对象

let showFanxianRelation = false  //默认不展现子节点

复制代码

把上面代码改造下,分离各个模块

//建立郭宝坤人际圈链接线links

const links_gbk = GuoBaoKun.map(item => {
    return  {
        source: '郭宝坤',
        target: item.name,
        symbolSize: 20,  //箭头大小
        label: formatLineLabel({
            '太子': '效忠',
            '郭攸之': '父亲',
            '范闲': '仇人',
        })
    }
})
复制代码
//建立范闲人际圈链接线links

const links_fx = FanXian.map(item => {
    return {
        source: '范闲',
        target: item.name,
        symbolSize: 20,
        label: formatLineLabel({
            '陈萍萍': '恩师',
            '林婉儿': '爱人',
            '五竹': '叔叔',
        })
    }
})
复制代码

初始化options里面的 links 和series的data (设置初始状态不包含人际圈,只展现范闲我的)

let links = links_gbk
let seriesData = [
    {name: '郭宝坤', x: 200, y: 100},
    ...GuoBaoKun 
]
复制代码
const options = {
    ...
    data: seriesData,
    links: links
}
复制代码

接来下只要添加事件,经过点击动态添加人际关系圈就好了

myChart && myChart.on('click', params => {
    console.log(params)  
    //这里能够经过params获得每一个节点信息,而后再判断点击了哪一个节点
})
复制代码

错误示例 - 全局更新 ❌

myChart && myChart.on('click', {name: '范闲'}, () => {
    //这里我指定了节点,因此不用再判断了
    
    showFanxianRelation = !showFanxianRelation
    if(showFanxianRelation) {
        links = [...links, ...links_fx]  //添加范闲关系线
        seriesData = [...seriesData, ...FanXian]
        
        //这里有个细节, 修改了数据后该怎么从新渲染呢
        //若是从新调用一遍渲染函数你会发现dom报错, 已经被占了,
        //这时候可能会调用myChart.dispose() 销毁以前的实例,
        
        myChart.dispose()
        myChart.init() 

    } else {
        ...
        //把数据还原成初始状态
    }
})
  // 可是这样每次点击节点会致使关系图闪一下, 全局更新了,
  // 因此这里咱们不采起这种方法, 只要更新局部options就行
复制代码

正确示例 - 局部更新 ✔

myChart && myChart.on('click', {name: '范闲'}, () => {
    showFanxianRelation = !showFanxianRelation
    if(showFanxianRelation) {
        options.series[0].links = [...links, ...links_fx]  //添加范闲关系线
        options.series[0].data = [...seriesData, ...FanXian]
    } else {
        options.series[0].links = links_gbk
        options.series[0].data = [
            {name: '郭宝坤', x: 200, y: 100},
            ...GuoBaoKun 
        ]
    }
    
    myChart.setOptions(options)
})
复制代码

让咱们来看下效果图

完美版伸缩.gif

最后的轻语

人这一辈子到底在追寻着什么

相关文章
相关标签/搜索