Fratel
Fratel

Reputation: 57

How to group nodes based on weight in Cytoscape cola

I am having trouble using cytoscape with cola.
I would like a network where nodes with "heavy" edges connecting them tend to stick closer to one another.
So far, my javascript code looks like this:

    var elems = [
    {data: {id: '1', name: 'Node 1', nodecolor: '#88cc88'}},
    {data: {id: '2', name: 'Node 2', nodecolor: '#888888'}},
    {data: {id: '3', name: 'Node 3', nodecolor: '#888888'}},
    {data: {id: '4', name: 'Node 4', nodecolor: '#888888'}},
    {data: {id: '5', name: 'Node 5', nodecolor: '#888888'}},
    {data: {id: 'e1', source: '1', target: '5', linkcolor: '#888888', "weight":50 } },
    {data: {id: 'e2', source: '3', target: '4', linkcolor: '#888888', "weight":30} },
    {data: {id: 'e3', source: '2', target: '1', linkcolor: '#888888', "weight":20} },
    {data: {id: 'e4', source: '1', target: '4', linkcolor: '#888888', "weight":100} },
    {data: {id: 'e5', source: '5', target: '2', linkcolor: '#888888', "weight":100} },
    {data: {id: 'e6', source: '1', target: '2', linkcolor: '#888888', "weight":40} }
];
var cy = cytoscape({
    container: document.getElementById('cy'),
    elements: elems,
    style: cytoscape.stylesheet()
            .selector('node').style({
                'background-color': 'data(nodecolor)',
                label: 'data(name)',
                width: 25,
                height: 25
            })
            .selector('edge').style({
                'line-color': 'data(linkcolor)',
                width: 3
            })
});
cy.layout({name: 'cola',
           infinite: true,
           fit: false,
           padding: 10,
           edgeLength: function( edge ){var len = edge.data('weight'); return 10/len; }});

As you can see, I tried to change the edgeLength parameter to be proportionally inverse to the "weight" property of the edges, but it doesn't seem to make any difference.

Upvotes: 0

Views: 883

Answers (1)

maxkfranz
maxkfranz

Reputation: 12250

You must use a formula that returns sensible lengths for edges. Your formula returns lengths less than one pixel for all edges. That's an impossible restriction, especially considering that Cola supports options like avoidOverlap and nodeSpacing.

A more appropriate formula would be something like edge => k / edge.data('weight') where k is something around the order of magnitude of 10000 -- you chose k = 10. k = 10000 gives e4 a length of 100 and e3 a length of 500, for example.

In order to use a layout effectively, it is important to carefully review all the layout options and make sure you set them appropriately for the result you want.

Upvotes: 1

Related Questions