add edges in zoomable circle-pack graph in d3 library

Viewed 78

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.

0 Answers
Related