Configure the Items
There are Node
and Edge
two types of items in a graph. In the last chapter, we rendered the Tutorial Demo with items with rough styles. Now, we are going to beautify the items while introducing the properties of the items.
Figure 1 The Tutorial Demo with cofigured items.
Basic Concept
Graph Item
There are Node
and Edge
two types of items in a graph. Several Built-in Nodes and Built-in Edges are provided by G6. The main difference between different types of items is their Graphics Shape. For example, a node's graphics shape can be a circle, a rect, an image, or others.
Properties of Item
The properties of an item can be be divided into two categories:
- Style Property
style
: Corresponds to the style in Canvas. When the State of an item is changed, the style can be updated. It is an object namedstyle
; - Other Property: Such as graphics
shape
,id
, they are a kind of properties that will not be changed when the State of the item is changed.
For example, When you change the state 'hover'
or 'click'
to true
for a node A, only the style properties of A can be updated, e.g. fill
, stroke
, and so on. The other properties such as shape
can not be changed. To update the other properties, configure A by graph.updateItem manually.
Data Structure
The data structure of a node:
{
id: 'node0', // Unique id of the node
shape: 'circle', // The graphics shape of the node
size: 40, // The size
label: 'node0' // The label
labelCfg: { // The configurations for the label
positions: 'center',// The relative position of the label
style: { // The style properties of the label
fontSize: 12, // The font size of the label
// ... // Other style properties of the label
}
}
// ..., // Other properties of the node
style: { // The object of style properties of the node
fill: '#000', // The filling color
stroke: '#888', // The stroke color
// ... // Other styleattribtues of the node
}
}
The data structure of an edge is similar to node, but two more properties source
and target
in addition, representing the id
of the source node and the id
of the target node respectively.
We can refine the visual requirements in figure 1 of Tutorial Demo into:
-
Visual Effect:
- R1: Set the color for stroke and filling for nodes with
fill
andstroke
; - R2: Set the color for the label with
labelCfg
; - R3: Set the opacity and color for edges with
opacity
,stroke
; - R4: Set the direction of the label with
labelCfg
;
- R1: Set the color for stroke and filling for nodes with
-
Map the data to visual channels:
- R5: Configure the shape of nodes with
shape
according to the propertyclass
in node data; - R6: Configure the line widht of edges with
lineWidth
according to the propertyweight
in edge data.
- R5: Configure the shape of nodes with
Configure the Properties
To satisfy different scenario, G6 provides 7 ways to configure the properties for items. Here we will only introduce two of them:
- Configure the global properties when instantiating a Graph;
- Configure the properties for different items in their data.
1. Configure the Global Properties When Instantiating a Graph
Applicable Scene: Unify the configurations for all the nodes or edges.
Usage: Configure it with two configurations of graph:
defaultNode
: The Style Property and Other Properties in the default state;defaultEdge
: The Style Property and Other Properties in the default state.
⚠️Attention: It is a way of unified global configuration, which does not distinguish the nodes with different properties (e.g. class
and weight
) in their data. That is to say, only R1, R2, R3, and R4 can be satisfied now:
Figure 2 Tutorial Demo with items configured by global configurations.
Configure the defaultNode
and defaultEdge
for graph to achieve the expected effect:
const graph = new G6.Graph({
// ... // Other configurations of the graph
// The style properties and other properties for all the nodes in the default state
defaultNode: {
size: 30, // The size of nodes
// ... // The other properties
// The style properties of nodes
style: {
fill: 'steelblue', // The filling color of nodes
stroke: '#666', // The stroke color of nodes
lineWidth: 1, // The line width of the stroke of nodes
},
// The properties for label of nodes
labelCfg: {
// The style properties for the label
style: {
fill: '#fff', // The color of the text
},
},
},
// The style properties and other properties for all the edges in the default state
defaultEdge: {
// ... // The other properties
// The style properties of edges
style: {
opacity: 0.6, // The opacity of edges
stroke: 'grey', // The color of the edges
},
// The properties for label of edges
labelCfg: {
autoRotate: true, // Whether to rotate the label according to the edges
},
},
});
2. Configure the Properties in Data
Applicable Scene: By this way, you can configure different items according to their properties in data.
Thus, the R5 and R6 can be satisfied now.
Usage: Write the properties into each item data, or traverse the data to assign the properties. Here we show assigning the attrbiutes into data by traversing:
const nodes = remoteData.nodes;
nodes.forEach(node => {
if (!node.style) {
node.style = {};
}
switch (
node.class // Configure the graphics shape of nodes according to their class
) {
case 'c0': {
node.shape = 'circle'; // The graphics shape is circle when class = 'c0'
break;
}
case 'c1': {
node.shape = 'rect'; // The graphics shape is rect when class = 'c1'
node.size = [35, 20]; // The node size when class = 'c1'
break;
}
case 'c2': {
node.shape = 'ellipse'; // The graphics shape is ellipse when class = 'c2'
node.size = [35, 20]; // The node size when class = 'c2'
break;
}
}
});
graph.data(remoteData);
The result:
Figure 3
From figure 3, we find some nodes are rendered as rects, some are ellipses. We also set the size
to override the size
in global configuration. The size
is an array when the node is a rect or an ellipse. We did not set the size
for circle node, so size: 30
in global configuration will still take effect for circle node. That is to say, configuring items by writing into data has higher priority than global configurations.
We further set the line widths for edges according to their weight:
// const nodes = ...
// Traverse the egdes data
const edges = remoteData.edges;
edges.forEach(edge => {
if (!edge.style) {
edge.style = {};
}
edge.style.lineWidth = edge.weight; // Mapping the weight in data to lineWidth
});
graph.data(remoteData);
The result:
The line width of the edges takes effect in the figure above. But the opacity and color setted in the global configurations are lost. The reason is that the global style
object in graph instance is overrided by the second configure method. The solution is move all the styles to the data:
const graph = new G6.Graph({
// ...
defaultEdge: {
// Remove the style here
labelCfg: {
// The properties for label of edges
autoRotate: true, // Whether to rotate the label according to the edges
},
},
});
// Traverse the nodes data
// const nodes = ...
// nodes.forEach ...
// Traverse the egdes data
const edges = remoteData.edges;
edges.forEach(edge => {
if (!edge.style) {
edge.style = {};
}
edge.style.lineWidth = edge.weight; // Mapping the weight in data to lineWidth
// The styles are moved to here
opt.style.opacity = 0.6;
opt.style.stroke = 'grey';
});
graph.data(remoteData);
graph.render();
Complete Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tutorial Demo</title>
</head>
<body>
<div id="mountNode"></div>
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-3.1.0/build/g6.js"></script>
<script>
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
fitView: true,
fitViewPadding: [ 20, 40, 50, 20 ],
defaultNode: {
size: 30,
labelCfg: {
style: {
fill: '#fff'
}
}
},
defaultEdge: {
labelCfg: {
autoRotate: true
}
},
});
const main = async () => {
const response = await fetch(
'https://gw.alipayobjects.com/os/basement_prod/6cae02ab-4c29-44b2-b1fd-4005688febcb.json'
);
const remoteData = await response.json();
const nodes = remoteData.nodes;
const edges = remoteData.edges;
nodes.forEach(node => {
if (!node.style) {
node.style = {};
}
node.style.lineWidth = 1;
node.style.stroke = '#666';
node.style.fill = 'steelblue';
switch (node.class) {
case 'c0': {
node.shape = 'circle';
break;
}
case 'c1': {
node.shape = 'rect';
node.size = [ 35, 20 ];
break;
}
case 'c2': {
node.shape = 'ellipse';
node.size = [ 35, 20 ];
break;
}
}
});
edges.forEach(edge => {
if (!edge.style) {
edge.style = {};
}
edge.style.lineWidth = edge.weight;
edge.style.opacity = 0.6;
edge.style.stroke = 'grey';
});
graph.data(remoteData);
graph.render();
};
main();
</script>
</body>
</html>
⚠️Attention:
Replace the url 'https://gw.alipayobjects.com/os/basement_prod/6cae02ab-4c29-44b2-b1fd-4005688febcb.json'
to change the data into yours.