Detached SVG elements after a call to paper remove

1,171 views
Skip to first unread message

Marko

unread,
Jan 7, 2015, 3:29:25 PM1/7/15
to joi...@googlegroups.com
Hi,

I've been trying to call remove on paper and ensure that no SVG element is left in memory, but unfortunately this is what I get after taking a heap snapshot:


From JavaScript Memory Profiling: Red nodes (which have a darker background) do not have direct references from JavaScript to them, but are alive because they’re part of a detached DOM tree. There may be a node in the tree referenced from JavaScript (maybe as a closure or variable) but is coincidentally preventing the entire DOM tree from being garbage collected.

I've used the tutorial example for the jsfiddle here: http://jsfiddle.net/3h34tawb/. Notice calls to paper.remove() and paper = null at end of JavaScript. After you open the jsfiddle in Google Chrome, go to Profiles tab and Take heap snapshot. Search for "Detached" and you will find Detached DOM tree / 41 entries related to SVG elements generated by JointJS. The question is, how can we remove paper without causing a memory leak.

Additionally, lodash has memory leak on bindAll function. This is described in Memory leak during _.bind #554 and fix is found here.

Thanks.

David Durman

unread,
Jan 7, 2015, 3:38:07 PM1/7/15
to joi...@googlegroups.com
Hi Marko,

You should first call graph.clear(), that will remove all the views associated with all the elements/links from the paper. You could also remove all the views by iterating over cells, getting their views and then removing them one by one:

graph.get('cells').forEach(function(cell) {
    var view = paper.findViewByModel(cell)
    view.remove();
})


---

David Durman
client IO

--

---
You received this message because you are subscribed to the Google Groups "JointJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jointjs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Marko Sanković

unread,
Jan 7, 2015, 3:57:04 PM1/7/15
to joi...@googlegroups.com
David,

Thank you very much. The proposed solution works really good:
graph.get('cells').forEach(function (cell) {

var view = paper.findViewByModel(cell)
view.remove();
});

paper.remove();
paper = null;

David Durman

unread,
Jan 7, 2015, 4:01:11 PM1/7/15
to joi...@googlegroups.com
You have a good point though! Maybe paper.remove() should do just that internally. I have just created an issue for this in Github: https://github.com/DavidDurman/joint/issues/110.

---

David Durman
client IO

puneetp...@gmail.com

unread,
Dec 10, 2017, 2:21:58 AM12/10/17
to JointJS
Hi,

I am trying to delete/remove all the elements from the graph. When I do it as below, only links get removed and while removing other svg elements, it throws below exception:

Uncaught TypeError: Cannot read property 'unembed' of undefined

I tried to achieve it with graph.clear();

because the above did not work I tried as below:

var cells = graph.getCells();
    for(i = 0; i < cells.length; i++) {
graph.getCell(cells[i].id).remove();
    }


Both the ways I get this error message:

Uncaught TypeError: Cannot read property 'unembed' of undefined

Vladimír Talaš

unread,
Dec 12, 2017, 4:37:03 AM12/12/17
to joi...@googlegroups.com
Hi, 

Try to remove links first, then elements - sort the `cells` array or use the `graph.getLinks` and `graph.getElements`. 

You obviously use the embedding, when the parent cell is removed, it automatically removes its children. So it's likely the `graph.getCell(cells[i].id).remove()` will fail, because the cells[i] may be an already removed child. You can directly call the `cell[i].remove()`  - it's fine if you call remove on an already removed cell. 

Regards, 

Vladimir 





To unsubscribe from this group and stop receiving emails from it, send an email to jointjs+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--

puneetp...@gmail.com

unread,
Dec 13, 2017, 12:06:36 AM12/13/17
to JointJS
Hi Vladimir,

I tried to remove the links, first. And then, the elements, as below:

 var links = graph.getLinks();
    for(i = 0; i < links.length; i++) {
    links[i].remove();
}
   
 var elements = graph.getElements();
      for(i =  0 ; i < elements.length  ; i++) {
      elements[i].remove();
   }  

the links get deleted and then in the second loop some elements also get deleted.
The elements that are connected/linked with other elements fail to delete.

I have also tried to delete the dependent elements first by looping the element from revers order, as below:

var elements = graph.getElements();
      for(i = elements.length -1 ; i >= 0; i--) {
      elements[i].remove();
 }

But this also fails to delete the parent element.(even though the links and dependent elements are already deleted)

And the error message is same as ever : "TypeError: Cannot read property 'unembed' of undefined"


Thanks with best Regards,
Puneet.
Reply all
Reply to author
Forward
0 new messages