Echarts繪制關系圖(一)

關系圖

何為關系圖,從字面上可以看出,為關系的圖形,既然為關系,那么就需要有點以及關系,用來表示點與點之間的聯(lián)系。所以我們可以得出:關系圖需要兩個必要的元素,節(jié)點,關系,其中關系需要包含有聯(lián)系的節(jié)點以及節(jié)點聯(lián)系說明。因此我們首先需要將數(shù)據(jù)設計出來。

數(shù)據(jù)

節(jié)點數(shù)據(jù)

nodes:[{
  name:'節(jié)點名',
  id:'節(jié)點id'
}]

關系數(shù)據(jù)

links:[{
  relation:{
    name:'關系名稱',
    id:'關系id'
   },
  source:'關系的起點節(jié)點id',
  target:'關系的目標節(jié)點id'
}]

至此我們的數(shù)據(jù)也弄明白了,那么我們現(xiàn)在來看下echarts關系圖的制作。

首先看下我們要做的關系圖的樣子
graph.png

引入Echarts

當前采用的是vue+ts模式的開發(fā)模式,故以下都將以此來說明。

yarn add echarts

由于使用的是ts.故需要引入類型說明

yarn add @types/echarts

創(chuàng)建dom節(jié)點

新建一個vue文件,新建dom節(jié)點,注意:如果dom節(jié)點沒有設置長寬,后面渲染會不出現(xiàn),因為沒有給出空間

<div id="echartsMain"></div>

基于Echarts搭建圖形基礎架子

由于echarts的架子都是差不多的,重點在于series,所以本篇文章主要在series上進行說明,故先復制一份常用架子,如下

myEcharts:any = null;
public initEcharts(){
   const mainDom: any = this.$el.querySelector("#echartsMain");//設置dom
   this.myEcharts = echarts.init(mainDom);//初始化echarts
   let option:any = {
        series:[]
   };
   this.myEcharts.setOption(option);
}

至此,我們一個基于echarts的圖形基礎架子搭建好了,刷新頁面,沒有報錯,dom節(jié)點也存在。那么下面就到了創(chuàng)建關系力布圖的時候了

創(chuàng)建節(jié)點

按照上圖,以及我們前面關于數(shù)據(jù)的說明,我們可以先創(chuàng)建節(jié)點數(shù)據(jù)

  let nodes: Array<any> = [
        {
          name: "韋小寶",
          id: "1",
        },
        {
          name: "方怡",
          id: "2",
        },
        {
          name: "雙兒",
          id: "3",
        },
        {
          name: "茅十八",
          id: "4",
        },
        {
          name: "吳六奇",
          id: "5",
        },
      ];

將節(jié)點數(shù)據(jù)設置到力布圖上,在上面的options中增加節(jié)點

llet options:any = {
     series:[{
          nodes:nodes
        }]
      }

此時數(shù)據(jù)加上了,但是沒有顯示,是因為我們沒有設置當前圖標類型為力布圖,因此在options中增加說明即可

let options:any = {
    series:[{
        type: 'graph',
        layout: 'force',
        nodes:nodes
    }]
}

那么我們就得到了如下的圖
node.png

但是這樣的話,有幾個問題,第一,節(jié)點過小,第二,不知道節(jié)點到底是哪個。那么我們下一步就應該給節(jié)點增加樣式

增加節(jié)點樣式

1:設置節(jié)點的大小,以及形狀,直接在nodes數(shù)據(jù)中進行修改

   let nodes: Array<any> = [
        {
          name: "韋小寶",
          id: "1",
          symbolSize: 60,//節(jié)點大小
          symbol:'circle',//節(jié)點形狀,'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'也可'image://url'設置節(jié)點圖片
        },
        {
          name: "方怡",
          id: "2",
          symbolSize: 60,
        },
        {
          name: "雙兒",
          id: "3",
          symbolSize: 60,
        },
        {
          name: "茅十八",
          id: "4",
          symbolSize: 60,
        },
        {
          name: "吳六奇",
          id: "5",
          symbolSize: 60,
        },
      ];

修改完后頁面為
size.png

在echarts中所有的節(jié)點的樣式都是通過itemStyle來進行設置的,同樣的在力布圖中已經(jīng)可以通過itemstyle屬性進行設置節(jié)點樣式(也可以直接在nodes數(shù)據(jù)中設置單個節(jié)點的樣式哦,這個可以自己去試下),同理節(jié)點上的文字顯示問題也是如此,

let options: any = {
        series: [
          {
           type: 'graph',
           layout: 'force',
            nodes: nodes,
            itemStyle: {
              color: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.5,
                colorStops: [
                  {
                    offset: 0,
                    color: "#3dd67a", // 0% 處的顏色
                  },
                  {
                    offset: 0.7,
                    color: "#3dd67a", // 0% 處的顏色
                  },
                  {
                    offset: 1,
                    color: "#95dcb2", // 100% 處的顏色
                  },
                ],
                global: false, // 缺省為 false
              },
            },
            label: {
              show: true,
              position: "bottom",
              distance: 5,
              fontSize: 18,
              align: "center",
            },
          },
        ],
      };

至此節(jié)點設置結束,頁面如下:
node-label.png

創(chuàng)建關系數(shù)據(jù)

按照最開始的圖片已經(jīng)數(shù)據(jù)說明,我們可以很明顯的將關系數(shù)據(jù)編輯出來,如下

