Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3 Directed Graph Editor additions

I have been trying to augment the d3 Directed Graph Editor code with a couple of ideas which would make it a very intuitive interface for people wanting to "manually grow" a graph. I managed to change the node ids to strings which the user can enter through a prompt call. The same goes for adding a "type" value to the links connecting the nodes.

The part I struggling with is that I can't manage to get the link property "type" rendered in the middle of the link when the graph redraws. Can anybody offer help/the code I would be able to manage doing so?

Here are the lines which set up example nodes and links:

var nodes = [
    {id: 'some name', reflexive: false},
    {id: 'some other name', reflexive: true },
    {id: 'some 3rd name', reflexive: false}
],
links = [
    {source: nodes[0], target: nodes[1], left: false, right: true ,type: 'some type I'},
    {source: nodes[1], target: nodes[2], left: false, right: true, type: 'some type II'}
];

When the nodes get rendered there is a code which adds the id as a string:

g.append('svg:text')
    .attr('x', 0)
    .attr('y', 4)
    .attr('class', 'id')
    .text(function(d) { return d.id; });

However when the links get redrawn there is no function which get's the value of the type property and parses it 1/2 way between the coordinates of the source and target nodes. Here is the code which deals, as far as I can tell with rendering the links.

// update existing links
path.classed('selected', function(d) { return d === selected_link; })
    .style('marker-start', function(d) { return d.left ? 'url(#start-arrow)' : ''; })
    .style('marker-end', function(d) { return d.right ? 'url(#end-arrow)' : ''; });


// add new links
path.enter().append('svg:path')
    .attr('class', 'link')
    .classed('selected', function(d) { return d === selected_link; })
    .style('marker-start', function(d) { return d.left ? 'url(#start-arrow)' : ''; })
    .style('marker-end', function(d) { return d.right ? 'url(#end-arrow)' : ''; })
    .on('mousedown', function(d) {
        if(d3.event.ctrlKey) return;

        // select link
        mousedown_link = d;
        if(mousedown_link === selected_link) selected_link = null;
        else selected_link = mousedown_link;
        selected_node = null;
        restart();
    });

Here is a link to a jsfiddle with the latest version of the code.

like image 601
swissintegrator Avatar asked Sep 29 '22 01:09

swissintegrator


1 Answers

In your tick function just recalculate the xy position of your text based on source and target xy:

 function tick() {
   d3.selectAll("text")
   .attr("x", function(d) {return (d.source.x + d.target.x) / 2})
   .attr("y", function(d) {return (d.source.y + d.target.y) / 2})
 }

Here's an updated jsFiddle with path labels: http://jsfiddle.net/rco31ofe/2/

like image 122
Elijah Avatar answered Oct 01 '22 18:10

Elijah