在react项目中使用antv G6的时候出现了invalid container的错误,各种找解决方案以及在GitHub上找G6的项目,花费了一些时间但是没有找到解决方法,不得不吐槽一下antv官网给出的例子,没有一个完整的demo,文档很不友好。
最后发现一篇博客,博客中说在componentDidMount的时候做图形的初始化,这个时候恍然大悟,我之前直接把初始化的代码写在render中,而render执行的时候return中的div还没有渲染,所以才会出现invalid container的错误。
使用function + hooks实现官网的一个例子,代码:
import React, { useState, useEffect } from 'react';
import G6 from '@antv/g6';
const DeviceGraph = () =>{
const data = {
nodes: [{
x: 100,
y: 100,
shape: 'circle',
label: 'circle',
},{
x: 200,
y: 100,
shape: 'rect',
label: 'rect',
},{
x: 300,
y: 100,
size: [60, 30],
shape: 'ellipse',
label: 'ellipse',
},{
x: 400,
y: 100,
shape: 'image',
img: 'https://gw.alipayobjects.com/zos/rmsportal/XuVpGqBFxXplzvLjJBZB.svg',
label: 'image',
}]
};
useEffect(() => {
const devicegraph = new G6.Graph({
container: 'mountNode',
fitViewPadding: 20,
height: 500,
width: Width,
nodeStyle: {
default: {
fill: '#40a9ff',
stroke: '#096dd9'
}
},
edgeStyle: {
default: { stroke: '#A3B1BF' }
},
modes: {
default: ['zoom-canvas', 'drag-canvas']
}
});
devicegraph.read(data);
}
});
return (
)
};
export default DeviceGraph
需要注意的一点是如果用于绘图的数据源发生改变的时候,需要清空画布,否则画出的图会闪烁。具体方法见https://www.yuque.com/antv/g6/graph
我的代码:
import React, { useState, useEffect } from 'react';
import G6 from '@antv/g6';
const DeviceGraph = () =>{
const [ graph, setGraph ] = useState(undefined);
const data = {
nodes: [{
x: 100,
y: 100,
shape: 'circle',
label: 'circle',
},{
x: 200,
y: 100,
shape: 'rect',
label: 'rect',
},{
x: 300,
y: 100,
size: [60, 30],
shape: 'ellipse',
label: 'ellipse',
},{
x: 400,
y: 100,
shape: 'image',
img: 'https://gw.alipayobjects.com/zos/rmsportal/XuVpGqBFxXplzvLjJBZB.svg',
label: 'image',
}]
};
useEffect(() => {
if(graph !== undefined){
graph.changeData(deviceData)
}
if(Data.length > 0 ){ // 这里的Data是绘图的数据源
const devicegraph = new G6.Graph({
container: 'mountNode',
fitViewPadding: 20,
height: 500,
width: Width,
nodeStyle: {
default: {
fill: '#40a9ff',
stroke: '#096dd9'
}
},
edgeStyle: {
default: { stroke: '#A3B1BF' }
},
modes: {
default: ['zoom-canvas', 'drag-canvas']
}
});
devicegraph.read(data);
setGraph(devicegraph);
}
}, [Data]);
return (
)
};
export default DeviceGraph
之前写React代码几乎都是使用Class,现在用了用function + React Hooks的方式感觉还是很好用的,比如使用useState可以保存graph实例,可以在其他的方法中访问这个变量,而使用class是无法保存到state中,会造成死循环。所以如果不是特别依赖react的生命周期类似componentDidMount这些的,推荐使用function + Hooks的方式构建,真香!!!