antvis / G6

♾ A Graph Visualization Framework in JavaScript.
https://g6.antv.antgroup.com/
MIT License
11.06k stars 1.31k forks source link

数据源更新,视图没有更新,使用clear()无效 #752

Closed bbp94 closed 5 years ago

bbp94 commented 5 years ago

使用的是React,父组件更新了数据传递给子组件(Graph),子组件明明接收到了新数据,并且使用graph.getNodes()查看后发现数据是更新的,但是前端页面确没有变化,还是之前的图,使用了clear(),changeData()都没有用。

bbp94 commented 5 years ago

使用的是g6,3.0.4版本,使用new G6.Graph()创建图

zhenhuiWang commented 5 years ago

我是在vue里用的treeGraph, 根据官网的例子,使用graph.getNodes()修改了节点的样式,打印出来的节点数据是确实修改了的, 但是前端页面视图没有改变。重新展开一遍才能显示修改之后的视图。 使用了graph.refresh() 也无效

baizn commented 5 years ago

排查一下,不要是其他业务代码影响的,如果还存在麻烦提供一个可复现的demo。

baizn commented 5 years ago

@zhenhuiWang @bbp94 graph.getNodes需要在render之前调用。

windows99 commented 4 years ago

兄弟问题解决了吗?我也遇到这样的问题,很难受

vuturn commented 4 years ago

也是遇到了这个问题,无法重绘,搞了好久

vuturn commented 4 years ago

用refreshLayout这个API之后可以了。。。

szanlin commented 4 years ago

用refreshLayout这个API之后可以了。。。

你什么版本

vuturn commented 4 years ago

用refreshLayout这个API之后可以了。。。

你什么版本

3.2.9

Jessie-jzn commented 4 years ago

请问怎么解决的?我这样写没有任何效果,打印出来的节点数据是确实修改了的, 但是前端页面视图没有改变。 const fetchGetRelation = async (value = params) => { if (value.showNo) { const res = await relationGraph(value) console.log('res', res) setRelationObject(res) if (!graph) { setInitializeGraph() } graph.changeData(res) graph.refreshLayout(true) } }

Jessie-jzn commented 4 years ago

请问怎么解决的?我这样写没有任何效果,打印出来的节点数据是确实修改了的, 但是前端页面视图没有改变。 const fetchGetRelation = async (value = params) => { if (value.showNo) { const res = await relationGraph(value) console.log('res', res) setRelationObject(res) if (!graph) { setInitializeGraph() } graph.changeData(res) graph.refreshLayout(true) } }

解决了,因为使用函数式组件,每次都会渲染一次,导致graph一直是null,需要new一遍实例,clear也没有执行。 把let graph=null 写在组件外或者存一下

JiangMengLei commented 4 years ago

@bbp94。。解决了吗?我用react也没法更新视图

JiangMengLei commented 4 years ago

@bbp94。。解决了吗?我用react也没法更新视图

graph.render()之后,会在容器里不断添加canvas,导致覆盖,而不是更新canvas。

临时解决办法:graph.render()之前,删除容器下所有子dom。

xsfxtsxxr commented 3 years ago
// 1.如果用的是class component,就在componentWillUnmount里面重置数据
componentWillUnmount(){
  graph = null
  nodes = []
  edges = []
}
// 2.如果用的是function component,就在useEffect里面清除,第二参数空数组,相当于componentDidMount,只开始执行一次,里面return相当于componentWillUnmount
useEffect(() => {
  // ....
  return () => {
    graph = null
    nodes = []
    edges = []
  }
},[])

// 这样一来,再次进入页面的时候会重新调用graph = new G6.Graph({...}),重新生成canvas画布
lengyuxian commented 2 years ago

请问这个还有其他更好的方法吗? 我也遇到了不断添加canvasd得情况,而且还是前面一个脑图打开得画布,还销毁不了

Yee-Guo commented 2 years ago
// 1.如果用的是class component,就在componentWillUnmount里面重置数据
componentWillUnmount(){
  graph = null
  nodes = []
  edges = []
}
// 2.如果用的是function component,就在useEffect里面清除,第二参数空数组,相当于componentDidMount,只开始执行一次,里面return相当于componentWillUnmount
useEffect(() => {
  // ....
  return () => {
    graph = null
    nodes = []
    edges = []
  }
},[])

// 这样一来,再次进入页面的时候会重新调用graph = new G6.Graph({...}),重新生成canvas画布

请问 当我在vue项目中,那我应该如何清空数据呢,直接在render()之前清空会导致整个图都无法绘制

mrcluo commented 2 years ago

技术栈:vue全家桶项目 场景:mounted初始化G6=>destroyed卸载G6=>再次进到这个页面=>canvas内容还是之前的数据,未更新 image

Yee-Guo commented 2 years ago

技术栈:vue全家桶项目 场景:mounted初始化G6=>destroyed卸载G6=>再次进到这个页面=>canvas内容还是之前的数据,未更新 image

我尝试过 将graph存入data中,this.mygraph=graph,后 面的渲染也使用this.graph.data()...然后this.mygraph.destroy()

mrcluo commented 2 years ago

技术栈:vue全家桶项目 场景:mounted初始化G6=>destroyed卸载G6=>再次进到这个页面=>canvas内容还是之前的数据,未更新 image

我尝试过 将graph存入data中,this.mygraph=graph,后 面的渲染也使用this.graph.data()...然后this.mygraph.destroy()

感觉你的回答,不过我也试了你这样的操作,视图还是未更新..

mrcluo commented 2 years ago

<UserGroupBloodChart v-if="dataObj.nodes.length" :dataObj="dataObj" :taskId="taskId" @isUserGroup="isUserGroup" @isTag="isTag" />

问题解决了 解决方案:引入g6组件的地方,加一个v-if, 新数据存入之前,先把数据清空让g6组件销毁,再重新加载。 经测试,g6组件加:key='动态时间戳' 也不行,必须按照以上做法销毁组件再重新加载

song0720 commented 1 year ago

useEffect(() => { if (!graph) { // 添加缩略图 // const miniMap = new G6.Minimap(); initG6(); graph.data(data); graph.render(); } return () => { graph.destroy();//这个是重点 graph = null; }; }, [data]);

seasonstorm commented 1 year ago

追加一种场景, 如果直接使用redux的数据来渲染会遇到, 手动深拷贝之后然后传递给read或者data方法 image

VirgoHxy commented 5 months ago
async mounted() {
  // vue 防止dom未渲染 无法渲染
  this.$nextTick(() => {
    // 初始化容器
    this.init();
    // 读取数据
    this.changeData();
    // 渲染图
    this.render();
  });
}
zhao995 commented 4 months ago

react中可以用destroy,先销毁再render