anvaka / VivaGraphJS

Graph drawing library for JavaScript
Other
3.78k stars 425 forks source link

Directed graph with vivagraphjs #173

Open Potote opened 8 years ago

Potote commented 8 years ago

I have to do a Social Network analysis using any javascript library. After see a lot of library, i decided use vivagraph because the great interface and interaction with it.

However, i need to do directed graph with some values. There is a great example of edges with arrows, but only use "id" for show that´s value, and i need to put any values. The "id" values cant be repeated, and that´s is my problem. Here is my code:

<script language="javascript" type="text/javascript" >
            function draw_graph() {
                var graph = Viva.Graph.graph();
                var graphics = Viva.Graph.View.svgGraphics(),
                nodeSize = 40;
                graphics.node(function(node){
                    return Viva.Graph.svg('image')
                            .attr('width', nodeSize)
                            .attr('height', nodeSize)
                            .link(node.data.url);
                })
                .placeNode(function(nodeUI, pos){
                    nodeUI.attr('x', pos.x - nodeSize/2).attr('y', pos.y - nodeSize/2);
                });

                var createMarker = function(id, integer_container) {
                return Viva.Graph.svg('marker')
                    .attr('id', id)
                    .attr('integer_container', integer_container)
                    .attr('viewBox', "0 0 10 10")
                    .attr('refX', "10")
                    .attr('refY', "5")
                    .attr('markerUnits', "strokeWidth")
                    .attr('markerWidth', "10")
                    .attr('markerHeight', "5")
                    .attr('orient', "auto");
                },

                marker = createMarker('Triangle');
                marker.append('path').attr('d', 'M 0 0 L 10 5 L 0 10 z');

                var defs = graphics.getSvgRoot().append('defs');
                defs.append(marker);

                var geom = Viva.Graph.geom();

                graphics.link(function(link){
                var label = Viva.Graph.svg('text').attr('id','label_'+link.data.id).text(link.data.id);
                var info_container = Viva.Graph.svg('text').attr('integer_container','label_'+link.data.integer_container).text(link.data.integer_container);

                graphics.getSvgRoot().childNodes[0].append(label);
                graphics.getSvgRoot().childNodes[1].append(info_container);

    return Viva.Graph.svg('path')
        .attr('stroke', 'gray')
        .attr('marker-end', 'url(#Triangle)')
        .attr('id', link.data.id)
        .attr('integer_container', link.data.integer_container);
    }).placeLink(function(linkUI, fromPos, toPos) {
        var toNodeSize = nodeSize,
        fromNodeSize = nodeSize;

        var from = geom.intersectRect(
            fromPos.x - fromNodeSize / 2, // left
            fromPos.y - fromNodeSize / 2, // top
            fromPos.x + fromNodeSize / 2, // right
            fromPos.y + fromNodeSize / 2, // bottom
            fromPos.x, fromPos.y, toPos.x, toPos.y)
        || fromPos;

        var to = geom.intersectRect(
            toPos.x - toNodeSize / 2, // left
            toPos.y - toNodeSize / 2, // top
            toPos.x + toNodeSize / 2, // right
            toPos.y + toNodeSize / 2, // bottom
            // segment:
            toPos.x, toPos.y, fromPos.x, fromPos.y)
            || toPos;

        var data = 'M' + from.x + ',' + from.y +
            'L' + to.x + ',' + to.y;

        linkUI.attr("d", data);

        var result = document.getElementsByTagName('label_'+linkUI.attr('integer_container'))
                //this dont run
                                //result.attr("x", (from.x + to.x) / 2);
                //result.attr("y", (from.y + to.y) / 2);

        var entry = document.getElementById('label_'+linkUI.attr('id'));
                entry.attr("x", (from.x + to.x) / 2);
                entry.attr("y", (from.y + to.y) / 2);
    });

                graph.addNode('User1', {url : 'http://oi68.tinypic.com/x57d3m.jpg'});
                graph.addNode('User2', {url : 'http://oi68.tinypic.com/x57d3m.jpg'});
                graph.addNode('User3', {url : 'http://oi68.tinypic.com/x57d3m.jpg'});
                graph.addNode('User4', {url : 'http://oi68.tinypic.com/x57d3m.jpg'});
                graph.addNode('User5', {url : 'http://oi68.tinypic.com/x57d3m.jpg'});
                graph.addLink('User1', 'User2', {id : 1, integer_container : 1});
                graph.addLink('User2', 'User3', {id : 2, integer_container : 2});
                graph.addLink('User3', 'User1', {id : 3, integer_container : 1});
                graph.addLink('User4', 'User2', {id : 4, integer_container : 1});
                graph.addLink('User5', 'User2', {id : 5, integer_container: 2});

                var layout = Viva.Graph.Layout.forceDirected(graph, {
                    springLength : 200,
                    springCoeff : 0.0005,
                    dragCoeff : 0.02,
                    gravity : -4.0
                    });
                var renderer = Viva.Graph.View.renderer(graph,
                    {
                        layout : layout,
                        graphics : graphics
                });
                renderer.run(); 
                //list each nodes from the graph
                graph.forEachNode(function(node){
                    console.log(node.id, node.data);
                });
                // show the connected nodes with user id 1
                graph.forEachLinkedNode('User1', function(linkedNode, link){
                    console.log("Connected node: ", linkedNode.id, linkedNode.data); 
                    console.dir(link); // link object itself
                });     
            }
      </script>

Any sugestions?

gg4u commented 7 years ago

You could store the direction in the link.data either as set a data attribute in SVG might you need it for rendering purpose