I want to create zoomable circle-pack graph with edges between most internal children,I used this code for base, and my code is :
var year=[]
var edges
var svg
function main_graph(){
svg = d3.select("svg"),
margin = 20,
diameter = +svg.attr("width"),
g = svg.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
var color = d3.scaleLinear()
.domain([-1, 5])
.range(["hsl(152,80%,80%)", "hsl(228,30%,40%)"])
.interpolate(d3.interpolateHcl);
svg.append("svg:defs")
.append("svg:marker")
.attr("id", "arrow")
.attr("viewBox", "0 0 10 10")
.attr("refX", 10)
.attr("refY", 5)
.attr("markerUnits", "strokeWidth")
.attr("markerWidth", 6)
.attr("markerHeight", 3)
.attr("orient", "auto")
.append("svg:path")
.style("stroke","none")
.attr("d", "M 0 0 L 10 5 L 0 10 z");
var pack = d3.pack()
.size([diameter/20, diameter/20])
.padding(20)
d3.json("flare.json", function(error, root) {
edges=root.links
var leyer1=root.children
var leyer1_len=leyer1.length
console.log(leyer1_len)
for(i=0;i<leyer1_len;i++){
var leyer2_len=(leyer1[i]).children.length
var leyer2=(leyer1[i]).children
for(j=0;j<leyer2_len;j++){
var from_year=leyer2[j].from
var to_year=leyer2[j].to
var id_auther=leyer2[j].id
year.push({from:from_year,to:to_year,id:id_auther})
}
}
if (error) throw error;
root = d3.hierarchy(root)
.sum(function(d) { return d.size; })
.sort(function(a, b) { return b.value - a.value; });
var focus = root,
nodes = pack(root).descendants(),
view;
var circle = g.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node
node--root"; })
.attr("id",function(d){return d.data.id})
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.style("fill", function(d) { return d.children ? color(d.depth) : null; })
.on("click", function(d) {if (focus !== d) zoom(d), d3.event.stopPropagation(); });
var text = g.selectAll("text")
.data(nodes)
.enter().append("text")
.attr("class", "label")
.style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; })
.style("display", function(d) { return d.parent === root ? "inline" : "none"; })
.text(function(d) { return d.data.name; });
var node = g.selectAll("circle,text");
const arrow = svg.selectAll('path.arrow').data(edges);
arrow.enter()
.append("path")
.attr("class","arrow")
.attr("x1", function(d){
debugger
let translate = getTranslate(d.source);
console.log(translate[0])
return translate[0]
})
.attr("x2", function(d){
let translate = getTranslate(d.target);
console.log(translate[0])
return translate[0]
})
.attr("y1", function(d){
let translate = getTranslate(d.source);
console.log(translate[1])
return translate[1]
})
.attr("y2", function(d){
let translate = getTranslate(d.target);
console.log(translate[1])
return translate[1]
})
.attr("d", function(d) {
let source = getTranslate(d.source),
target = getTranslate(d.target),
x1= source[0],
x2= target[0],
y1= source[1],
y2= target[1];
diffX = x2 - x1;
diffY = y2 - y1;
// Length of path from center of source node to center of target node
pathLength = Math.sqrt((diffX * diffX) + (diffY * diffY));
// x and y distances from center to outside edge of target node
offsetX = (diffX * 10) / pathLength;
offsetY = (diffY * 10) / pathLength;
return "M" + x1 + "," + y1 + "L" + (x2 - offsetX) + "," + (y2 - offsetY);
})
.style("stroke", "black")
.style("fill", "none")
.style("stroke-width", 0.5)
.attr("marker-end", "url(#arrow)");
function getTranslate(datum) {
debugger
var myselect=d3.select('#'+datum)
const string = myselect.attr("transform");
const translate = string.substring(string.indexOf("(")+1, string.indexOf(")")).split(",");
return translate;
}
svg
.style("background", color(-1))
.on("click", function() { zoom(root); });
zoomTo([root.x, root.y, root.r * 2 + margin]);
function zoom(d) {
var focus0 = focus; focus = d;
var transition = d3.transition()
.duration(d3.event.altKey ? 7500 : 750)
.tween("zoom", function(d) {
var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
return function(t) { zoomTo(i(t)); };
});
transition.selectAll("text")
.filter(function(d) { return d.parent === focus || this.style.display === "inline"; })
.style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })
.on("start", function(d) { if (d.parent === focus) this.style.display = "inline"; })
.on("end", function(d) { if (d.parent !== focus) this.style.display = "none"; });
}
function zoomTo(v) {
var k = diameter / v[2]; view = v;
node.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });
circle.attr("r", function(d) { return d.r * k; });
}
});
}
I append path to graph but I don't get result. my json format also is here
{"name":"variants","links":[{"source":"i0","target":"i2"},
{"source":"i12","target":"i13"}],"id":14,"children":[{"name":"19","id":15,"children":
[{"name":"aaaacxi7gjuvmascvqjaabaadm","size":25,"from":1930,"to":2006,"id":'i15'},
{"name":"undefined","size":25,"from":1910,"to":2008,"id":"i1"},
{"name":"aaaacxi7gjuvmascvqjaabaadi","size":25,"from":1955,"to":1965,"id":"i14"},
{"name":"aaaacxi7gjuvmascvqjaabaade","size":25,"from":1980,"to":2015,"id":"i0"},
{"name":"aaaacxi7gjuvmascvqjaabaac4","size":25,"from":1950,"to":2070,"id":"i2"},
{"name":"aaaacxi7gjuvmascvqjaabaada","size":25,"from":1900,"to":2020,"id":"i3"},
{"name":"aaaacxi7gjuvmascvqjaabaadu","size":25,"from":1980,"to":2008,"id":"i4"},
{"name":"aaaacxi7gjuvmascvqjaabaadq","size":25,"from":1990,"to":2000,"id":"i5"}]}
,{"name":"22","id":"i16","children":[{"name":"neda","size":25,"from":2000,"to":2020,"id":"i8"},
{"name":"aaaacxi7gka5qascvqjaabaaai","size":25,"from":1940,"to":2000,"id":"i9"},
{"name":"aaaacxi7gka5oascvqjaabaacq","size":55,"from":1960,"to":2010,"id":"i10"},
{"name":"aaaacxi7gka5qascvqjaabaaay","size":55,"from":1940,"to":2000,"id":"i11"},
{"name":"aaaacxi7gj4eqascvqjaabaab4","size":55,"from":1980,"to":2020,"id":"i12"},
{"name":"aaaacxi7gka5oascvqjaabaacm","size":55,"from":1940,"to":2000,"id":"i13"}]}
]}
my code add path in svg element but I think they are not in correct position,
and also this post is nearly to my purpose
Thank you very much for helping me.