preface
This article is more delicious after reading through the G6 documentation and understanding the G6…
What is G6?
The official text is as follows:
G6 is a graph visualization engine. It provides the basic capabilities of graph visualization such as drawing, layout, analysis, interaction and animation. It’s about making relationships transparent and simple. Give users Insight into relational data.
The above reference to “basic capabilities” needs to be highlighted, because it can be said that the G6 essence.
To put it more purely, G6 is a namespace that provides graphics-oriented programming, gives developers the ability to manually assemble graphics and customize graphical interactions, and makes their own living, reflecting the official foundational capabilities.
Now, let’s conceptually implement a workflow monitoring visualization product using G6 around the topic of process visualization. The skill points of this product involve:
- Customize job nodes
- Nodes are configured with styles for different states
- Node response event
- Drag and drop to generate edges to connect the two nodes
- Delete nodes and edges
- Get graph data
Custom node
/ * * *@desc Custom node API *@param {String} nodeName- Node name, globally unique *@param {Object} options- Node configuration item *@param {String} extendName- Inherited built-in node name */
G6.registerNode(nodeName, options, extendName)
Copy the code
- Nodes (and edges) are the smallest units of a graph, and nodes are assembled by shapes. We can understand this:
- If nodes are chemical molecules, shapes are atoms;
- If the node is a car, shape is the tire, glass, seat and other parts that assemble the car
- Implementing a custom node rendering onto the canvas must satisfy:
- Customize the node and give it a globally unique name.
- When rendering a graph through data, the node
type
Specified as the name in (1).
// Customize the job node
G6.registerNode('job-node',
{
draw (cfg, group) {
const keyShape = group.addShape()
return keyShape // Each node has a keyShape, so this step is necessary}},'single-node'
)
// Render custom job nodes by specifying node type in the data
// There are other ways to configure the node type for rendering, such as global configuration, function configuration, etc. Please refer to them by yourself
const data = {
nodes: [{id: 1.type: 'job-node'
}
]
}
G6.read(data)
Copy the code
Node configuration state style
During actual G6 development, there are two different scenarios where state styles need to be configured:
- Different attribute values of business data fields lead to different styles of nodes drawn, such as whether the node is disabled or available.
- Different interaction, node drawing effect is different, such as mouse hover and mouse click selected node;
// First, draw a node based on the data
1.1 Preparing Data
const data = {
nodes: [{id: 1.type: 'job-node'.name: 'Inspection monitoring'
disabled: true
},
{
id: 2.type: 'job-node'.name: 'Core warehouse'.disabled: false}}]// 1.2 Dynamic mapping based on service data during the registration of user-defined nodes
G6.registerNode('job-node',
{
draw (cfg, group) {
// The business data attributes are passed to CFG during the drawing process, so here we can get the name/disabled attributes in the data
const { name, disabled } = cfg
const keyShape = group.addShape()
// the group.addShape() method returns a graph instance
// Change the style of the graph dynamically based on the business data attributes
keyShape.attr({
cursor: disabled ? 'not-allowed' : 'default' // If diabled is disabled (true), a disabled gesture is displayed when levitating
})
return keyShape
}
},
'single-node'
)
// Second, based on the interaction configuration style
// 2.1 Configure the status style when registering a node
G6.registerNode('job-node',
{
options: {
stateStyles: {
hover: {
fill: '#ccc'
},
select: {
fill: 'red'
}
}
}
draw (cfg, group) {
const keyShape = group.addShape()
return keyShape
}
},
// Inheriting the built-in node is necessary. The internal node encapsulates the keyshape and subshape styles of the node's 'options.stateStyles' configuration in different states
// This means we don't have to copy setState and its internal handling of node shapes
'single-node'
)
// 2.2 Adding node status during Interaction
// Cursor the node, the node background is gray
graph.on('node:mouseenter'.evt= > {
const node = evt.item
graph.setItemState(node, 'hover'.true)})// Mouse cursor over the node, the node background is set to default
graph.on('node:mouseout'.evt= > {
const node = evt.item
graph.setItemState(node, 'hover'.false)})// Click the node, the node background becomes red
graph.on('node:click'.evt= > {
const node = evt.item
graph.setItemState(node, 'select'.true)})Copy the code
Node response event
G6 provides event registration mechanism for monitoring canvas, node, edge, group and other multidimensional dimensions. We can register events for different dimensions according to the actual scene.
In addition, in G6, the smallest unit of event response is the node or edge. If you want to respond to a graph in the node, you can listen on the event of the node/edge, and then judge by the event object and the related API of the node/edge.
For example, a node can only be removed from the canvas by clicking its close-icon-Shape.
G6.registerNode('job-node',
{
draw (cfg, group) {
const iconShape = group.addShape('image', {
attrs: {
url: closeIcon
},
// The name attribute is required. You can retrieve the name of the graph defined here via the event object
name: 'close-icon-shape'
})
const keyShape = group.addShape()
return keyShape
}
},
'single-node'
)
constdata = {... }const graph = newG6.Graph({... }) graph.on('node:click'.evt= > {
/ / the node
const item = evt.item
/ / shape pattern
const target = evt.target
// Get the name of the graph definition with the get('name') method
if (target.get('name') = = ='close-icon-shape') {
// This will only happen if you click close-icon-shape
graph.removeItem(item)
}
})
Copy the code
Drag and drop to generate edges to connect the two nodes
The drag-and-drop generation side is composed of a series of events, or a set of actions, so registering a single event response can be difficult to achieve the desired effect or even affect other interactions.
So G6 gives us the ability to encapsulate a set of actions together, and that’s where G6 interaction modes and custom interactions come in.
By switching the interaction modes, we can make the elements in the diagram react differently to the same event.
For example, there are default and Edit modes:
- The default mode includes clicking on the selected node and dragging the canvas.
- Edit mode includes clicking a node to pop up an edit box and dragging a node.
For details, see the toggle mode in the G6 diagram example to add points and edges.
Get graph data
After the above steps, our flow chart is basically achieved:
- Node drawing and generation
- Process dependencies between job nodes
- A node is added or deleted
Finally, the graph data needs to be acquired and transmitted to the server to persist the graph data. In THE G6 graph, the data acquisition is also quite simple, and only the following methods are needed:
console.log(graph.save()) // graph is an instance of g6.graph
// The above method prints an object of the following format
{
nodes: [...]. .edges: [...]. .// Group /combo...
}
Copy the code
Get in the bowl!
At this point, we have conceptually completed the core functions of a workflow monitoring visualization product.
This article mainly from the idea and G6 provided by the ability to start, no in-depth code details, or even most of the time, because the details of not three days and three nights can not finish 😜, I hope you understand.
If you are using the G6 and have any doubts about the G6 or think the G6 is good, what a coincidence! I know a mysterious organization (the activity is not allowed to put advertising, so after the activity to stickers), little brother little sister you will come to me to play ~
The last
Before I touched the G6, I used canvas canvas objects to make my whole heart happy for a while.
After learning G6, I have a considerable amount of confidence in the demand for visual products. I am very grateful to the leaders of the G6 team for their guidance and clarification when the younger brother just started on the road. Here I must thank a few elder brothers by name: Shiwu, Yu Ran and Juze! Also thanks to a few nights ago in the dream are drawing path of their own. Love you! 😚
Finally, here are the notes I made when I was studying G6:
- Shape graph of user-defined node:
- All graphs are drawn relative to the center of the node (the coordinates of the center of the node are relative to the canvas and controlled by the matrix where the group is). X/y is specifiedRelative to the node centerThe distance of the position of. Dimension attributes use:
width / height / r / rx / ry
- All graphs are drawn relative to the center of the node (the coordinates of the center of the node are relative to the canvas and controlled by the matrix where the group is). X/y is specifiedRelative to the node centerThe distance of the position of. Dimension attributes use:
- Custom nodes inherit built-in nodes:
single-node
: Internal encapsulation handles the node’soptions.stateStyles
Configure keyshape and subshape styles in different states, which means we don’t have to copysetState
And its internal style for handling each shape of the node
- The event parameter properties of the canvas:
graph.on('click'.evt= > {
console.log('Output node', evt.item); / / null < > click on the canvas | Node < Node > click | Edge < click side >
console.log('Output graph', evt.target); // Text | Path | Rect ....
console.log('Output parent', evt.parent); / / null < > click on the canvas | Group < graphics Group, click on the node or edge >
})
Copy the code
group
和shape
Graphical concepts, like SVG’s G tag and other graphical tags like Circle;item
It is not a graphical concept. As instances of nodes and edges on the canvas, it contains manipulation methods for the visualizations associated with the API and a proxy for the group
- Extraneous support
lineAppendWidth
Widen the range. The restshape
Also supported, to setstroke
The shape attribute is supported by the G layer. - Get canvas matrix information:
const matrix = graph.get('group').getMatrix()
Copy the code
🏆 technology project phase iii | data visualization of those things…