let links: Array<any> = [
        {
          source: "1",
          target: "2",
          relation: {
            name: "老婆",
            id: "1",
          },
        },
        {
          source: "1",
          target: "3",
          relation: {
            name: "老婆",
            id: "1",
          },
        },
        {
          source: "1",
          target: "4",
          relation: {
            name: "兄弟",
            id: "1",
          },
        },
        {
          source: "4",
          target: "1",
          relation: {
            name: "兄弟",
            id: "1",
          },
        },
        {
          source: "3",
          target: "5",
          relation: {
            name: "義妹",
            id: "1",
          },
        },
      ];

力布圖添加關系

在options中增加關系數(shù)據(jù),如下

let options: any = {
        series: [
          {
            type: 'graph',
            layout: 'force',
            nodes: nodes,
            links:links,
            itemStyle: {
              color: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.5,
                colorStops: [
                  {
                    offset: 0,
                    color: "#3dd67a", // 0% 處的顏色
                  },
                  {
                    offset: 0.7,
                    color: "#3dd67a", // 0% 處的顏色
                  },
                  {
                    offset: 1,
                    color: "#95dcb2", // 100% 處的顏色
                  },
                ],
                global: false, // 缺省為 false
              },
            },
            label: {
              show: true,
              position: "bottom",
              distance: 5,
              fontSize: 18,
              align: "center",
            },
          },
        ],
      };

此時頁面展示情況如下:
關系.png

多個關系處理

從上面的圖形以及數(shù)據(jù)中,我們可以看到,其實茅十八和韋小寶互相為兄弟關系的,但是上圖中沒有顯示,如果我們?nèi)タ磀om節(jié)點,我們可以看到其實茅十八和韋小寶間有兩條線,但是由于兩間之間直線距離最短,所以echarts就直接給重合了,那么我們怎么解決呢,最簡單的方式將重疊的線變成曲線,因此在options中增加曲線率即可

let options: any = {
        series: [
          {
            type: 'graph',
            layout: 'force',
            nodes: nodes,
            links:links,
            itemStyle: {
              color: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.5,
                colorStops: [
                  {
                    offset: 0,
                    color: "#3dd67a", // 0% 處的顏色
                  },
                  {
                    offset: 0.7,
                    color: "#3dd67a", // 0% 處的顏色
                  },
                  {
                    offset: 1,
                    color: "#95dcb2", // 100% 處的顏色
                  },
                ],
                global: false, // 缺省為 false
              },
            },
            label: {
              show: true,
              position: "bottom",
              distance: 5,
              fontSize: 18,
              align: "center",
            },
            autoCurveness: 0.01, //多條邊的時候,自動計算曲率
          },
        ],
      };

此時頁面展示為
image.png

增加關系說明以及指向

let options: any = {
        series: [
          {
            type: 'graph',
            layout: 'force',
            nodes: nodes,
            links: links,
            itemStyle: {
              color: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.5,
                colorStops: [
                  {
                    offset: 0,
                    color: "#3dd67a", // 0% 處的顏色
                  },
                  {
                    offset: 0.7,
                    color: "#3dd67a", // 0% 處的顏色
                  },
                  {
                    offset: 1,
                    color: "#95dcb2", // 100% 處的顏色
                  },
                ],
                global: false, // 缺省為 false
              },
            },
            label: {
              show: true,
              position: "bottom",
              distance: 5,
              fontSize: 18,
              align: "center",
            },
            autoCurveness: 0.01, //多條邊的時候,自動計算曲率
            edgeLabel: {//邊的設置
              show: true,
              position: "middle",
              fontSize: 12,
              formatter: (params) => {
                return params.data.relation.name;
              },
            },
            edgeSymbol: ["circle", "arrow"], //邊兩邊的類型
          },
        ],
      };

此時頁面展示為
image.png

此時一個關系圖的最基本的設置就配置完成了。

ps:可能各位按照代碼敲出來的頁面長這樣
image.png

此時我們看圖可以看到,所有的節(jié)點都挨著,所以說明節(jié)點間沒有排斥力,同時關系間的線的長度都沒有設置,因此直接在options增加相應的設置即可,最終的options如下
let options: any = {
        series: [
          {
            type: 'graph',
            layout: 'force',
            nodes: nodes,
            links: links,
            itemStyle: {
              color: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.5,
                colorStops: [
                  {
                    offset: 0,
                    color: "#3dd67a", // 0% 處的顏色
                  },
                  {
                    offset: 0.7,
                    color: "#3dd67a", // 0% 處的顏色
                  },
                  {
                    offset: 1,
                    color: "#95dcb2", // 100% 處的顏色
                  },
                ],
                global: false, // 缺省為 false
              },
            },
            label: {
              show: true,
              position: "bottom",
              distance: 5,
              fontSize: 18,
              align: "center",
            },
            autoCurveness: 0.01, //多條邊的時候,自動計算曲率
            edgeLabel: {//邊的設置
              show: true,
              position: "middle",
              fontSize: 12,
              formatter: (params) => {
                return params.data.relation.name;
              },
            },
            edgeSymbol: ["circle", "arrow"], //邊兩邊的類型
            force: {
              repulsion: 100,
               gravity:0.01,
                edgeLength:200
           }
          },
        ],
      };

附加echarts力布圖配置鏈接
https://echarts.apache.org/zh/option.html#series-graph.type
下一章將會實現(xiàn)節(jié)點拖拽后固定,以及文字隨縮放而變化以及將某個指定的節(jié)點定位到視圖中間

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容