Built with blockbuilder.org
Referred from but converted to d3 v4.
https://bl.ocks.org/mohdsanadzakirizvi/6fc325042ce110e1afc1a7124d087130
http://www.coppelia.io/2014/07/an-a-to-z-of-extra-features-for-the-d3-force-layout/
xxxxxxxxxx
<html>
<head>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.11.0/jquery-ui.min.js"></script>
<link type="text/css" href="https://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css">
</link>
<style>
.link {
stroke: #ccc;
}
.node text {
pointer-events: none;
font: sans-serif;
}
</style>
</head>
<body>
<div class="ui-widget">
<input id="search">
<button type="button" onclick="searchNode()">Search</button>
</div>
<svg></svg>
<script type="text/javascript">
//Set margins and sizes
var margin = {
top: 20,
bottom: 50,
right: 30,
left: 50
};
//Load Color Scale
var color = d3.scaleOrdinal(d3.schemeCategory20);
//Create an SVG element and append it to the DOM
var width = 960 - margin.left - margin.right;
var height = 700 - margin.top - margin.bottom;
var svgElement = d3.select("svg");
svgElement.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function (d) {
return d.id;
}).distance(200))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
//Load External Data
d3.json("got_social_graph.json", function (dataset) {
//Extract data from dataset
var nodes = dataset.nodes,
links = dataset.links;
var link = svgElement.append("g")
.attr("class", "link")
.selectAll("line")
.data(links)
.enter()
.append("line")
.attr("stroke-width", function (d) {
return d.weight / 10;
});
var node = svgElement.selectAll("g.node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node");
node.append("circle")
.attr("r", function (d) {
return d.influence / 2 > 5 ? d.influence / 2 : 5;
})
.attr("fill", function (d) {
return color(d.zone * 10);
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
node.append("text")
.attr("dx", 12)
.attr("dy", "0.35em")
.attr("font-size", function (d) {
return d.influence * 1.5 > 9 ? d.influence * 1.5 : 9;
})
.text(d => d.character);
node.on('dblclick', connectedNodes);
var optArray = [];
for (var i = 0; i < nodes.length - 1; i++) {
optArray.push(nodes[i].character);
}
optArray = optArray.sort();
console.log(optArray);
jQuery(function () {
jQuery("#search").autocomplete({
source: optArray
});
});
//Toggle stores whether the highlighting is on
var toggle = 0;
//Create an array logging what is connected to what
var linkedByIndex = {};
for (i = 0; i < dataset.nodes.length; i++) {
linkedByIndex[i + "," + i] = 1;
};
dataset.links.forEach(function (d) {
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
//This function looks up whether a pair are neighbours
function neighboring(a, b) {
return linkedByIndex[a.index + "," + b.index];
}
function connectedNodes() {
if (toggle == 0) {
//Reduce the opacity of all but the neighbouring nodes
d = d3.select(this).node().__data__;
node.style("opacity", function (o) {
return neighboring(d, o) | neighboring(o, d) ? 1 : 0.25;
});
link.style("opacity", function (o) {
return d.index == o.source.index | d.index == o.target.index ? 1 : 0.25;
});
//Reduce the op
toggle = 1;
} else {
//Put them back to opacity=1
node.style("opacity", 1);
link.style("opacity", 1);
toggle = 0;
}
}
//This function will be executed for every tick of force layout
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
function ticked() {
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("cx", function (d) {
return d.x;
})
.attr("cy", function (d) {
return d.y;
});
d3.selectAll("g.node")
.attr("transform", d => `translate(${d.x} , ${d.y})`)
}
});
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
function searchNode() {
//find the node
var selectedVal = document.getElementById('search').value;
var node = svgElement.selectAll(".node");
if (selectedVal == "none") {
node.style("stroke", "white").style("stroke-width", "1");
} else {
var selected = node.filter(function (d, i) {
return d.character != selectedVal;
});
selected.style("opacity", "0");
var link = svgElement.selectAll(".link")
link.style("opacity", "0");
d3.selectAll(".node, .link").transition()
.duration(5000)
.style("opacity", 1);
}
}
</script>
</body>
</html>
Modified http://d3js.org/d3-selection-multi.v1.js to a secure url
Modified http://code.jquery.com/ui/1.11.0/jquery-ui.min.js to a secure url
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-selection-multi.v1.js
https://code.jquery.com/ui/1.11.0/jquery-ui.min.js