GoJS on web worker

Can GOJS work on multithreading environment?

Hope you aware that i am loading 2000 to 5000 nodes in the diagramming tool due to business needs. Hence I do receive following error and want to resolve this issue by using HTML5 web worker object. Please help me on this.

Few links are over here
http://www.tutorialspoint.com/html5/html5_web_workers.htm
http://blogs.msdn.com/b/davrous/archive/2011/07/15/introduction-to-the-html5-web-workers-the-javascript-multithreading-approach.aspx
http://www.html5rocks.com/en/tutorials/workers/basics/

We are aware of this limitation and plan to address it in the future.

http://gojs.net/latest/samples/virtualizedTree.html will solve my problem?

Generally speaking the primary reasons that the browser remains unresponsive for too long are loading too many nodes and links and performing a compute-intensive layout.

Unless your nodes are complicated, I would not think that loading 2000 nodes is too many. I suppose 5000 might be, depending on the browser – it’s likely too many on a smartphone. Virtualization would help in reducing the amount of work done at load time, as well as reducing the memory usage after initialization. But it takes programming work to implement virtualization correctly.

For layouts, TreeLayout and GridLayout and the default Layout are very fast, so they would not cause any unresponsiveness issues. However LayeredDigraphLayout is very limited in how large a graph it can handle in a reasonable amount of time. (It’s even worse than in our other diagramming products because JavaScript is significantly slower than .NET or Java.) 2000 nodes is definitely too many for LayeredDigraphLayout. Unfortunately there is no easy solution. In GoDiagram we do support running the layout in a separate thread. However WebWorkers in JavaScript is not really at all like in-process threads because there is no shared memory.

I am able to add unlimited number of nodes using below approach. However I am unable to add transitions above 2000+ irrespective increasing the timeline or decreasing the number of links.

Can you please help out on this issue?

var loadQty = 150;
var timespan = 2000;
var counter = Math.floor(nodes.length / loadQty);
var rem = nodes.length % loadQty;
var timerCount = -1;
for (var i = 0; i < counter; i++) {
setTimeout(function () {
timerCount++;
this.AsIsGraph.model.addNodeDataCollection(nodes.slice((loadQty * timerCount), ((timerCount + 1) * loadQty) + rem));
}.bind(this), timespan * i);
}
setTimeout(function () {
this.AsIsGraph.model.addNodeDataCollection(nodes.slice(counter * loadQty, (counter * loadQty) + rem));
timerCount = -1;
}.bind(this), timespan * counter);

        setTimeout(function () {
            this.AutoArrangeDiagram();
        }.bind(this), (timespan * counter) + timespan);

        var intialDelay = (timespan * counter) + timespan;
        var t_loadQty = 75;
        var t_timespan = 10000;
        var t_counter = Math.floor(nodeArray.TransitionData.length / t_loadQty);
        var t_rem = nodeArray.TransitionData.length % t_loadQty;
        for (var i = 0; i < t_counter; i++) {
            setTimeout(function () {
                timerCount++;
                this.AsIsGraph.model.addLinkDataCollection(nodeArray.TransitionData.slice((t_loadQty * timerCount), ((timerCount + 1) * t_loadQty) + t_rem));
            }.bind(this), intialDelay + (t_timespan * i));
        }
        setTimeout(function () {
            this.AsIsGraph.model.addLinkDataCollection(nodeArray.TransitionData.slice(t_counter * t_loadQty, (t_counter * t_loadQty) + t_rem));
        }.bind(this), intialDelay + (t_timespan * t_counter));

        setTimeout(function () {
            MX.util.MxUtility.HideSpinner();
            this.FindNodeCounter();
        }.bind(this), intialDelay + (t_timespan * t_counter) + timespan);

What do you mean by “unable to add…”?
Are you getting an error or are you getting the Unresponsive Script warning?
What kind of Layout are you using?

I receive “Unresponsive Script warning”

