How to add text in the center of node in force directed graph? [duplicate] - d3.js

This question already has answers here:
Placing labels at the center of nodes in d3.js
(3 answers)
Closed 7 years ago.
Here is the code to draw to text in the center of the circle.
node.append("text")
.attr("dx", 10)
.attr("dy", ".35em")
.text(function(d) { return d.group });
Here is the jsfiddle

Just set text-anchor attribute middle to the text element. This code would work even for nodes having different size.
node.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.text(function(d) { return d.group });
Working snippet:
var width = 500,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(80)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var mis = document.getElementById('mis').innerHTML;
graph = JSON.parse(mis);
force.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) {
return Math.sqrt(d.value);
});
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", function(d,i){ return i%2==0?10:8 })
.style("fill", function(d) {
return color(d.group);
})
node.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.text(function(d) {
return d.group
});
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;
});
d3.selectAll("circle").attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
d3.selectAll("text").attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
});
});
.link {
stroke: #ccc;
}
.node text {
pointer-events: none;
font: 10px sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script type="application/json" id="mis">
{ "nodes": [{ "name": "Myriel", "group": 1 }, { "name": "Napoleon", "group": 1 }, { "name": "Mlle.Baptistine", "group": 1 }, { "name": "Mme.Magloire", "group": 1 }, { "name": "CountessdeLo", "group": 1 }, { "name": "Geborand", "group": 1 }, { "name": "Champtercier", "group": 1 }, { "name": "Cravatte", "group": 1 }, { "name": "Count", "group": 1 }, { "name": "OldMan", "group": 1 }, { "name": "Labarre", "group": 2 }, { "name": "Valjean", "group": 2 }, { "name": "Marguerite", "group": 3 }, { "name": "Mme.deR", "group": 2 }, { "name": "Isabeau", "group": 2 }, { "name": "Gervais", "group": 2 }, { "name": "Tholomyes", "group": 3 }, { "name": "Listolier", "group": 3 }, { "name": "Fameuil", "group": 3 }, { "name": "Blacheville", "group": 3 }, { "name": "Favourite", "group": 3 }, { "name": "Dahlia", "group": 3 }, { "name": "Zephine", "group": 3 }, { "name": "Fantine", "group": 3 }, { "name": "Mme.Thenardier", "group": 4 }, { "name": "Thenardier", "group": 4 }, { "name": "Cosette", "group": 5 }, { "name": "Javert", "group": 4 }, { "name": "Fauchelevent", "group": 0 }, { "name": "Bamatabois", "group": 2 }, { "name": "Perpetue", "group": 3 }, { "name": "Simplice", "group": 2 }, { "name": "Scaufflaire", "group": 2 }, { "name": "Woman1", "group": 2 }, { "name": "Judge", "group": 2 }, { "name": "Champmathieu", "group": 2 }, { "name": "Brevet", "group": 2 }, { "name": "Chenildieu", "group": 2 }, { "name": "Cochepaille", "group": 2 }, { "name": "Pontmercy", "group": 4 }, { "name": "Boulatruelle", "group": 6 }, { "name": "Eponine", "group": 4 }, { "name": "Anzelma", "group": 4 }, { "name": "Woman2", "group": 5 }, { "name": "MotherInnocent", "group": 0 }, { "name": "Gribier", "group": 0 }, { "name": "Jondrette", "group": 7 }, { "name": "Mme.Burgon", "group": 7 }, { "name": "Gavroche", "group": 8 }, { "name": "Gillenormand", "group": 5 }, { "name": "Magnon", "group": 5 }, { "name": "Mlle.Gillenormand", "group": 5 }, { "name": "Mme.Pontmercy", "group": 5 }, { "name": "Mlle.Vaubois", "group": 5 }, { "name": "Lt.Gillenormand", "group": 5 }, { "name": "Marius", "group": 8 }, { "name": "BaronessT", "group": 5 }, { "name": "Mabeuf", "group": 8 }, { "name": "Enjolras", "group": 8 }, { "name": "Combeferre", "group": 8 }, { "name": "Prouvaire", "group": 8 }, { "name": "Feuilly", "group": 8 }, { "name": "Courfeyrac", "group": 8 }, { "name": "Bahorel", "group": 8 }, { "name": "Bossuet", "group": 8 }, { "name": "Joly", "group": 8 }, { "name": "Grantaire", "group": 8 }, { "name": "MotherPlutarch", "group": 9 }, { "name": "Gueulemer", "group": 4 }, { "name": "Babet", "group": 4 }, { "name": "Claquesous", "group": 4 }, { "name": "Montparnasse", "group": 4 }, { "name": "Toussaint", "group": 5 }, { "name": "Child1", "group": 10 }, { "name": "Child2", "group": 10 }, { "name": "Brujon", "group": 4 }, { "name": "Mme.Hucheloup", "group": 8 }], "links": [{ "source": 1, "target": 0, "value": 1 }, { "source": 2, "target": 0, "value": 8 }, { "source": 3, "target": 0, "value": 10 }, { "source": 3, "target": 2, "value": 6 }, { "source": 4, "target": 0, "value": 1 }, { "source": 5, "target": 0, "value": 1 }, { "source": 6, "target": 0, "value": 1 }, { "source": 7, "target": 0, "value": 1 }, { "source": 8, "target": 0, "value": 2 }, { "source": 9, "target": 0, "value": 1 }, { "source": 11, "target": 10, "value": 1 }, { "source": 11, "target": 3, "value": 3 }, { "source": 11, "target": 2, "value": 3 }, { "source": 11, "target": 0, "value": 5 }, { "source": 12, "target": 11, "value": 1 }, { "source": 13, "target": 11, "value": 1 }, { "source": 14, "target": 11, "value": 1 }, { "source": 15, "target": 11, "value": 1 }, { "source": 17, "target": 16, "value": 4 }, { "source": 18, "target": 16, "value": 4 }, { "source": 18, "target": 17, "value": 4 }, { "source": 19, "target": 16, "value": 4 }, { "source": 19, "target": 17, "value": 4 }, { "source": 19, "target": 18, "value": 4 }, { "source": 20, "target": 16, "value": 3 }, { "source": 20, "target": 17, "value": 3 }, { "source": 20, "target": 18, "value": 3 }, { "source": 20, "target": 19, "value": 4 }, { "source": 21, "target": 16, "value": 3 }, { "source": 21, "target": 17, "value": 3 }, { "source": 21, "target": 18, "value": 3 }, { "source": 21, "target": 19, "value": 3 }, { "source": 21, "target": 20, "value": 5 }, { "source": 22, "target": 16, "value": 3 }, { "source": 22, "target": 17, "value": 3 }, { "source": 22, "target": 18, "value": 3 }, { "source": 22, "target": 19, "value": 3 }, { "source": 22, "target": 20, "value": 4 }, { "source": 22, "target": 21, "value": 4 }, { "source": 23, "target": 16, "value": 3 }, { "source": 23, "target": 17, "value": 3 }, { "source": 23, "target": 18, "value": 3 }, { "source": 23, "target": 19, "value": 3 }, { "source": 23, "target": 20, "value": 4 }, { "source": 23, "target": 21, "value": 4 }, { "source": 23, "target": 22, "value": 4 }, { "source": 23, "target": 12, "value": 2 }, { "source": 23, "target": 11, "value": 9 }, { "source": 24, "target": 23, "value": 2 }, { "source": 24, "target": 11, "value": 7 }, { "source": 25, "target": 24, "value": 13 }, { "source": 25, "target": 23, "value": 1 }, { "source": 25, "target": 11, "value": 12 }, { "source": 26, "target": 24, "value": 4 }, { "source": 26, "target": 11, "value": 31 }, { "source": 26, "target": 16, "value": 1 }, { "source": 26, "target": 25, "value": 1 }, { "source": 27, "target": 11, "value": 17 }, { "source": 27, "target": 23, "value": 5 }, { "source": 27, "target": 25, "value": 5 }, { "source": 27, "target": 24, "value": 1 }, { "source": 27, "target": 26, "value": 1 }, { "source": 28, "target": 11, "value": 8 }, { "source": 28, "target": 27, "value": 1 }, { "source": 29, "target": 23, "value": 1 }, { "source": 29, "target": 27, "value": 1 }, { "source": 29, "target": 11, "value": 2 }, { "source": 30, "target": 23, "value": 1 }, { "source": 31, "target": 30, "value": 2 }, { "source": 31, "target": 11, "value": 3 }, { "source": 31, "target": 23, "value": 2 }, { "source": 31, "target": 27, "value": 1 }, { "source": 32, "target": 11, "value": 1 }, { "source": 33, "target": 11, "value": 2 }, { "source": 33, "target": 27, "value": 1 }, { "source": 34, "target": 11, "value": 3 }, { "source": 34, "target": 29, "value": 2 }, { "source": 35, "target": 11, "value": 3 }, { "source": 35, "target": 34, "value": 3 }, { "source": 35, "target": 29, "value": 2 }, { "source": 36, "target": 34, "value": 2 }, { "source": 36, "target": 35, "value": 2 }, { "source": 36, "target": 11, "value": 2 }, { "source": 36, "target": 29, "value": 1 }, { "source": 37, "target": 34, "value": 2 }, { "source": 37, "target": 35, "value": 2 }, { "source": 37, "target": 36, "value": 2 }, { "source": 37, "target": 11, "value": 2 }, { "source": 37, "target": 29, "value": 1 }, { "source": 38, "target": 34, "value": 2 }, { "source": 38, "target": 35, "value": 2 }, { "source": 38, "target": 36, "value": 2 }, { "source": 38, "target": 37, "value": 2 }, { "source": 38, "target": 11, "value": 2 }, { "source": 38, "target": 29, "value": 1 }, { "source": 39, "target": 25, "value": 1 }, { "source": 40, "target": 25, "value": 1 }, { "source": 41, "target": 24, "value": 2 }, { "source": 41, "target": 25, "value": 3 }, { "source": 42, "target": 41, "value": 2 }, { "source": 42, "target": 25, "value": 2 }, { "source": 42, "target": 24, "value": 1 }, { "source": 43, "target": 11, "value": 3 }, { "source": 43, "target": 26, "value": 1 }, { "source": 43, "target": 27, "value": 1 }, { "source": 44, "target": 28, "value": 3 }, { "source": 44, "target": 11, "value": 1 }, { "source": 45, "target": 28, "value": 2 }, { "source": 47, "target": 46, "value": 1 }, { "source": 48, "target": 47, "value": 2 }, { "source": 48, "target": 25, "value": 1 }, { "source": 48, "target": 27, "value": 1 }, { "source": 48, "target": 11, "value": 1 }, { "source": 49, "target": 26, "value": 3 }, { "source": 49, "target": 11, "value": 2 }, { "source": 50, "target": 49, "value": 1 }, { "source": 50, "target": 24, "value": 1 }, { "source": 51, "target": 49, "value": 9 }, { "source": 51, "target": 26, "value": 2 }, { "source": 51, "target": 11, "value": 2 }, { "source": 52, "target": 51, "value": 1 }, { "source": 52, "target": 39, "value": 1 }, { "source": 53, "target": 51, "value": 1 }, { "source": 54, "target": 51, "value": 2 }, { "source": 54, "target": 49, "value": 1 }, { "source": 54, "target": 26, "value": 1 }, { "source": 55, "target": 51, "value": 6 }, { "source": 55, "target": 49, "value": 12 }, { "source": 55, "target": 39, "value": 1 }, { "source": 55, "target": 54, "value": 1 }, { "source": 55, "target": 26, "value": 21 }, { "source": 55, "target": 11, "value": 19 }, { "source": 55, "target": 16, "value": 1 }, { "source": 55, "target": 25, "value": 2 }, { "source": 55, "target": 41, "value": 5 }, { "source": 55, "target": 48, "value": 4 }, { "source": 56, "target": 49, "value": 1 }, { "source": 56, "target": 55, "value": 1 }, { "source": 57, "target": 55, "value": 1 }, { "source": 57, "target": 41, "value": 1 }, { "source": 57, "target": 48, "value": 1 }, { "source": 58, "target": 55, "value": 7 }, { "source": 58, "target": 48, "value": 7 }, { "source": 58, "target": 27, "value": 6 }, { "source": 58, "target": 57, "value": 1 }, { "source": 58, "target": 11, "value": 4 }, { "source": 59, "target": 58, "value": 15 }, { "source": 59, "target": 55, "value": 5 }, { "source": 59, "target": 48, "value": 6 }, { "source": 59, "target": 57, "value": 2 }, { "source": 60, "target": 48, "value": 1 }, { "source": 60, "target": 58, "value": 4 }, { "source": 60, "target": 59, "value": 2 }, { "source": 61, "target": 48, "value": 2 }, { "source": 61, "target": 58, "value": 6 }, { "source": 61, "target": 60, "value": 2 }, { "source": 61, "target": 59, "value": 5 }, { "source": 61, "target": 57, "value": 1 }, { "source": 61, "target": 55, "value": 1 }, { "source": 62, "target": 55, "value": 9 }, { "source": 62, "target": 58, "value": 17 }, { "source": 62, "target": 59, "value": 13 }, { "source": 62, "target": 48, "value": 7 }, { "source": 62, "target": 57, "value": 2 }, { "source": 62, "target": 41, "value": 1 }, { "source": 62, "target": 61, "value": 6 }, { "source": 62, "target": 60, "value": 3 }, { "source": 63, "target": 59, "value": 5 }, { "source": 63, "target": 48, "value": 5 }, { "source": 63, "target": 62, "value": 6 }, { "source": 63, "target": 57, "value": 2 }, { "source": 63, "target": 58, "value": 4 }, { "source": 63, "target": 61, "value": 3 }, { "source": 63, "target": 60, "value": 2 }, { "source": 63, "target": 55, "value": 1 }, { "source": 64, "target": 55, "value": 5 }, { "source": 64, "target": 62, "value": 12 }, { "source": 64, "target": 48, "value": 5 }, { "source": 64, "target": 63, "value": 4 }, { "source": 64, "target": 58, "value": 10 }, { "source": 64, "target": 61, "value": 6 }, { "source": 64, "target": 60, "value": 2 }, { "source": 64, "target": 59, "value": 9 }, { "source": 64, "target": 57, "value": 1 }, { "source": 64, "target": 11, "value": 1 }, { "source": 65, "target": 63, "value": 5 }, { "source": 65, "target": 64, "value": 7 }, { "source": 65, "target": 48, "value": 3 }, { "source": 65, "target": 62, "value": 5 }, { "source": 65, "target": 58, "value": 5 }, { "source": 65, "target": 61, "value": 5 }, { "source": 65, "target": 60, "value": 2 }, { "source": 65, "target": 59, "value": 5 }, { "source": 65, "target": 57, "value": 1 }, { "source": 65, "target": 55, "value": 2 }, { "source": 66, "target": 64, "value": 3 }, { "source": 66, "target": 58, "value": 3 }, { "source": 66, "target": 59, "value": 1 }, { "source": 66, "target": 62, "value": 2 }, { "source": 66, "target": 65, "value": 2 }, { "source": 66, "target": 48, "value": 1 }, { "source": 66, "target": 63, "value": 1 }, { "source": 66, "target": 61, "value": 1 }, { "source": 66, "target": 60, "value": 1 }, { "source": 67, "target": 57, "value": 3 }, { "source": 68, "target": 25, "value": 5 }, { "source": 68, "target": 11, "value": 1 }, { "source": 68, "target": 24, "value": 1 }, { "source": 68, "target": 27, "value": 1 }, { "source": 68, "target": 48, "value": 1 }, { "source": 68, "target": 41, "value": 1 }, { "source": 69, "target": 25, "value": 6 }, { "source": 69, "target": 68, "value": 6 }, { "source": 69, "target": 11, "value": 1 }, { "source": 69, "target": 24, "value": 1 }, { "source": 69, "target": 27, "value": 2 }, { "source": 69, "target": 48, "value": 1 }, { "source": 69, "target": 41, "value": 1 }, { "source": 70, "target": 25, "value": 4 }, { "source": 70, "target": 69, "value": 4 }, { "source": 70, "target": 68, "value": 4 }, { "source": 70, "target": 11, "value": 1 }, { "source": 70, "target": 24, "value": 1 }, { "source": 70, "target": 27, "value": 1 }, { "source": 70, "target": 41, "value": 1 }, { "source": 70, "target": 58, "value": 1 }, { "source": 71, "target": 27, "value": 1 }, { "source": 71, "target": 69, "value": 2 }, { "source": 71, "target": 68, "value": 2 }, { "source": 71, "target": 70, "value": 2 }, { "source": 71, "target": 11, "value": 1 }, { "source": 71, "target": 48, "value": 1 }, { "source": 71, "target": 41, "value": 1 }, { "source": 71, "target": 25, "value": 1 }, { "source": 72, "target": 26, "value": 2 }, { "source": 72, "target": 27, "value": 1 }, { "source": 72, "target": 11, "value": 1 }, { "source": 73, "target": 48, "value": 2 }, { "source": 74, "target": 48, "value": 2 }, { "source": 74, "target": 73, "value": 3 }, { "source": 75, "target": 69, "value": 3 }, { "source": 75, "target": 68, "value": 3 }, { "source": 75, "target": 25, "value": 3 }, { "source": 75, "target": 48, "value": 1 }, { "source": 75, "target": 41, "value": 1 }, { "source": 75, "target": 70, "value": 1 }, { "source": 75, "target": 71, "value": 1 }, { "source": 76, "target": 64, "value": 1 }, { "source": 76, "target": 65, "value": 1 }, { "source": 76, "target": 66, "value": 1 }, { "source": 76, "target": 63, "value": 1 }, { "source": 76, "target": 62, "value": 1 }, { "source": 76, "target": 48, "value": 1 }, { "source": 76, "target": 58, "value": 1 }] }
</script>

You can tamper the dx and dy to move it to the center something like this.
node.append("text")
.attr("dx", function(d) { if(d.group > 9) {return -5.5} else {return -1.5;} })
.attr("dy", ".3em")
.text(function(d) { return d.group });
What this does is if the group is 9 then single digit then return -1.5 else for 2 digit return -5.5.
Working code here
Hope this helps!

It works after changing the position of dx;
node.append("text")
.attr("dx", -2)
.attr("dy", ".35em")
.text(function(d) { return d.group });
Here is the updated fiddle.

Related

Download a PNG from URL LookIntoBitcoin

There is a page with URL:
https://www.lookintobitcoin.com/charts/1-year-hodl-wave/
I'm designing a page and I just want to reference the "image" of this URL.
It has a download PNG file, how can i just get the path/url to this png image file?
Here is the image icon, but i cant figure out how to get the url path to just the png file.
Can anyone show me how to get it?
This image is dynamically generated at client side (browser), so here is two ways to solve your problem:
Use Selenium or PhantomJS (both using headless browser technology) to emulate browser behaviour and automatically "press" download button at background.
Fetch JSON data and create graph by yourself (for example how to create PNG image based on txt file in python)
I recommend second way because it more flexible and you will be able to widely customize result image. But it may be more complicated than headless browser way.
If you want to use second way, you can fetch JSON data using python (for example):
import requests
import json
url = 'https://www.lookintobitcoin.com/django_plotly_dash/app/hodl_wave/_dash-update-component'
request_data = {
"output":"chart.figure",
"changedPropIds":["url.pathname"],
"inputs":[
{
"id":"url",
"property":"pathname",
"value":"/charts/1-year-hodl-wave/"
}
]
}
response = requests.post(url, json=request_data)
print(json.dumps(response.json(), indent=2))
And output will be:
{
"response": {
"props": {
"figure": {
"data": [
{
"line": {
"color": "#003366",
"width": 1.2
},
"name": "BTC Price",
"x": [
"2010-08-17",
"2020-09-13",
"2020-09-14",
...
"2021-09-07",
"2021-09-08"
],
"y": [
0.07,
0.07,
...
46215.0
],
"yaxis": "y2",
"type": "scatter"
},
{
"connectgaps": true,
"line": {
"color": "#ffa500",
"width": 0.8
},
"name": "1Yr+ HODL Wave",
"x": [
"2010-08-17",
...
"2021-12-16T00:00:00",
"2021-12-17T00:00:00"
],
"y": [
0.28032062150000003,
0.2807032645,
...
0.5101534705064048,
0.5090896880670537
],
"yaxis": "y",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(255, 207, 209, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Peak",
"showlegend": true,
"x": [
"2011-06-13"
],
"y": [
20.11
],
"yaxis": "y2",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(255, 207, 209, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Peak",
"showlegend": false,
"x": [
"2011-06-13"
],
"y": [
0.2979442568
],
"yaxis": "y",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(255, 207, 209, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Peak",
"showlegend": false,
"x": [
"2013-12-02"
],
"y": [
1047.9
],
"yaxis": "y2",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(255, 207, 209, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Peak",
"showlegend": false,
"x": [
"2013-12-02"
],
"y": [
0.3877138953
],
"yaxis": "y",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(255, 207, 209, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Peak",
"showlegend": false,
"x": [
"2017-12-20"
],
"y": [
16811.3
],
"yaxis": "y2",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(255, 207, 209, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Peak",
"showlegend": false,
"x": [
"2017-12-20"
],
"y": [
0.43133634880000005
],
"yaxis": "y",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(211, 245, 231, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Bottom",
"showlegend": false,
"x": [
"2011-11-22"
],
"y": [
2.31
],
"yaxis": "y2",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(211, 245, 231, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Bottom",
"showlegend": false,
"x": [
"2011-11-22"
],
"y": [
0.3073864328
],
"yaxis": "y",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(211, 245, 231, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Bottom",
"showlegend": false,
"x": [
"2015-01-17"
],
"y": [
201.75
],
"yaxis": "y2",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(211, 245, 231, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Bottom",
"showlegend": false,
"x": [
"2015-01-17"
],
"y": [
0.5363931366
],
"yaxis": "y",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(211, 245, 231, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Bottom",
"showlegend": true,
"x": [
"2018-12-20"
],
"y": [
3983.01
],
"yaxis": "y2",
"type": "scatter"
},
{
"hoverinfo": "skip",
"marker": {
"color": "rgba(211, 245, 231, 0.75)",
"size": 15
},
"mode": "markers",
"name": "Price Bottom",
"showlegend": false,
"x": [
"2018-12-20"
],
"y": [
0.5097358173
],
"yaxis": "y",
"type": "scatter"
}
],
"layout": {
"hovermode": "closest",
"images": [
{
"layer": "below",
"opacity": 0.1,
"sizex": 0.4,
"sizey": 0.4,
"source": "https://www.lookintobitcoin.com/static/img/logo/logo-stacked.png",
"x": 0.4,
"xref": "paper",
"y": 0.75,
"yref": "paper"
}
],
"legend": {
"font": {
"color": "#696969"
},
"orientation": "h",
"x": 0.1
},
"margin": {
"t": 10
},
"uirevision": "False",
"xaxis": {
"color": "#696969",
"gridcolor": "#d3d3d3",
"hoverformat": "%d-%b-%y",
"range": [
"2010-08-17",
"2021-12-17T00:00:00"
],
"showline": true,
"showspikes": true,
"spikecolor": "#696969",
"spikedash": "solid",
"spikemode": "toaxis+across",
"spikethickness": 1
},
"yaxis": {
"color": "#696969",
"hoverformat": "%",
"range": [
0,
1
],
"showgrid": false,
"showspikes": true,
...
"spikethickness": 1,
"tickformat": "%",
"title": {
"text": "1Yr+ HODL Wave"
}
},
"yaxis2": {
"color": "#696969",
"dtick": 1,
...
"spikethickness": 1,
"ticktext": [
"$0.001",
...
"$10,000",
"$100,000"
],
"tickvals": [
0.001,
...
100000
],
"title": {
"text": "BTC Price (USD)"
},
"type": "log",
"zeroline": true
}
}
}
}
}
}

Understanding why strings break this 3d.js force.graph code

I am running this code in a jupyter notebook. First, I create this HTML element:
%%html
<div id="d3-example"></div>
<style>
.node {stroke: #fff; stroke-width: 1.5px;}
.link {stroke: #999; stroke-opacity: .6;}
</style>
Then I run this javascript:
%%javascript
// We load the d3.js library from the Web.
require.config({paths:
{d3: "http://d3js.org/d3.v3.min"}});
require(["d3"], function(d3) {
// The code in this block is executed when the
// d3.js library has been loaded.
// First, we specify the size of the canvas
// containing the visualization (size of the
// <div> element).
var width = 300, height = 300;
// We create a color scale.
var color = d3.scale.category10();
// We create a force-directed dynamic graph layout.
var force = d3.layout.force()
.charge(-120)
.linkDistance(1)
.size([width, height]);
// In the <div> element, we create a <svg> graphic
// that will contain our interactive visualization.
var svg = d3.select("#d3-example").select("svg")
if (svg.empty()) {
svg = d3.select("#d3-example").append("svg")
.attr("width", width)
.attr("height", height);
}
// We load the JSON file.
d3.json("graph2.json", function(error, graph) {
if (error) throw error;
// In this block, the file has been loaded
// and the 'graph' object contains our graph.
// We load the nodes and links in the
// force-directed graph.
force.nodes(graph.nodes)
.links(graph.links)
.start();
// We create a <line> SVG element for each link
// in the graph.
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link");
// We create a <circle> SVG element for each node
// in the graph, and we specify a few attributes.
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5) // radius
.style("fill", function(d) {
// The node color depends on the club.
return color(d.club);
})
.call(force.drag);
// The name of each node is the node number.
node.append("title")
.text(function(d) { return d.name; });
// We bind the positions of the SVG elements
// to the positions of the dynamic force-directed
// graph, at each time step.
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("cx", function(d){return d.x})
.attr("cy", function(d){return d.y});
});
});
});
And this is the content of the json file:
{
"nodes": [
{
"name": 0,
"club": "Mr. Hi"
},
{
"name": 1,
"club": "Mr. Hi"
},
{
"name": 2,
"club": "Mr. Hi"
},
{
"name": 3,
"club": "Mr. Hi"
},
{
"name": 4,
"club": "Mr. Hi"
},
{
"name": 5,
"club": "Mr. Hi"
},
{
"name": 6,
"club": "Mr. Hi"
},
{
"name": 7,
"club": "Mr. Hi"
},
{
"name": 8,
"club": "Mr. Hi"
},
{
"name": 9,
"club": "Officer"
},
{
"name": 10,
"club": "Mr. Hi"
},
{
"name": "11",
"club": "Mr. Hi"
},
{
"name": "12",
"club": "Mr. Hi"
},
{
"name": "13",
"club": "Mr. Hi"
},
{
"name": "14",
"club": "Officer"
},
{
"name": "15",
"club": "Officer"
},
{
"name": "16",
"club": "Mr. Hi"
},
{
"name": "17",
"club": "Mr. Hi"
},
{
"name": "18",
"club": "Officer"
},
{
"name": "19",
"club": "Mr. Hi"
},
{
"name": "20",
"club": "Officer"
},
{
"name": "21",
"club": "Mr. Hi"
},
{
"name": "22",
"club": "Officer"
},
{
"name": "23",
"club": "Officer"
},
{
"name": "24",
"club": "Officer"
},
{
"name": "25",
"club": "Officer"
},
{
"name": "26",
"club": "Officer"
},
{
"name": "27",
"club": "Officer"
},
{
"name": "28",
"club": "Officer"
},
{
"name": "29",
"club": "Officer"
},
{
"name": "30",
"club": "Officer"
},
{
"name": "31",
"club": "Officer"
},
{
"name": "32",
"club": "Officer"
},
{
"name": "33",
"club": "Officer"
}
],
"links": [
{
"source": 0,
"target": 1
},
{
"source": 0,
"target": 2
},
{
"source": 0,
"target": 3
},
{
"source": 0,
"target": 4
},
{
"source": 0,
"target": 5
},
{
"source": 0,
"target": 6
},
{
"source": 0,
"target": 7
},
{
"source": 0,
"target": 8
},
{
"source": 0,
"target": 10
},
{
"source": 0,
"target": 11
},
{
"source": 0,
"target": 12
},
{
"source": 0,
"target": 13
},
{
"source": 0,
"target": 17
},
{
"source": 0,
"target": 19
},
{
"source": 0,
"target": 21
},
{
"source": 0,
"target": 31
},
{
"source": 1,
"target": 2
},
{
"source": 1,
"target": 3
},
{
"source": 1,
"target": 7
},
{
"source": 1,
"target": 13
},
{
"source": 1,
"target": 17
},
{
"source": 1,
"target": 19
},
{
"source": 1,
"target": 21
},
{
"source": 1,
"target": 30
},
{
"source": 2,
"target": 3
},
{
"source": 2,
"target": 7
},
{
"source": 2,
"target": 8
},
{
"source": 2,
"target": 9
},
{
"source": 2,
"target": 13
},
{
"source": 2,
"target": 27
},
{
"source": 2,
"target": 28
},
{
"source": 2,
"target": 32
},
{
"source": 3,
"target": 7
},
{
"source": 3,
"target": 12
},
{
"source": 3,
"target": 13
},
{
"source": 4,
"target": 6
},
{
"source": 4,
"target": 10
},
{
"source": 5,
"target": 6
},
{
"source": 5,
"target": 10
},
{
"source": 5,
"target": 16
},
{
"source": 6,
"target": 16
},
{
"source": 8,
"target": 30
},
{
"source": 8,
"target": 32
},
{
"source": 8,
"target": 33
},
{
"source": 9,
"target": 33
},
{
"source": 13,
"target": 33
},
{
"source": 14,
"target": 32
},
{
"source": 14,
"target": 33
},
{
"source": 15,
"target": 32
},
{
"source": 15,
"target": 33
},
{
"source": 18,
"target": 32
},
{
"source": 18,
"target": 33
},
{
"source": 19,
"target": 33
},
{
"source": 20,
"target": 32
},
{
"source": 20,
"target": 33
},
{
"source": 22,
"target": 32
},
{
"source": 22,
"target": 33
},
{
"source": 23,
"target": 25
},
{
"source": 23,
"target": 27
},
{
"source": 23,
"target": 29
},
{
"source": 23,
"target": 32
},
{
"source": 23,
"target": 33
},
{
"source": 24,
"target": 25
},
{
"source": 24,
"target": 27
},
{
"source": 24,
"target": 31
},
{
"source": 25,
"target": 31
},
{
"source": 26,
"target": 29
},
{
"source": 26,
"target": 33
},
{
"source": 27,
"target": 33
},
{
"source": 28,
"target": 31
},
{
"source": 28,
"target": 33
},
{
"source": 29,
"target": 32
},
{
"source": 29,
"target": 33
},
{
"source": 30,
"target": 32
},
{
"source": 30,
"target": 33
},
{
"source": 31,
"target": 32
},
{
"source": 31,
"target": 33
},
{
"source": 32,
"target": 33
}
]
}
​I want to customize the code and use it to visualize a different file. But I don't fully understand the code. I changed the values in the links section to strings. And that breaks the code. I want to use strings for my other graph. But I don't see how the javascript code depends on integers. For some reason, it breaks and no graph is displayed.

LUIS consider TIME and DURATION as number ENTITY

I was expecting entities such DATE, TIME, DURATION & No Of People Joining the Call in below JSON.
Now i got entities back such as DATE,TIME and DURATION correctly but for No Of People there is problem for me.
I am getting four entities as NUMBER so now i am confused as how to pick exact entity that represent No Of People. Ideally it is No. 6, but i am not getting on which basis i should decide that 6 is the No Of People
{
"query": "book audio bridge tomorrow for 6 people for 30 mins starts at 5:30 PM",
"topScoringIntent": {
"intent": "BookAudioBridge",
"score": 0.9895838
},
"intents": [
{
"intent": "BookAudioBridge",
"score": 0.9895838
},
{
"intent": "ListBooking",
"score": 0.00677821552
}
],
"entities": [
{
"entity": "tomorrow",
"type": "builtin.datetimeV2.date",
"startIndex": 18,
"endIndex": 25,
"resolution": {
"values": [
{
"timex": "2018-06-21",
"type": "date",
"value": "2018-06-21"
}
]
}
},
{
"entity": "30 mins",
"type": "builtin.datetimeV2.duration",
"startIndex": 44,
"endIndex": 50,
"resolution": {
"values": [
{
"timex": "PT30M",
"type": "duration",
"value": "1800"
}
]
}
},
{
"entity": "5:30 pm",
"type": "builtin.datetimeV2.time",
"startIndex": 62,
"endIndex": 68,
"resolution": {
"values": [
{
"timex": "T17:30",
"type": "time",
"value": "17:30:00"
}
]
}
},
{
"entity": "6",
"type": "builtin.number",
"startIndex": 31,
"endIndex": 31,
"resolution": {
"value": "6"
}
},
{
"entity": "30",
"type": "builtin.number",
"startIndex": 44,
"endIndex": 45,
"resolution": {
"value": "30"
}
},
{
"entity": "5",
"type": "builtin.number",
"startIndex": 62,
"endIndex": 62,
"resolution": {
"value": "5"
}
},
{
"entity": "30",
"type": "builtin.number",
"startIndex": 64,
"endIndex": 65,
"resolution": {
"value": "30"
}
}
]
}
You could build a composite entity of number and simple entity for "people" so that the entity that comes back indicates 6 as number and simple entity name as people.

D3.js labeled force graph does not reload data

I am trying to create a force graph in d3.js with some labels on top of each node and also some content-dependent style (for instance, the colour of the node is dependent on a 'type' property). I am starting with one of the examples but I cannot make the graph to display new data when I update it. For instance, when changing the text property on the list of data, the label on the node should change, however it does not. I think the problem might be in the data()/enter() procedure, which I am still trying to fully understand. What I have so far managed to get is the following: https://jsfiddle.net/5Luv0btd/2/ . Any help would be much appreciated!
That is because once you've entered the data, you do not have to operate on the nodeEnter anymore. The reason is simple: .enter() merges into the update selection when you append or insert.. In other words, after chaining .enter(), node effectively refers to both the old and new data. Citing the example for the v3.x documentation for d3:
var update_sel = svg.selectAll("circle").data(data)
update_sel.attr(/* operate on old elements only */)
update_sel.enter().append("circle").attr(/* operate on new elements only */)
update_sel.attr(/* operate on old and new elements */)
update_sel.exit().remove() /* complete the enter-update-exit pattern */
Therefore, working with node itself will suffice, i.e.:
// Enter selection
node.enter().append("g")
.attr("class", "node")
.call(drag);
// From this point onwards:
// `node` will refer to both old and new data
// Do magic ;)
node.append("circle")
.attr("r", 10)
.style('fill', function(d) {
return color(d.type)
})
.attr("width", 16)
.attr("height", 16);
node.append("text")
.attr("dx", 0)
.attr("dy", ".35em")
.text(function(d) {
return d.name
})
.attr("text-anchor", "middle");
See working fiddle here: https://jsfiddle.net/teddyrised/5Luv0btd/5/, or refer to the code snippet below:
var data = {
"nodes": [{
"name": "Myriel",
"type": 1
}, {
"name": "Napoleon",
"type": 1
}, {
"name": "Mlle.Baptistine",
"type": 1
}, {
"name": "Mme.Magloire",
"type": 1
}, {
"name": "CountessdeLo",
"type": 1
}, {
"name": "Geborand",
"type": 1
}, {
"name": "Champtercier",
"type": 1
}, {
"name": "Cravatte",
"type": 1
}, {
"name": "Count",
"type": 1
}, {
"name": "OldMan",
"type": 1
}, {
"name": "Labarre",
"type": 2
}, {
"name": "Valjean",
"type": 2
}, {
"name": "Marguerite",
"type": 3
}, {
"name": "Mme.deR",
"type": 2
}, {
"name": "Isabeau",
"type": 2
}, {
"name": "Gervais",
"type": 2
}, {
"name": "Tholomyes",
"type": 3
}, {
"name": "Listolier",
"type": 3
}, {
"name": "Fameuil",
"type": 3
}, {
"name": "Blacheville",
"type": 3
}, {
"name": "Favourite",
"type": 3
}, {
"name": "Dahlia",
"type": 3
}, {
"name": "Zephine",
"type": 3
}, {
"name": "Fantine",
"type": 3
}, {
"name": "Mme.Thenardier",
"type": 4
}, {
"name": "Thenardier",
"type": 4
}, {
"name": "Cosette",
"type": 5
}, {
"name": "Javert",
"type": 4
}, {
"name": "Fauchelevent",
"type": 0
}, {
"name": "Bamatabois",
"type": 2
}, {
"name": "Perpetue",
"type": 3
}, {
"name": "Simplice",
"type": 2
}, {
"name": "Scaufflaire",
"type": 2
}, {
"name": "Woman1",
"type": 2
}, {
"name": "Judge",
"type": 2
}, {
"name": "Champmathieu",
"type": 2
}, {
"name": "Brevet",
"type": 2
}, {
"name": "Chenildieu",
"type": 2
}, {
"name": "Cochepaille",
"type": 2
}, {
"name": "Pontmercy",
"type": 4
}, {
"name": "Boulatruelle",
"type": 6
}, {
"name": "Eponine",
"type": 4
}, {
"name": "Anzelma",
"type": 4
}, {
"name": "Woman2",
"type": 5
}, {
"name": "MotherInnocent",
"type": 0
}, {
"name": "Gribier",
"type": 0
}, {
"name": "Jondrette",
"type": 7
}, {
"name": "Mme.Burgon",
"type": 7
}, {
"name": "Gavroche",
"type": 8
}, {
"name": "Gillenormand",
"type": 5
}, {
"name": "Magnon",
"type": 5
}, {
"name": "Mlle.Gillenormand",
"type": 5
}, {
"name": "Mme.Pontmercy",
"type": 5
}, {
"name": "Mlle.Vaubois",
"type": 5
}, {
"name": "Lt.Gillenormand",
"type": 5
}, {
"name": "Marius",
"type": 8
}, {
"name": "BaronessT",
"type": 5
}, {
"name": "Mabeuf",
"type": 8
}, {
"name": "Enjolras",
"type": 8
}, {
"name": "Combeferre",
"type": 8
}, {
"name": "Prouvaire",
"type": 8
}, {
"name": "Feuilly",
"type": 8
}, {
"name": "Courfeyrac",
"type": 8
}, {
"name": "Bahorel",
"type": 8
}, {
"name": "Bossuet",
"type": 8
}, {
"name": "Joly",
"type": 8
}, {
"name": "Grantaire",
"type": 8
}, {
"name": "MotherPlutarch",
"type": 9
}, {
"name": "Gueulemer",
"type": 4
}, {
"name": "Babet",
"type": 4
}, {
"name": "Claquesous",
"type": 4
}, {
"name": "Montparnasse",
"type": 4
}, {
"name": "Toussaint",
"type": 5
}, {
"name": "Child1",
"type": 10
}, {
"name": "Child2",
"type": 10
}, {
"name": "Brujon",
"type": 4
}, {
"name": "Mme.Hucheloup",
"type": 8
}],
"links": [{
"source": 1,
"target": 0,
"value": 1
}, {
"source": 2,
"target": 0,
"value": 8
}, {
"source": 3,
"target": 0,
"value": 10
}, {
"source": 3,
"target": 2,
"value": 6
}, {
"source": 4,
"target": 0,
"value": 1
}, {
"source": 5,
"target": 0,
"value": 1
}, {
"source": 6,
"target": 0,
"value": 1
}, {
"source": 7,
"target": 0,
"value": 1
}, {
"source": 8,
"target": 0,
"value": 2
}, {
"source": 9,
"target": 0,
"value": 1
}, {
"source": 11,
"target": 10,
"value": 1
}, {
"source": 11,
"target": 3,
"value": 3
}, {
"source": 11,
"target": 2,
"value": 3
}, {
"source": 11,
"target": 0,
"value": 5
}, {
"source": 12,
"target": 11,
"value": 1
}, {
"source": 13,
"target": 11,
"value": 1
}, {
"source": 14,
"target": 11,
"value": 1
}, {
"source": 15,
"target": 11,
"value": 1
}, {
"source": 17,
"target": 16,
"value": 4
}, {
"source": 18,
"target": 16,
"value": 4
}, {
"source": 18,
"target": 17,
"value": 4
}, {
"source": 19,
"target": 16,
"value": 4
}, {
"source": 19,
"target": 17,
"value": 4
}, {
"source": 19,
"target": 18,
"value": 4
}, {
"source": 20,
"target": 16,
"value": 3
}, {
"source": 20,
"target": 17,
"value": 3
}, {
"source": 20,
"target": 18,
"value": 3
}, {
"source": 20,
"target": 19,
"value": 4
}, {
"source": 21,
"target": 16,
"value": 3
}, {
"source": 21,
"target": 17,
"value": 3
}, {
"source": 21,
"target": 18,
"value": 3
}, {
"source": 21,
"target": 19,
"value": 3
}, {
"source": 21,
"target": 20,
"value": 5
}, {
"source": 22,
"target": 16,
"value": 3
}, {
"source": 22,
"target": 17,
"value": 3
}, {
"source": 22,
"target": 18,
"value": 3
}, {
"source": 22,
"target": 19,
"value": 3
}, {
"source": 22,
"target": 20,
"value": 4
}, {
"source": 22,
"target": 21,
"value": 4
}, {
"source": 23,
"target": 16,
"value": 3
}, {
"source": 23,
"target": 17,
"value": 3
}, {
"source": 23,
"target": 18,
"value": 3
}, {
"source": 23,
"target": 19,
"value": 3
}, {
"source": 23,
"target": 20,
"value": 4
}, {
"source": 23,
"target": 21,
"value": 4
}, {
"source": 23,
"target": 22,
"value": 4
}, {
"source": 23,
"target": 12,
"value": 2
}, {
"source": 23,
"target": 11,
"value": 9
}, {
"source": 24,
"target": 23,
"value": 2
}, {
"source": 24,
"target": 11,
"value": 7
}, {
"source": 25,
"target": 24,
"value": 13
}, {
"source": 25,
"target": 23,
"value": 1
}, {
"source": 25,
"target": 11,
"value": 12
}, {
"source": 26,
"target": 24,
"value": 4
}, {
"source": 26,
"target": 11,
"value": 31
}, {
"source": 26,
"target": 16,
"value": 1
}, {
"source": 26,
"target": 25,
"value": 1
}, {
"source": 27,
"target": 11,
"value": 17
}, {
"source": 27,
"target": 23,
"value": 5
}, {
"source": 27,
"target": 25,
"value": 5
}, {
"source": 27,
"target": 24,
"value": 1
}, {
"source": 27,
"target": 26,
"value": 1
}, {
"source": 28,
"target": 11,
"value": 8
}, {
"source": 28,
"target": 27,
"value": 1
}, {
"source": 29,
"target": 23,
"value": 1
}, {
"source": 29,
"target": 27,
"value": 1
}, {
"source": 29,
"target": 11,
"value": 2
}, {
"source": 30,
"target": 23,
"value": 1
}, {
"source": 31,
"target": 30,
"value": 2
}, {
"source": 31,
"target": 11,
"value": 3
}, {
"source": 31,
"target": 23,
"value": 2
}, {
"source": 31,
"target": 27,
"value": 1
}, {
"source": 32,
"target": 11,
"value": 1
}, {
"source": 33,
"target": 11,
"value": 2
}, {
"source": 33,
"target": 27,
"value": 1
}, {
"source": 34,
"target": 11,
"value": 3
}, {
"source": 34,
"target": 29,
"value": 2
}, {
"source": 35,
"target": 11,
"value": 3
}, {
"source": 35,
"target": 34,
"value": 3
}, {
"source": 35,
"target": 29,
"value": 2
}, {
"source": 36,
"target": 34,
"value": 2
}, {
"source": 36,
"target": 35,
"value": 2
}, {
"source": 36,
"target": 11,
"value": 2
}, {
"source": 36,
"target": 29,
"value": 1
}, {
"source": 37,
"target": 34,
"value": 2
}, {
"source": 37,
"target": 35,
"value": 2
}, {
"source": 37,
"target": 36,
"value": 2
}, {
"source": 37,
"target": 11,
"value": 2
}, {
"source": 37,
"target": 29,
"value": 1
}, {
"source": 38,
"target": 34,
"value": 2
}, {
"source": 38,
"target": 35,
"value": 2
}, {
"source": 38,
"target": 36,
"value": 2
}, {
"source": 38,
"target": 37,
"value": 2
}, {
"source": 38,
"target": 11,
"value": 2
}, {
"source": 38,
"target": 29,
"value": 1
}, {
"source": 39,
"target": 25,
"value": 1
}, {
"source": 40,
"target": 25,
"value": 1
}, {
"source": 41,
"target": 24,
"value": 2
}, {
"source": 41,
"target": 25,
"value": 3
}, {
"source": 42,
"target": 41,
"value": 2
}, {
"source": 42,
"target": 25,
"value": 2
}, {
"source": 42,
"target": 24,
"value": 1
}, {
"source": 43,
"target": 11,
"value": 3
}, {
"source": 43,
"target": 26,
"value": 1
}, {
"source": 43,
"target": 27,
"value": 1
}, {
"source": 44,
"target": 28,
"value": 3
}, {
"source": 44,
"target": 11,
"value": 1
}, {
"source": 45,
"target": 28,
"value": 2
}, {
"source": 47,
"target": 46,
"value": 1
}, {
"source": 48,
"target": 47,
"value": 2
}, {
"source": 48,
"target": 25,
"value": 1
}, {
"source": 48,
"target": 27,
"value": 1
}, {
"source": 48,
"target": 11,
"value": 1
}, {
"source": 49,
"target": 26,
"value": 3
}, {
"source": 49,
"target": 11,
"value": 2
}, {
"source": 50,
"target": 49,
"value": 1
}, {
"source": 50,
"target": 24,
"value": 1
}, {
"source": 51,
"target": 49,
"value": 9
}, {
"source": 51,
"target": 26,
"value": 2
}, {
"source": 51,
"target": 11,
"value": 2
}, {
"source": 52,
"target": 51,
"value": 1
}, {
"source": 52,
"target": 39,
"value": 1
}, {
"source": 53,
"target": 51,
"value": 1
}, {
"source": 54,
"target": 51,
"value": 2
}, {
"source": 54,
"target": 49,
"value": 1
}, {
"source": 54,
"target": 26,
"value": 1
}, {
"source": 55,
"target": 51,
"value": 6
}, {
"source": 55,
"target": 49,
"value": 12
}, {
"source": 55,
"target": 39,
"value": 1
}, {
"source": 55,
"target": 54,
"value": 1
}, {
"source": 55,
"target": 26,
"value": 21
}, {
"source": 55,
"target": 11,
"value": 19
}, {
"source": 55,
"target": 16,
"value": 1
}, {
"source": 55,
"target": 25,
"value": 2
}, {
"source": 55,
"target": 41,
"value": 5
}, {
"source": 55,
"target": 48,
"value": 4
}, {
"source": 56,
"target": 49,
"value": 1
}, {
"source": 56,
"target": 55,
"value": 1
}, {
"source": 57,
"target": 55,
"value": 1
}, {
"source": 57,
"target": 41,
"value": 1
}, {
"source": 57,
"target": 48,
"value": 1
}, {
"source": 58,
"target": 55,
"value": 7
}, {
"source": 58,
"target": 48,
"value": 7
}, {
"source": 58,
"target": 27,
"value": 6
}, {
"source": 58,
"target": 57,
"value": 1
}, {
"source": 58,
"target": 11,
"value": 4
}, {
"source": 59,
"target": 58,
"value": 15
}, {
"source": 59,
"target": 55,
"value": 5
}, {
"source": 59,
"target": 48,
"value": 6
}, {
"source": 59,
"target": 57,
"value": 2
}, {
"source": 60,
"target": 48,
"value": 1
}, {
"source": 60,
"target": 58,
"value": 4
}, {
"source": 60,
"target": 59,
"value": 2
}, {
"source": 61,
"target": 48,
"value": 2
}, {
"source": 61,
"target": 58,
"value": 6
}, {
"source": 61,
"target": 60,
"value": 2
}, {
"source": 61,
"target": 59,
"value": 5
}, {
"source": 61,
"target": 57,
"value": 1
}, {
"source": 61,
"target": 55,
"value": 1
}, {
"source": 62,
"target": 55,
"value": 9
}, {
"source": 62,
"target": 58,
"value": 17
}, {
"source": 62,
"target": 59,
"value": 13
}, {
"source": 62,
"target": 48,
"value": 7
}, {
"source": 62,
"target": 57,
"value": 2
}, {
"source": 62,
"target": 41,
"value": 1
}, {
"source": 62,
"target": 61,
"value": 6
}, {
"source": 62,
"target": 60,
"value": 3
}, {
"source": 63,
"target": 59,
"value": 5
}, {
"source": 63,
"target": 48,
"value": 5
}, {
"source": 63,
"target": 62,
"value": 6
}, {
"source": 63,
"target": 57,
"value": 2
}, {
"source": 63,
"target": 58,
"value": 4
}, {
"source": 63,
"target": 61,
"value": 3
}, {
"source": 63,
"target": 60,
"value": 2
}, {
"source": 63,
"target": 55,
"value": 1
}, {
"source": 64,
"target": 55,
"value": 5
}, {
"source": 64,
"target": 62,
"value": 12
}, {
"source": 64,
"target": 48,
"value": 5
}, {
"source": 64,
"target": 63,
"value": 4
}, {
"source": 64,
"target": 58,
"value": 10
}, {
"source": 64,
"target": 61,
"value": 6
}, {
"source": 64,
"target": 60,
"value": 2
}, {
"source": 64,
"target": 59,
"value": 9
}, {
"source": 64,
"target": 57,
"value": 1
}, {
"source": 64,
"target": 11,
"value": 1
}, {
"source": 65,
"target": 63,
"value": 5
}, {
"source": 65,
"target": 64,
"value": 7
}, {
"source": 65,
"target": 48,
"value": 3
}, {
"source": 65,
"target": 62,
"value": 5
}, {
"source": 65,
"target": 58,
"value": 5
}, {
"source": 65,
"target": 61,
"value": 5
}, {
"source": 65,
"target": 60,
"value": 2
}, {
"source": 65,
"target": 59,
"value": 5
}, {
"source": 65,
"target": 57,
"value": 1
}, {
"source": 65,
"target": 55,
"value": 2
}, {
"source": 66,
"target": 64,
"value": 3
}, {
"source": 66,
"target": 58,
"value": 3
}, {
"source": 66,
"target": 59,
"value": 1
}, {
"source": 66,
"target": 62,
"value": 2
}, {
"source": 66,
"target": 65,
"value": 2
}, {
"source": 66,
"target": 48,
"value": 1
}, {
"source": 66,
"target": 63,
"value": 1
}, {
"source": 66,
"target": 61,
"value": 1
}, {
"source": 66,
"target": 60,
"value": 1
}, {
"source": 67,
"target": 57,
"value": 3
}, {
"source": 68,
"target": 25,
"value": 5
}, {
"source": 68,
"target": 11,
"value": 1
}, {
"source": 68,
"target": 24,
"value": 1
}, {
"source": 68,
"target": 27,
"value": 1
}, {
"source": 68,
"target": 48,
"value": 1
}, {
"source": 68,
"target": 41,
"value": 1
}, {
"source": 69,
"target": 25,
"value": 6
}, {
"source": 69,
"target": 68,
"value": 6
}, {
"source": 69,
"target": 11,
"value": 1
}, {
"source": 69,
"target": 24,
"value": 1
}, {
"source": 69,
"target": 27,
"value": 2
}, {
"source": 69,
"target": 48,
"value": 1
}, {
"source": 69,
"target": 41,
"value": 1
}, {
"source": 70,
"target": 25,
"value": 4
}, {
"source": 70,
"target": 69,
"value": 4
}, {
"source": 70,
"target": 68,
"value": 4
}, {
"source": 70,
"target": 11,
"value": 1
}, {
"source": 70,
"target": 24,
"value": 1
}, {
"source": 70,
"target": 27,
"value": 1
}, {
"source": 70,
"target": 41,
"value": 1
}, {
"source": 70,
"target": 58,
"value": 1
}, {
"source": 71,
"target": 27,
"value": 1
}, {
"source": 71,
"target": 69,
"value": 2
}, {
"source": 71,
"target": 68,
"value": 2
}, {
"source": 71,
"target": 70,
"value": 2
}, {
"source": 71,
"target": 11,
"value": 1
}, {
"source": 71,
"target": 48,
"value": 1
}, {
"source": 71,
"target": 41,
"value": 1
}, {
"source": 71,
"target": 25,
"value": 1
}, {
"source": 72,
"target": 26,
"value": 2
}, {
"source": 72,
"target": 27,
"value": 1
}, {
"source": 72,
"target": 11,
"value": 1
}, {
"source": 73,
"target": 48,
"value": 2
}, {
"source": 74,
"target": 48,
"value": 2
}, {
"source": 74,
"target": 73,
"value": 3
}, {
"source": 75,
"target": 69,
"value": 3
}, {
"source": 75,
"target": 68,
"value": 3
}, {
"source": 75,
"target": 25,
"value": 3
}, {
"source": 75,
"target": 48,
"value": 1
}, {
"source": 75,
"target": 41,
"value": 1
}, {
"source": 75,
"target": 70,
"value": 1
}, {
"source": 75,
"target": 71,
"value": 1
}, {
"source": 76,
"target": 64,
"value": 1
}, {
"source": 76,
"target": 65,
"value": 1
}, {
"source": 76,
"target": 66,
"value": 1
}, {
"source": 76,
"target": 63,
"value": 1
}, {
"source": 76,
"target": 62,
"value": 1
}, {
"source": 76,
"target": 48,
"value": 1
}, {
"source": 76,
"target": 58,
"value": 1
}]
};
var width = 960,
height = 500,
color = d3.scale.category20();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var force = d3.layout.force()
.gravity(0.05)
.distance(100)
.charge(-100)
.size([width, height]);
var draw = function(data) {
force
.nodes(data.nodes)
.links(data.links)
.start();
var drag = d3.behavior.drag().origin(function(d) {
return d;
});
var link = svg.selectAll(".link")
.data(data.links);
var linkEnter = link.enter().append("line")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(data.nodes, function(d) {
return d.name
});
node.enter().append("g")
.attr("class", "node")
.call(drag);
node.append("circle")
.attr("r", 10)
.style('fill', function(d) {
return color(d.type)
})
.attr("width", 16)
.attr("height", 16);
node.append("text")
.attr("dx", 0)
.attr("dy", ".35em")
.text(function(d) {
return d.name
})
.attr("text-anchor", "middle");
link.exit().remove();
node.exit().remove();
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) {
return "translate(" + d.x + "," + d.y + ")";
});
});
}
draw(data);
setTimeout(function(d) {
data.nodes[0].name = "A changed name";
data.nodes[0].type = 2;
// The node 'Myriel' should now have the labed 'A changed name'
draw(data)
}, 2000);
.link {
stroke: #ccc;
}
.node text {
pointer-events: none;
font: 10px sans-serif;
}
<script src="//d3js.org/d3.v3.min.js"></script>

Forced directed D3 Graph setting specific image for each node

Hi I have gone through few questions and possible solutions of putting image as node in forced directed. But all of them are either putting randomly or one image for all. Is there any way i can assign particular image to particular node? Basically i am creating dynamically and fetching data from database. Any help would be highly appreciated.
hi just click the load button and heres the sample of what you want http://jsfiddle.net/elviz/V6Qr8/91/
function loadImage() {
if (LoadData) {
root = {
"name": "physics",
"imageURL": "",
"type": "user",
"children": [{
"name": "DragForce",
"imageURL": "",
"size": 1082,
"type": "user"
}, {
"name": "GravityForce",
"imageURL": "",
"size": 1336,
"type": "user"
}, {
"name": "IForce",
"imageURL": "",
"size": 319,
"type": "user"
}, {
"name": "NBodyForce",
"imageURL": "",
"size": 10498,
"type": "user"
}, {
"name": "Node 1",
"imageURL": "",
"type": "user",
"children": [{
"name": "DragForce 1.1",
"imageURL": "",
"size": 1082,
"type": "chat"
}, {
"name": "DragForce 1.2",
"imageURL": "",
"size": 1082,
"type": "message"
}]
},
{
"name": "Particle",
"imageURL": "",
"size": 2822,
"type": "user"
}, {
"name": "Simulation",
"imageURL": "",
"size": 9983,
"type": "user"
}, {
"name": "Node 2",
"imageURL": "",
"type": "user",
"children": [{
"name": "DragForce 2.1",
"imageURL": "",
"size": 1082,
"type": "message"
}, {
"name": "DragForce 2.2",
"imageURL": "",
"size": 1082,
"type": "message"
}]
},
{
"name": "Spring",
"imageURL": "",
"size": 2213,
"type": "user"
}, {
"name": "SpringForce",
"imageURL": "",
"size": 1681,
"type": "user"
}, {
"name": "Node 3",
"imageURL": "",
"type": "user",
"children": [{
"name": "DragForce 2.1",
"imageURL": "",
"size": 1082,
"type": "chat"
}, {
"name": "DragForce 3.2",
"imageURL": "",
"size": 1082,
"type": "chat"
}]
}]
};
Try as shown in fiddle:
http://jsfiddle.net/cyril123/n28k7oqo/3/
You can specify your data as and pass the image as shown below
var graph = {
"nodes": [
{"x": 469, "y": 410, 'img': "https://cdn1.iconfinder.com/data/icons/industry-2/96/Mine-512.png"},
{"x": 493, "y": 364, 'img': "https://cdn0.iconfinder.com/data/icons/ikooni-outline-free-basic/128/free-09-128.png"},
{"x": 442, "y": 365, 'img': "https://cdn0.iconfinder.com/data/icons/ikooni-outline-free-basic/128/free-17-128.png"},
{"x": 467, "y": 314, 'img': "https://cdn0.iconfinder.com/data/icons/ikooni-outline-free-basic/128/free-22-128.png"},
{"x": 477, "y": 248, 'img': "https://cdn0.iconfinder.com/data/icons/ikooni-outline-free-basic/128/free-13-128.png"},
{"x": 425, "y": 207, 'img': "https://cdn1.iconfinder.com/data/icons/industry-2/96/Mine-512.png"},
{"x": 402, "y": 155, 'img': "https://cdn0.iconfinder.com/data/icons/ikooni-outline-free-basic/128/free-03-128.png"},
{"x": 369, "y": 196, 'img': "https://cdn1.iconfinder.com/data/icons/industry-2/96/Mine-512.png"},
{"x": 350, "y": 148, 'img': "https://cdn1.iconfinder.com/data/icons/industry-2/96/Mine-512.png"},
{"x": 539, "y": 222, 'img': "https://cdn1.iconfinder.com/data/icons/industry-2/96/Mine-512.png"},
{"x": 594, "y": 235, 'img': "https://cdn0.iconfinder.com/data/icons/ikooni-outline-free-basic/128/free-23-128.png"},
{"x": 582, "y": 185, 'img': "https://cdn1.iconfinder.com/data/icons/industry-2/96/Mine-512.png"},
{"x": 633, "y": 200, 'img': "https://cdn1.iconfinder.com/data/icons/industry-2/96/Mine-512.png"}
],
"links": [
{"source": 0, "target": 1},
{"source": 1, "target": 2},
{"source": 2, "target": 0},
{"source": 1, "target": 3},
{"source": 3, "target": 2},
{"source": 3, "target": 4},
{"source": 4, "target": 5},
{"source": 5, "target": 6},
{"source": 5, "target": 7},
{"source": 6, "target": 7},
{"source": 6, "target": 8},
{"source": 7, "target": 8},
{"source": 9, "target": 4},
{"source": 9, "target": 11},
{"source": 9, "target": 10},
{"source": 10, "target": 11},
{"source": 11, "target": 12},
{"source": 12, "target": 10}
]
}
Explanation
The x and y in the json is the probable place where you want to place the circle. Imagine you don't have x and y for any of the nodes; in such case don't pass the x and y in JSON. Something like this:
..."nodes": [
{
'img': "https://cdn1.iconfinder.com/data/icons/industry-2/96/Mine-512.png"
}, ....
Regarding the img pass the url of the image you wish to see on the node.
Like I have done above.
This will append the image to the node group:
//make groups which will hold the image and the circle
nodes = node.data(graph.nodes)
.enter().append("g");
//make a node circle in the group
var circles = nodes.append("circle")
.attr("class", "node")
.attr("r", 12)
.on("dblclick", dblclick)
.call(drag);
//make images in the group
var images = nodes.append("svg:image")
.attr("xlink:href",function(d) {return d.img})
.attr("height", "20")
.attr("width", "20");
The node group is the group which contains the circle and the image.
Like in my Arda family tree I load the images locally by the name of the person. So every person has it's own picture.
Also make sure that you have the onerror in HTML used to show a default image when the wanted image is deleted or something else. Otherwhise the Google Chrome shows an ugly red cross. Just as a tip =)
If you have any further question, just ask.

Resources