I am not able to figure out what I am doing wrong in the following html code. I have a JSON file with a "cohesive" attribute which is a continuous variable. I want to draw a force directed graph on D3JS using the JSON file with the node color reflecting the difference in cohesive energy. When I run this script, I don't get any errors but there is no output as well. I just started with HTML scripting so please forgive me if I am making a very silly error but I would really appreciate if someone could point out what I am doing wrong.
function convertRange(value, r1, r2) {
return (value - r1[0]) * (r2[1] - r2[0]) / (r1[1] - r1[0]) + r2[0];
}
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var colorScale = d3.scaleLinear(d3.interpolateViridis);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
d3.json("Perovskite_info.json", function(error, graph) {
if (error) throw error;
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", function(d) {
return Math.sqrt(d.value);
});
var node = svg.append("g")
.attr("nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 5)
.attr("fill", function(d) {
return colorScale(convertRange(d.cohesive_en, [1.6, 7.2], [0, 1]));
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
node.append("title")
.text(function(d) {
return d.id;
});
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.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;
});
}
});
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;
}
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: black;
stroke-width: 1.5px;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<h1>Cohesive Energy Calculation</h1>
<svg width="1060" height="800"></svg>
This is how one my json begins:
{"directed": false, "multigraph": false, "graph": {}, "nodes": [{"pos": [-37.50340668168362, -0.6442713601030169], "cohesive_en": 5.752120797750001, "cohesive": 5.752120797750001, "cluster": 1, "similarity": 0.6371195466189876, "id": "PrCoO3"},
For the full JSON please follow this link: https://api.myjson.com/bins/m3gd8
Edit: So I figured out what the problems were:
First off, as one of the answers stated, I was using d3.v5 but using the d3v4 api to import data. Secondly, I also needed to import the d3 interpolate module which I hadn't done. So the code wasn't working. This question was asked at a point where I had done d3 for 2 days so the quality of the code is low.