anvaka / VivaGraphJS

Graph drawing library for JavaScript
Other
3.73k stars 423 forks source link

How to structure the layout of customized nodes OR how to define positions for customized nodes #100

Closed AfterEight closed 9 years ago

AfterEight commented 9 years ago

Hello,

first of all, thank you for sharing your lib. I really enjoy working with it, but somehow I got stuck with the following problem: I am using customized nodes, e.g.,
var ui = Viva.Graph.svg('g'), text = Viva.Graph.svg('text').text(node.data).attr('width', node.data.size).attr('height', node.data.size).attr("id", '1').attr("font-weight", 'bold'), img = Viva.Graph.svg('image').attr('width', 84).attr('height', 84).link('img/A/' + node.data + '.jpg'); ui.append(text); ui.append(img); ui.myCustomSize = node.data.size; There are several of such nodes in one graph. But not all of these node are connected to a center node, e.g.,
graph.addLink(1, 2); graph.addLink(2, 3); graph.addLink(1, 4); graph.addLink(4, 5); graph.addLink(5, 6); graph.addLink(4, 7); graph.addLink(7, 8); graph.addLink(8, 9); As this results in a layout like a mess, I tried to define custom positions like .placeNode(function(nodeUI, pos) { nodeUI.attr('transform','translate(' +(pos.x) + ',' + (pos.y) + ')');

and: ui.attr('transform','translate(100,298)'); and: var constantLayout = Viva.Graph.Layout.constant(graph); but this even do not result in a structured layout.

Can you please tell me how to force customized nodes to a defined position OR how to adapt the automatically positioning, so that the nodes do not overlap each other?

Below the complete code

function changeAirPollutionDiv() { if (document.getElementById("myDiv").style.display == 'none') { document.getElementById("myDiv").style.display = 'block'; var object = document.getElementById("myDiv"); while (object.hasChildNodes()) { object.removeChild(object.firstChild); } var graph = Viva.Graph.graph();

   nodePositions = [
                {x: 0, y: 0},
                {x: 0, y: 0},
                {x: 0, y: 0},
                {x: 0, y: -50},
                {x: 0, y: -75},
                {x: 0, y: -100},
                {x: 0, y: -25},
                {x: 0, y: 0}

    var firstNode=graph.addNode(1, 'A');
    firstNode.isPinned = true;
    graph.addNode(2, 'P');
    graph.addNode(3, 'S');
    graph.addNode(4, 'E');
     graph.addNode(5, 'F');
     graph.addNode(6, 'W');

     graph.addNode(7, 'N');
     graph.addNode(8, 'S');
     graph.addNode(9, 'T');

    graph.addLink(1, 2);
    graph.addLink(2, 3);
    graph.addLink(1, 4);
    graph.addLink(4, 5);
    graph.addLink(5, 6);
    graph.addLink(4, 7);
    graph.addLink(7, 8);
    graph.addLink(8, 9);
    var graphics = Viva.Graph.View.svgGraphics();
    var nodeSize = 40;
    var no = 20;

    graphics.node(function (node) {
        if (node.id == 1) {
            var ui = Viva.Graph.svg('g'), 
            text = Viva.Graph.svg('text').text(node.data).attr('width', node.data.size).attr('height', node.data.size).attr("id", '1').attr("font-weight", 'bold'),
            img = Viva.Graph.svg('image').attr('width', 84).attr('height', 84).link('img/A/' + node.data + '.jpg');
            ui.append(text);
            ui.append(img);
            ui.myCustomSize = node.data.size;
            return ui;
        } else {
            var ui = Viva.Graph.svg('g'),
                    text = Viva.Graph.svg('text').text(node.data).attr('width', node.data.size).attr('height', node.data.size).attr("id", '2'),
                    img = Viva.Graph.svg('image').attr('width', 84).attr('height', 84).link('img/A/' + node.data + '.jpg');
            ui.append(text);
            ui.append(img);
            ui.myCustomSize = node.data.size;
            //pinNode(1, !layout.isNodePinned(node));
            return ui;
        }

    .placeNode(function(nodeUI, pos) {
     nodeUI.attr('transform','translate(' +(pos.x) + ',' + (pos.y) + ')');

     });

    var renderer = Viva.Graph.View.renderer(graph,{

                        container: document.getElementById("myDiv"),
                        graphics: graphics

                    });
    renderer.run();
}
else {
    document.getElementById("myDiv").style.display = 'none';

}

}

anvaka commented 9 years ago

I tried to reproduce the problem, but I need more info.

Here is the running application, based on your source code:

http://plnkr.co/edit/wG6K9nxl7A79PjSSk4bY?p=preview

It is missing images, that is expected. Otherwise, what is wrong with it?

AfterEight commented 9 years ago

Hey, thanks for your quick reply. I quecked for the differences: With https://anvaka.github.io/VivaGraphJS/dist/vivagraph.js you are linking to version 0.5.71. I am using version 0.5.72. Because of the differences in these versions in function integrate : function (simulator, timeStep){ ... It is not working with 0.5.72. I rolled back to 0.5.71. Thanks again for your help Greetings

anvaka commented 9 years ago

Maybe I'm missing something, but it works in 0.5.72 as well: http://plnkr.co/edit/wG6K9nxl7A79PjSSk4bY?p=preview

How do you reference vivagraph library in html? Are you using something like

<script src='https://raw.githubusercontent.com/anvaka/VivaGraphJS/master/dist/vivagraph.js'></script>

?

ahmetkizilay commented 9 years ago

I think the problem @AfterEight is referring to is related to the stability checking algorithm introduced in the latest version. With the new version, the renderer stops immediately, before nodes could spread out like it does in the 0.5.71. One thing you can do is to use the prerender parameter. If you set prerender to something like 1200, the nodes are spreaded out when graph is loaded.

var renderer = Viva.Graph.View.renderer(graph, {
  graphics: graphics,
  prerender: 1200
});

Check out this fork of @anvaka's example link

AfterEight commented 9 years ago

@artsince: That's the point. Thank you for the workaround

mcpat1993 commented 6 years ago

I think after you perform a graph.clear() the isPinned = true variable doesn't work any more. Any idea why this is?