In this chapter, we will learn the Graph process. Here, we will take the Graph around Guo Baokun as an example.


// Create guo Baokun's interpersonal circle
const GuoBaoKun = [
    { name: 'Guo Youzhi'.x: 100.y: 200 },
    { name: 'prince'.x: 200.y: 200 },
    { name: 'such'.x: 300.y: 200},]Copy the code
// Wrap the cable label
function formatLineLabel(relation={}) { // Relation: human relations
    return {
        show: true.formatter: function (m) {
            return relation[m.data.target]
        }
    }
}

Copy the code

/ / create option

const options = {
    tooltip: {},
    series: [{type: 'graph'./ / diagram
            symbolSize: 70.label: {show: true}, // Display the node text
            edgeSymbol: ['none'.'arrow'].// Connect the shape at both ends of the line, where the arrows are set
            data: [{name: 'Kuo Bao-kun'.x: 200.y: 100 },
                ...GuoBaoKun
            ],
            links: GuoBaoKun.map(item= > {
                return  {
                    source: 'Kuo Bao-kun'./ / starting point
                    target: item.name,  / / the end
                    symbolSize: 20.// Arrow size
                    label: formatLineLabel({
                        'prince': 'loyalty'.'Guo Youzhi': 'father'.'such': 'enemy'})}})}]}Copy the code
// Render the graphics
import * as echarts from 'echarts'

let myChart = null

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

Copy the code

Such a simple kuo Baokun character relationship map is completed

As you can see, the default is a circular node, and we can set up a long square as required

Set nodes of various shapes

    series: [
        {
            type: 'graph'.symbol: 'rect'.// Set a long square
            //symbol: 'diamond', set to diamond
            //symbol: 'triangle'
            //symbolSize: [100, 50], // set length and width. }]Copy the code

Let’s look at the different renderings

Next to expand interpersonal relationships, let’s take Fan Leisure as an example

Expand the three-level node

// Create a casual network
const FanXian = [
    { name: 'Chen Pingping'.x: 100.y: 300 },
    { name: 'Lin Wan 'er'.x: 200.y: 300 },
    { name: 'five bamboo'.x: 300.y: 300},]Copy the code

Now that we have the connections, we can just go under the links extension

links: GuoBaoKun.map(item= > {
    return  {
        source: 'Kuo Bao-kun'.target: item.name, 
        symbolSize: 20.label: formatLineLabel({
            'prince': 'loyalty'.'Guo Youzhi': 'father'.'such': 'enemy',
        })
    }
}).concat(FanXian.map(item= > {   // Let's expand the connection line
    return {
        source: 'such'.target: item.name,
        symbolSize: 20.label: formatLineLabel({
            'Chen Pingping': 'teacher'.'Lin Wan 'er': 'to love'.'five bamboo': 'uncle',}}}))Copy the code

rendering

You can expand on that if you want, so I’m not going to write it here, but we can change the connector style

Setting cable

series: [
    {
        ...
        lineStyle: {
            type: 'dashed'.color: '#201ba1'.curveness: 0.2.// The curve curve of 0~1 can also be negative, but the bending direction is different
        },
        
        // Set the node literal style
        label: {}, 
        
        // Set the text style on the connection line
        edgeLabel: {
            color: 'red'.fontSize: 16,}}]Copy the code

Refer to figure

Now let’s try to make the dotted line move, so it’s a little bit more visualized where it goes

Dynamic dotted line chart

Let's start with the principle: by constantly changing the dashOffset implementationlet dashOffset = 5
    
    options = {
        ...
        series: [{...lineStyle: {...type: [5.10].dashOffset: dashOffset,
                }  
            }
        ]
    } 
    
    
    function move() {
        dashOffset++
        if(dashOffset > 15) {
            dashOffset = 0
        }
        myChart.setOption(options)  
        setTimeout(move, 20)}Copy the code

rendering

Those of you who are thinner might think that the dotted line is going against the current, we just have to make dashOffset–

Dynamic scale node

May again at this time of a node demand need scalable, click launches the child nodes, and then click close child nodes that, so we will continue to expand, the first click echarts we will think about a click event, but how to give each node binding, and how do you know which node click? Let’s take a look

Let’s take Fan Xian as an example

// Create a switch first. Since we only add events to Fanxian, we only need one switch
// If multiple node events are added, objects can be created as required

let showFanxianRelation = false  // By default, child nodes are not displayed

Copy the code

Modify the above code, separate each module

// Create guo Baokun interpersonal circle links

const links_gbk = GuoBaoKun.map(item= > {
    return  {
        source: 'Kuo Bao-kun'.target: item.name,
        symbolSize: 20.// Arrow size
        label: formatLineLabel({
            'prince': 'loyalty'.'Guo Youzhi': 'father'.'such': 'enemy',})}})Copy the code
// Create a fan of interpersonal links line links

const links_fx = FanXian.map(item= > {
    return {
        source: 'such'.target: item.name,
        symbolSize: 20.label: formatLineLabel({
            'Chen Pingping': 'teacher'.'Lin Wan 'er': 'to love'.'five bamboo': 'uncle',})}})Copy the code

Initialize links and Series data in Options (set initial state not to include circle of people, only for demo individuals)

Let links = links_gbk let seriesData = [{name: 'GuoBaoKun ', x: 200, y: 100},...GuoBaoKun]Copy the code
const options = {
    ...
    data: seriesData,
    links: links
}
Copy the code

Next, just add the event and click to dynamically add the circle of relationships

On ('click', params => {console.log(params)})Copy the code

Error example – global update ❌

myChart && myChart.on('click', {name: 'such'}, () = > {
    // Here I specify the node, so there is no need to judgeshowFanxianRelation = ! showFanxianRelationif(showFanxianRelation) {
        links = [...links, ...links_fx]  // Add a fan line
        seriesData = [...seriesData, ...FanXian]
        
        // There is a detail here, how to rerender after modifying the data
        // If you call the render function again, you will find that the DOM is occupied.
        Mychart.dispose () may be called to destroy the previous instance,
        
        myChart.dispose()
        myChart.init() 

    } else{...// Restore the data to the original state}})// However, every time you click on a node, the graph will flash.
  // We don't want to do this, we just want to update the local options
Copy the code

Correct example – update bookmarks in foreground

myChart && myChart.on('click', {name: 'such'}, () = >{ showFanxianRelation = ! showFanxianRelationif(showFanxianRelation) {
        options.series[0].links = [...links, ...links_fx]  // Add a fan line
        options.series[0].data = [...seriesData, ...FanXian]
    } else {
        options.series[0].links = links_gbk
        options.series[0].data = [
            {name: 'Kuo Bao-kun'.x: 200.y: 100},
            ...GuoBaoKun 
        ]
    }
    
    myChart.setOptions(options)
})
Copy the code

Let’s take a look at the renderings

The last whisper

What is the pursuit of man in this life