G6.antv. vision/zh
This article will implement a demo based on React and AntV G6: Highlight the upstream and downstream diagrams of nodes when the mouse moves over them.
The preparatory work
Create a React project using the create-react-app scaffolding
$ create-react-app antv-demo
Copy the code
2, install @antv/g6, this demo uses @ANTv /g6**@3.4.8**
I @ $NPM antv/[email protected]Copy the code
3, use,
import G6 from '@antv/g6';
Copy the code
Start! GOGOGO
1, Data should be returned by request, for simplicity we create a recordLists
*/ this.recordLists = [{'upID': '111', 'superior': 'chairman of the board of directors' and' superiorName ':' Bob ', '_selfID' : '222', 'love' : 'senior advisor', '_selfName' : 'Alice'}, {' thus: '111', 'superior' : 'chairman of the board of directors' and' superiorName ':' Bob ', '_selfID' : '333', 'love' : 'chairman assistant', '_selfName' : 'Mary'}, {' thus: '111', 'superior' : 'chairman of the board of directors' and' superiorName ':' Bob ', '_selfID' : '444', 'love' : 'general manager', '_selfName' : 'Henry'}, {' thus: '222', 'superior' : 'senior advisor', 'superiorName' : 'upTenant222', '_selfID' : '555', 'love' : 'senior advisor assistant', '_selfName' : 'William'}, / /...Copy the code
G6 requires data including Nodes and edges:
const data = { nodes: [], edges: [] };
Copy the code
Parse the contents of orderLists into data:
2. Customize the node
The node needs to display the position and name, so we customize the node by inheriting the base class ‘single-shape’.
G6.registerNode('relationNode', { drawShape: function drawShape(cfg, group) { const strokeColor = '#CDCDCD'; const calcStrLen = str => { let len = 0; for (let i = 0; i < str.length; i++) { if (str.charCodeAt(i) > 0 && str.charCodeAt(i) < 128) { len++; } else { len += 2; } } return len; }; Const fittingString = (STR, maxWidth, fontSize) => {const fontWidth = fontSize * 1.3; // size + margin maxWidth = maxWidth * 2; Const width = calcStrLen(STR) * fontWidth; Const ellipsis = '... '; if (width > maxWidth) { const actualLen = Math.floor((maxWidth - 10) / fontWidth); const result = str.substring(0, actualLen) + ellipsis; return result; } return str; }; const rect = group.addShape('rect', { attrs: { x: -100 + 5, y: -25, width: 200, height: 60, radius: 3, stroke: ${strokeColor} '+ 0.015 + ':# FFF ', fillOpacity: 1, lineWidth: ${strokeColor}' + 0.015 + ':# FFF ', fillOpacity: 1, lineWidth: 1}}); group.addShape('text', { attrs: { x: -95 + 10, y: 3, fill: '#333', text: fittingString(cfg.superiorName, 185, 14), fontSize: 14, fontWeight: 510, isName: true } }) group.addShape('text', { attrs: { x: -95 + 10, y: 25, fill: '#999', text: fittingString(cfg.superior, 185, 12), fontSize: 12, fontWeight: 510, isPosition: true } }) return rect; } }, 'single-shape');Copy the code
3. Graph initialization
Const graph = new G6. Graph ({/ / container: mount nodes' mountNode, width: this. Props. The width | | window. The innerWidth, height: this.props.height || window.innerHeight, layout: { type: 'dagre', ranksep: 40, nodesep: 80, controlPoints: True}, modes: {default: ['drag-canvas',// can drag 'zoom-canvas'// can zoom]}, defaultNode: {// Use custom node type: 'relationNode', labelCfg: { style: { fill: '#666', fontSize: 14, fontWeight: 'bold' } } }, defaultEdge: { type: 'polylines, style: {radius: 20, endArrow: {path:' M 0, 0, 8, 4 A, 5,5,0,0,1,8 L - 4 Z ', the fill: '# DDD},},,}});Copy the code
4. Node event binding
Events used in this demo:
Mouseenter: Mouseenter is triggered by moving the mouse over the element, tracing upstream and downstream nodes, and highlight, the rest of the nodes are gray;
Mousemove: The mousemove is triggered repeatedly as the mouse moves inside the element, and a tooltip pops up if the area is’ rank ‘or’ name ‘.
Mouseout: Triggers when the mouse moves out of the target element to remove the tooltip.
Mouseleave: Triggered when the mouse moves out of the element range, returning to the original state of all nodes.
graph.on('node:mouseenter', ev => { const item = ev.item; const edgeItems = ev.item.getInEdges() || []; const sonEdgeItems = ev.item.getOutEdges() || []; findParents(edgeItems, item, item); FindSons (sonEdgeItems, item, item); // Trace the downstream node graph.setitemState (item, 'highlight', true); graph.update(item, { style: { stroke: '#FD9839', fill: 'l (0, 0) : # FD9839 + 0.015 + 0.015 +' : # FD9839 '+' : # FFF, cursor: 'pointer'}}) changeOthers (); }); graph.on('node:mousemove', (evt) => { const { item, target, x, y } = evt; const { attrs: { isName, isPosition }, } = target; const model = item.getModel(); const { superiorName, _selfName, superior, _self, id } = model; if (isName || isPosition) { const postion = graph.getClientByPoint(x, y); createTooltip(postion, isName ? superiorName || _selfName : superior || _self, id); } else { removeTooltip(id); }}); graph.on('node:mouseout', (evt) => { const { item, target } = evt; const { attrs: { isName, isPosition }, } = target; const model = item.getModel(); const { id } = model; if (isName || isPosition) { removeTooltip(id); }}); graph.on('node:mouseleave', ev => { const item = ev.item; clearStates(); graph.setItemState(item, 'highlight', false); graph.update(item, { style: { stroke: '#CDCDCD', fill: 'l (0, 0) : # eight-line + 0.015 + 0.015 +' : # eight-line '+' : # FFF, cursor: 'default' fillOpacity: 1}})})Copy the code
* * https://github.com/Toxic12138/antv-demo * * demo complete sample
🏆 technology project phase iii | data visualization of those things…