score:2

Accepted answer

var graph = {
    "nodes": [{
            "name": "1",
            "rating": 90,
            "id": 2951,
            "x": 90,
            "y": 50,
           "fixed": true
        }, {
            "name": "2",
            "rating": 80,
            "id": 654654,
            "x": 50,
            "y": 50,
            "fixed": true
        }, {
            "name": "3",
            "rating": 80,
            "id": 6546544,
            "x": 50,
            "y": 90,
            "fixed": true
        },

    ],
    "links": [{
            "source": 1,
            "target": 0,
            "value": 6,
            "label": "publishedOn"
        }, {
            "source": 1,
            "target": 2,
            "value": 6,
            "label": "publishedOn"
        }, {
            "source": 1,
            "target": 0,
            "value": 4,
            "label": "containsKeyword"
        },

    ]
}


var margin = {
    top: -5,
    right: -5,
    bottom: -5,
    left: -5
};
var width = 500 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-200)
    .linkDistance(50)
    .size([width + margin.left + margin.right, height + margin.top + margin.bottom]);

var zoom = d3.behavior.zoom()
     .scaleExtent([.1, 1])
    .on("zoom", zoomed);
 
var drag = d3.behavior.drag()
    .origin(function(d) {
        return d;
    })
    .on("dragstart", dragstarted)
    .on("drag", dragged)
    .on("dragend", dragended);


var svg = d3.select("#map").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.right + ")").call(zoom);

var rect = svg.append("rect")
    .attr("width", width)
    .attr("height", height)
    .style("fill", "none")
    .style("pointer-events", "all");

var container = svg.append("g");

//d3.json('http://blt909.free.fr/wd/map2.json', function(error, graph) {



force
    .nodes(graph.nodes)
    .links(graph.links)
    .start();

var movement = 200;

var link = container.append("g")
   // .attr("class", "links")
    .selectAll(".link")
    .data(graph.links)
    .enter().append("line")
    .attr("class", "link")
    .style("stroke-width", function(d) {
        return Math.sqrt(d.value);
    })
    //.attr("transform", function(d) {
    //    return "translate(" + movement + "," + 0 + ")";
    //})
.attr("x1", function(d) { return d.source.x; })
	.attr("y1", function(d) { return d.source.y; })
	.attr("x2", function(d) { return d.target.x; })
	.attr("y2", function(d) { return d.target.y; })
; 


var node = container
    .selectAll(".node").append("g")
    
    .data(graph.nodes)
    .enter().append("g")

    .attr("class", "node")
    .attr("cx", function(d) {
        return d.x;
    })
    .attr("cy", function(d) {
        return d.y;
    })
    .call(drag)
;

node.append("circle")

    .attr("r", function(d) {
        return d.weight * 2 + 12;
    })
    .style("fill", function(d) {
        return color(1 / d.rating);
    })
    //.attr("transform", function(d) {
    //    return "translate(" + movement + "," + 0 + ")";
    //})
//.call(drag)
; //Here you move the nodes

force.on("tick", tick);

function tick(){
//force.on("tick", function() {
    link.attr("x1", function(d) {
            return d.source.x;
        })
        .attr("y1", function(d) {
            return d.source.y;
        })
        .attr("x2", function(d) {
            return d.target.x;
        })
        .attr("y2", function(d) {
            return d.target.y;
        });

    node.attr("transform", function(d) {
        //Here i create a node radius so it doesnt go offscreen
        var nodeRadius = d.weight * 2 + 12
        
        //here I do checks to see if it goes offscreen
        if(d.x<= nodeRadius){
           d.x = nodeRadius;
           }
        if(d.y<= nodeRadius){
           d.y = nodeRadius;
           }7
        if(d.x>width - nodeRadius){
           d.x = width - nodeRadius;
           }
        if(d.y>height - nodeRadius){
           d.y = height - nodeRadius;
           }
        
        return "translate(" + d.x + "," + d.y + ")";
        
    });
}

var linkedByIndex = {};
graph.links.forEach(function(d) {
    linkedByIndex[d.source.index + "," + d.target.index] = 1;
});

function isConnected(a, b) {
    return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index];
}

node.on("mouseover", function(d) {
    link.attr("stroke-dasharray", 10 + " " + 10)
    .attr("stroke-dashoffset", 500)
    .transition()
    .duration(2000)
    .ease("linear")
    .attr("stroke-dashoffset", 0);
    
    
    node.classed("node-active", function(o) {
        thisOpacity = isConnected(d, o) ? true : false;
        this.setAttribute('fill-opacity', thisOpacity);
        return thisOpacity;
    });

    link.classed("link-active", function(o) {
        return o.source === d || o.target === d ? true : false;
    });

    d3.select(this).classed("node-active", true);
    d3.select(this).select("circle").transition()
        .duration(750)
        .attr("r", (d.weight * 2 + 12) * 1.5);
})

.on("mouseout", function(d) {

  link.attr("stroke-dasharray", 0).attr("stroke-dashoffset", 0);
    node.classed("node-active", false);
    link.classed("link-active", false);

    d3.select(this).select("circle").transition()
        .duration(750)
        .attr("r", d.weight * 2 + 12);
});


function dottype(d) {
    d.x = +d.x;
    d.y = +d.y;
    return d;
}

function zoomed() {
    container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}

function dragstarted(d) {
    d3.event.sourceEvent.stopPropagation();

    d3.select(this).classed("dragging", true);
    force.start();
}

function dragged(d) {
    force.stop();
    d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
    
     
    tick(); 

}

function dragended(d) {
    d.fixed = true;

    //d3.select(this).classed("dragging", false);
    tick();
}
.node {
  stroke: #fff;
  stroke-width: 1.5px;
}

.node-active{
  stroke: #555;
  stroke-width: 1.5px;
}

.link {
  stroke: #555;
  stroke-opacity: .3;
}

.link-active {
  stroke-opacity: 1;
}

.overlay {
  fill: none;
  pointer-events: all;
}

#map{
    border: 2px #555 dashed;
    width:500px;
    height:400px;
}
<link href="https://code.jquery.com/ui/1.10.4/themes/black-tie/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="map"></div>

Hope you are looking for this,

Description for the code In mouse over function I've added below lines of code

link.attr("stroke-dasharray", 10 + " " + 10)
        .attr("stroke-dashoffset", 500)
        .transition()
        .duration(2000)
        .ease("linear")
        .attr("stroke-dashoffset", 0);

above I'm setting stroke-dasharray attribute with "10 10" this will make line to be displayed in dashed style like - - - -, next setting stroke-dashoffset with 500 this value makes the dashes to move faster means value changes 0 to 500 in the time span of 2000 milliseconds which is mentioned in duration(2000) of transition above you can see that. After completion of transition I'm changing stroke-dashoffset to 0 to make it as line,

And also in mouseout function I've added below line

link.attr("stroke-dasharray", 0).attr("stroke-dashoffset", 0);

This will make the lines again from dashed to single line.

And For more observation Once you mouseover to any circle the animation will started and it'll continued for 2seconds, but within 2seconds if you mouseover to the circle you can see the animation which is activated previously and still running. So that is left for your choice whether to play the animation for 2seconds or not, hope you understood where to change the value for this, And one more thing is when you want to make it as a single line, immediately when the mouseout is fired or after the animation is completed. These two things need to be observed.

Hope you understood every thing, If not ask me. Okay.I might have done this yesterday, due to time and system availability.


Related Query