I use swimlane layout

There is no “swimlane layout”, but the Swimlanes sample does use LayeredDigraphLayout within each Group, and each “lane” is a Group.

So if you are trying to put thousands of nodes and links into a single lane, that’s not going to work – LayeredDigraphLayout is too slow to handle such a large graph. (Even in Java or .NET thousands would be pushing the limit, so it’s way too big for JavaScript. Read my earlier post.)

But if each lane/Group doesn’t have too many nodes and links, it might work. Still, I suspect this is not going to work in general. I suppose you could try using TreeLayout as the Group.layout and see if the results are acceptable. It really depends on the kinds of graphs that you have.

I use StackLayout, below you can see my diagram layout, is there any change required in diagram layout?

myDiagram =
$(go.Diagram, “gojsDiagram”,
{
// use a custom ResizingTool (along with a custom ResizeAdornment on each Group)
resizingTool: new GroupResizingTool(),
initialContentAlignment: go.Spot.TopCenter,
//autoScale: go.Diagram.Uniform,
allowHorizontalScroll: true,
allowVerticalScroll: true,
‘animationManager.isEnabled’: false,
//allowLink: false,
// use a simple layout that ignores links to stack the top-level Groups on top of each other
layout:
$(StackLayout,
{
cellSize: new go.Size(1, 1),
spacing: new go.Size(0, 0),
wrappingColumn: (HORIZONTAL ? 1 : Infinity),
wrappingWidth: Infinity,
isViewportSized: false,
comparer: keyCompare
}),
// don’t allow dropping onto the diagram’s background
mouseDrop: function (e) { e.diagram.currentTool.doCancel(); },
“toolManager.mouseWheelBehavior”: go.ToolManager.WheelZoom,
// a clipboard copied node is pasted into the original node’s group (i.e. lane).
“commandHandler.copiesGroupKey”: true
});

The StackLayout is required to keep all of the Groups, representing lanes, lined up and directly adjacent to each other in the Y direction.

How many lanes do you envision having, with what range of numbers of nodes and links “swimming” in each lane?

Correct.

Minimum of 12 swimlanes in Y direction, minimum of 5 nodes in each and maximum of 2000 nodes in each.

Try replacing the Group.layout with a TreeLayout to see if everything but the layout works for you. If it does, but it doesn’t when the Group.layout is a LayeredDigraphLayout, then we know the problem is the layout, for which we do not have a good alternative at this time. Perhaps there is a way of using nested grouping and progressive disclosure (expanding groups) that would work for your app.

I will check that now.

Meanwhile, I figured out what is the issue. As soon as I comment out ‘go.Link.AvoidsNodes’ and set the routing to ‘go.Link.Normal’, my 10000 links starts loading with out “Page Unresponsive” message.

But link should not overlap on the nodes as per business requirement.
Now, can you please help me on this? Below you see my link template

var linkTemplate =
$(go.Link,
{
//routing: isAngleView ? go.Link.AvoidsNodes : go.Link.Normal,
routing: go.Link.Normal,
//curve: go.Link.JumpOver,
//reshapable: true,
//resegmentable: true,
relinkableFrom: true,
relinkableTo: true,
fromPortId: “”,
toPortId: “”,
//corner: 5,
//segmentOrientation: go.Link.OrientUpright,
//curviness: 20,
//adjusting: go.Link.Scale,
name: ‘LINK’,
doubleClick: getLinkWindow.bind(this)
}

Thanks for figuring out that that might be the problem. One possibility is not to use routing=AvoidsNodes or curve=JumpOver in the template, but to change to those values after everything has loaded. You can do that in an “InitialLayoutCompleted” DiagramEvent listener.

As soon as I call the below code in “InitialLayoutCompleted” listener, I receive “Page Unresponsive” message. CryCry


myDiagram.links.each(function (l) {
l.routing = go.Link.AvoidsNodes;
});

You might need to set that property in batches in separate timer functions.