00. Introduction

A graph consists of two points and a line. This can be regarded as a basic representation of a graph structure. There are many scenarios that require the use of graph visualization. As shown in the figure below, graphs play a key role in different fields.

![Field Relationship Map](https://gw.alipayobjects.com/mdn/rms_402c1a/afts/img/A*G8I1TaPvDogAAAAAAAAAAAAAARQnAQ)

Graphin visualization tool launched by AntV might suit your needs to visualize a relationship graph. The following walkthrough shows how Graphin can help us develop a graph analysis application.

Friendly reminder: This website is generated by dumi, so you can directly click the lower right corner </> of the demo example to view the source code.

01. Installation Dependencies

If you are using React, you can import Graphin as a React component.

This article uses yarn to install dependencies, but npm can also be used. @antv/graphin is the core component of the library, while @antv/graphin-components provides a set of analysis components. Graphin's icon library is provided by @antv/graphin-icons.

yarn add @antv/graphin@latest --save
yarn add @antv/graphin-components@latest --save
yarn add @antv/graphin-icons --save

02. Visualize Relational Data

The first step to perform graph analysis is to visualize graph data. The graph structure consists of Nodes and Edges. id is the only required parameter of a Node, while source and target are required parameters of an Edge. The source and target should correspond to the start and end node id of the edge.

关系数据
{
  "nodes": [
    {
      "id": "node-0",
      "x": 100,
      "y": 100
    },
    {
      "id": "node-1",
      "x": 200,
      "y": 200
    },
    {
      "id": "node-2",
      "x": 100,
      "y": 300
    }
  ],
  "edges": [
    {
      "source": "node-0",
      "target": "node-1"
    }
  ]
}
可视化结果

03. Visual Channel Mapping

In the first step, we successfully render the nodes and edges of a graph. However, the current graph styles are a little simple. We will now map information on nodes and edges to different visual options. Apart from the size, shape, and style, Graphin's built-in nodes and edges are standardized. The built-in node graphin-circle consists of 5 parts, namely keyshape, label, icon, badges, and halo. They are placed in the style field of the node, as shown below:

Note ⚠️: To show all the configuration options, the full configuration file is displayed here. In actual development, we have the Utils.genDefaultNodeStyle function to help us quickly generate configuration files according to the theme style. At the same time, each node can contain only the part of the style that needs customization (Graphin does deepMerge internally with the style of each node)

关系数据

{
  nodes: [
    {
      id: 'node-0',
      x: 200,
      y: 240,
      style: {
        // 节点的主要形状,即圆形容器,可以在这里设置节点的大小,border,填充色
        keyshape: {
          /** 容器的宽度 */
          lineWidth: 3,
          /** 节点的大小 */
          size: 80,
          /** 包围边颜色 */
          stroke: parimaryColor,
          /** 填充色 */
          fill: Utils.hexToRgbaToHex(parimaryColor, 0.2),
          /** 透明度 */
          opacity: 1,
          /** 鼠标样式 */
          cursor: 'pointer',
        },
        // 是节点的标签,可以设置标签的值 和样式:放置方位,大小,字体颜色,偏移位置
        label: {
          /** label的名称 */
          value: '节点-0',
          /** 展示位置  'top' | 'bottom' | 'left' | 'right' | 'center'; */
          position: 'top',
          /** 文本填充色 */
          fill: '#000',
          /** 文本大小 */
          fontSize: 16,
          fontFamily: 'normal',
          textAlign: 'center',
          /** 文本在各自方向上的偏移量,主要为了便于调整文本位置 */
          offset: 0,
        },
        // 是节点的中心 ICON 区域,icon 可以是图片,可以是文本,也可以是字体图标。
        icon: {
          /** 类型可以为字体图标,可以为网络图片,可以为纯文本 'font' | 'image' | 'text' */
          type: 'font',
          /** 根据类型,填写对应的值 */
          value: icons.user,
          /** 图标大小 */
          size: 40,
          /** 字体图标的填充色 */
          fill: parimaryColor,
          /** 字体Family */
          fontFamily: 'graphin',
        },
        // 节点的徽标区域,是一个数组,可以分别在不同方位放置,其内容区域可以是文本,数字,也可以是图标。
        badges: [
          {
            /** 放置的位置,ef:LT(left top)左上角 */
            position: 'RT',
            /** 类型可以为字体图标,可以为网络图片,可以为纯文本 */
            type: 'text',
            value: '10',
            // type = image 时生效,表示图片的宽度和高度
            size: [25, 25],
            /** 徽标填充色 */
            fill: Utils.hexToRgbaToHex(parimaryColor, 1),
            /** 徽标描边色 */
            stroke: '',
            /** 徽标内文本的颜色 */
            color: '#fff',
            fontSize: 14,
            fontFamily: '',
            // badge 中文本距离四周的偏移量
            padding: 0,
            // badge 在 x 和 y 方向上的偏移量
            offset: [0, 0],
          },
          {
            /** 放置的位置,ef:LT(left top)左上角 */
            position: 'LB',
            /** 类型可以为字体图标,可以为网络图片,可以为纯文本 */
            type: 'text',
            value: 'Pin',
            // type = image 时生效,表示图片的宽度和高度
            size: [25, 25],
            /** 徽标填充色 */
            fill: Utils.hexToRgbaToHex(parimaryColor, 1),
            /** 徽标描边色 */
            stroke: '',
            /** 徽标内文本的颜色 */
            color: '#fff',
            fontSize: 12,
            fontFamily: '',
            // badge 中文本距离四周的偏移量
            padding: 0,
            // badge 在 x 和 y 方向上的偏移量
            offset: [0, 0],
          },
        ],
        // 节点的光环,在节点交互过程中(hover,selected,disabled,active)等,可以打开光环,默认是隐藏的,也可以自定义
        halo: {
          /** 光晕 */
          fill: Utils.hexToRgbaToHex(parimaryColor, 0.2),
          /** 透明度 */
          opacity: 1,
          /** 是否展示 */
          visible: false,
          /** 鼠标Hover上去样式 */
          cursor: 'pointer',
        },
        // 节点的交互样式,默认 Graphin 已经内置了交互样式(即将 halo 图形显示出来),也可以自定义
        status: {
          hover: {
            halo: {
              visible: true,
            },
          },
          selected: {
            halo: {
              visible: true,
            },
            keyshape: {
              lineWidth: 10,
            },
          },
        },
      },
    },
  ],
  edges: [],
}
  
  
可视化结果

Let us continue our example. node-0 is a user, node-1 is an enterprise, and node-2 is another enterprise. Using the above-mentioned built-in nodes in Graphin, we can map the size of the node to represent the scale of the enterprise, the icon of the node to display different attributes and color to distinguish its attributes.

    1. Label each node
    1. Map the size of the enterprise, data.count, to the size of the node
    1. Map the different data types, data.type, to the icon of the node
    1. Since node-0 is the actual controlling owner behind node-2, we can represent the relationship as a dotted edge
关系数据
{
  "nodes": [
    {
      "id": "node-0",
      "x": 100,
      "y": 100,
      "data": {
        "type": "user"
      },
      "style": {
        "label": {
          "value": "node-0"
        },
        "keyshape": {
          "size": 30,
          "stroke": "#FF6A00",
          "fill": "#FF6A00",
          "fillOpacity": 0.2,
          "strokeOpacity": 1
        },
        "icon": {
          "type": "font",
          "value": "",
          "size": 15,
          "fill": "#FF6A00",
          "fontFamily": "graphin"
        }
      }
    },
    {
      "id": "node-1",
      "x": 200,
      "y": 200,
      "data": {
        "type": "company",
        "count": 300
      },
      "style": {
        "label": {
          "value": "node-1"
        },
        "keyshape": {
          "size": 60,
          "stroke": "#46a7a6",
          "fill": "#46a7a6",
          "fillOpacity": 0.2,
          "strokeOpacity": 1
        },
        "icon": {
          "type": "font",
          "value": "",
          "size": 30,
          "fill": "#46a7a6",
          "fontFamily": "graphin"
        }
      }
    },
    {
      "id": "node-2",
      "x": 100,
      "y": 300,
      "data": {
        "type": "company",
        "count": 200
      },
      "style": {
        "label": {
          "value": "node-2"
        },
        "keyshape": {
          "size": 40,
          "stroke": "#46a7a6",
          "fill": "#46a7a6",
          "fillOpacity": 0.2,
          "strokeOpacity": 1
        },
        "icon": {
          "type": "font",
          "value": "",
          "size": 20,
          "fill": "#46a7a6",
          "fontFamily": "graphin"
        }
      }
    }
  ],
  "edges": [
    {
      "source": "node-0",
      "target": "node-1"
    },
    {
      "source": "node-0",
      "target": "node-2",
      "style": {
        "keyshape": {
          "lineDash": [
            2,
            2
          ],
          "stroke": "#FF6A00"
        },
        "label": {
          "value": "实际控制人",
          "fill": "#FF6A00"
        }
      }
    }
  ]
}
可视化结果

04. Choose the right layout

Layout is one of the most important components of graph visualization. We have come across the preset layout, which renders the x and y attribute specified by the user as coordinate position onto the canvas. This is useful if the data is returned from the server with the position coordinates calculated. However, if the data does not contain layout information, we can no longer use preset to determine the graph layout. In this case, an appropriate layout algorithm is important to draw the graph. Let's use Graphin's built-in function Utils.mock to simulate some data and see how the graph looks like with different layout algorithms

同心圆布局算法:Concentric
有向分层算法:Dagre

As shown in the layout above, we can focus on the relationship of the central node with the concentric circle algorithm layout, which sorts the node based on the degree distribution, by default. This allows you to see the key culprits of a criminal syndicate network at a glance. The nodes under the directed layering algorithm are arranged hierarchically according to the flow direction of the edges. In some networks with obvious flow directions, such as capital flows, the upstream and downstream relationships can be clearly seen.

In a general graph visualization platform, it is not immediately clear which layout algorithm to draw the graph in the beginning. The most user-friendly solution is to provide layout switching capabilities for users to choose the layout independently. With additional AI capabilities, we could possibly predict the best layout based on the data used and training data. This feature is still work in progress.

布局切换
 graphin-force
布局预测
还在开发中...

05. Good interaction can enhance user analysis experience

After the data is successfully rendered and drawn with a suitable layout, the product manager comes to you with the following suggestions

  • The canvas should support zooming, to enable users to view the big picture when the amount of data is huge
  • There should be user feedback on node click. It will be great to perform "delicate" changes on the node
  • Highlight the neighbouring nodes and edges to reduce visual interference
  • Select nodes in batches with mouse circle selection, or draw your own area selection like the magic wand in Adobe Photoshop
  • ... (100+ optimization suggestions omitted here)

Ultimately, the project manager praises your skills and talent, and believe that you can implement the graph analysis experience well. At this moment, you, withholding the apprehensions in your heart, dread staying up late to complete the development.

Good graph interaction can enhance the user's analytical experience. From this perspective, the product manager is right. Graphin is a technical product polished from the line of business. We deconstructed interaction behaviour and encapsulated it into components to allow developers to import it based on demands and needs.

import { Behaviors } from '@antv/graphin';
const {
TreeCollapse, // Expand and collapse the tree map
DragCanvas, // Drag the canvas
ZoomCanvas, //Zoom canvas
ClickSelect, // Click to select the node
BrushSelect, //Circle selection operation
DragNode, // Drag node
ResizeCanvas, // automatically adjust canvas width and height
LassoSelect, // Lasso operation
DragCombo, // Drag Combo
ActivateRelations, // associated highlight
Hoverable, // Hover operation
} = Behaviors;
网图的 Hover 关联高亮 <ActivateRelations />
树图的 Click 展开收起 <TreeCollapse />

06. Good analysis components can improve user analysis efficiency

As business needs deepen, user demand for analysis increases. The simple canvas and graphic element operations no longer satisfy users' analysis demands, for example:

  • The operation of nodes is not limited to clicking nodes. It is also necessary to mark nodes, drill down data, delete, and reverse selection. At this time, you need a right-click menu component.
  • Data classification needs to be marked with contour components or legends

Graphin summarized 26 analysis components according to the guidance in the white paper "AntV Graph Visual Analysis Solution".

组件梳理Xmind
components-xmind
右键菜单 + 鱼眼放大镜

07. Precipitating these product solutions, maybe you could use them

We will discuss more on the business application in this section. There are several similarities found in the application of graph visual analysis in different business fields. As an example, in the knowledge graph and financial risk control, there is a core product function, the former is knowledge reasoning, the latter is risk detection. In these scenarios, a drill-down analysis approach is used. This requires dynamic processing of both data and layout. The exploration challenges of dynamic graphs are the first business problem solved by the Graphin team. We abstract this problem as a combination of two technical solutions of data-driven + progressive layout and hope to provide assistance in everyone's business.

无动画扩散
有动画扩散

In addition to the dynamic layout, large graph exploration is a common requirement in business. Adopting the Louvain algorithm aggregation, using Combo capability or node aggregation display mode, combined with MiniMap small map navigation, fish-eye magnifying glass, can help meet the exploration needs of large graphs. Refer to this DEMO for more information.

The above sections are all the contents for our quick start. Through the small DEMO walkthrough, we have demonstrated the basic capability of Graphin:

  • Support the rendering of two different data structures: tree map and network map.
  • Built-in multiple layouts, support sub-map layout, incremental layout, layout switching.
  • Wide variety of style customization of nodes and edges.
  • Support the imports of interactive behavior combinations: Currently, 9 common interaction behaviors have been completed to meet our daily interaction needs.
  • Built-in rich analysis components, currently 6 commonly used components have been completed: right-click menu, tooltip, minimap navigation, legend component, fisheye magnifier, contour component. There are 26 components in total.
  • Accumulate product functions from business types, such as dynamic map exploration and big map exploration.

If you are still interested, you can continue to read the in-depth exploration part, which will introduce you to Graphin's extension mechanism and component customization mechanism, as well as GraphinStudio that we will focus on next.