2017-08-09 66 views
0

我試圖在點擊繪製子節點時獲取數據。 我已閱讀this similar question的答案。d3加載點擊下一個節點的數據

但是,看起來像是在點擊時添加的子節點無法找到父節點。

enter image description here

這裏是我的全部代碼:

var hierarchy = d3.layout.hierarchy().children(function(d) { 
    return d.childCi; 
}); 

function parseLevel(node, level) { 
    node.level = level; 
    if (typeof node.children !== 'undefined') { 
     node.children.forEach(function(children) { 
      parseLevel(children, level + 1); 
     }); 
    } 
} 

var COLLAPSE_LEVEL = 1; 

var width = 960, height = 500, root; 

var force = d3.layout.force().linkDistance(80).charge(-120).gravity(.05) 
     .size([ width, height ]).on("tick", tick); 

var svg = d3.select("#canvas-svg").append("svg").attr("width", width).attr(
     "height", height); 

var link = svg.selectAll(".link"), 

node = svg.selectAll(".node"); 

d3.json("graph.json", function(error, json) { 
    if (error) 
     throw error; 

    hierarchy(json); 
    root = json; 
    update(); 
    parseLevel(root, 0); 
    //collapseAll(); 
    root.children.forEach(collapseAll); 
}); 

function collapse(d) { 
    if (d.children) { 
     d._children = d.children; 
     d._children.forEach(collapse); 
     d.children = null; 
    } 
} 

function collapseAll(d) { 

    if (d.children) { 
     d.children.forEach(collapseAll); 
     if (d.level < COLLAPSE_LEVEL) { 
      return; 
     } 
     collapse(d); 
     update(); 
    } 
} 

function update() { 
    var nodes = flatten(root), links = d3.layout.tree().links(nodes); 
    console.log(links); 

    // Restart the force layout. 
    force.nodes(nodes).links(links).start(); 

    // Update links. 
    link = link.data(links, function(d) { 
     return d.target.id; 
    }); 

    link.exit().remove(); 

    link.enter().insert("line", ".node").attr("class", "link"); 

    // Update nodes. 
    node = node.data(nodes, function(d) { 
     return d.id; 
    }); 

    node.exit().remove(); 

    var nodeEnter = node.enter().append("g").attr("class", "node").on(
      "click", click).call(force.drag); 

    nodeEnter.append("circle").attr("r", function(d) { 
     return Math.sqrt(d.size)/10 || 10; 
    }); 

    nodeEnter.append("text").attr("dy", ".35em").text(function(d) { 
     return d.ciName; 
    }); 

    nodeEnter.append("text").attr("dy", ".35em").attr("y", -10).text(
      function(d) { 

       if (d.childBox) { 

        console.log('d.childBox[0].childCiCount' 
          + d.childBox[0].childCiCount); 
        return d.childBox[0].childCiCount; 
       } 

       if (d.children) 
        return d.children.length; 
       else if (d._children) 
        return d._children.length; 
       else 
        return ''; 
      }); 

    node.select("circle").style("fill", color); 
} 

function tick() { 

    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 + ")"; 
    }); 
} 

function color(d) { 

    if (d._children) { 
     return "#3182bd"; 
    } else if (d.children) { 
     return "#c6dbef"; 
    } else { 
     if (d.ciStatusLevel == 1) { 
      console.log("ciStatusLevel:" + d.ciStatusLevel); 
      return "#FFF173"; 
     } 

     return "#fd8d3c"; 
    } 

    /* return d._children ? "#3182bd" // collapsed package 
    : d.children ? "#c6dbef" // expanded package 
    : "#fd8d3c"; // leaf node */ 
} 

//Toggle children on click. 
/* function click(d) { 
if (d3.event.defaultPrevented) return; // ignore drag 

if (d.children) { 
d._children = d.children; 
d.children = null; 
} else { 
d.children = d._children; 
d._children = null; 
} 
update(); 


} 
*/ 

function click(d) { 

    if (!d.children && !d._children) { 

     var nameOfTheFile = 'data/test1.json'; 
     var childObjects; 

     d3.json(nameOfTheFile, function(error, json) { 

      childObjects = json; 

      console.log(childObjects); 
      childObjects.forEach(function(node) { 

       if (node.ciName != d.ciName) { 
        (d._children || (d._children = [])).push(node); 

       } 

      }); 

      if (d.children) { 
       d._children = d.children; 
       d.children = null; 
      } else { 
       d.children = d._children; 
       d._children = null; 
      } 
      update(d); 

     }); 

    } else { 
     if (d.children) { 
      d._children = d.children; 
      d.children = null; 
     } else { 
      d.children = d._children; 
      d._children = null; 
     } 
     update(d); 
    } 

} 

//Returns a list of all nodes under the root. 
function flatten(root) { 
    var nodes = [], i = 0; 

    function recurse(node) { 
     if (node.children) { 
      node.children.forEach(recurse); 
     } 
     if (!node.id) { 
      node.id = ++i; 
     } 
     nodes.push(node); 

    } 

    recurse(root); 
    return nodes; 
} 

P.S:我使用武力佈局(https://bl.ocks.org/mbostock/1093130

+0

目前還不清楚你在問什麼。關係是自上而下的,即父節點持有對其子節點的引用,但子節點對其父節點一無所知。你真正的問題是什麼?你在期待什麼?你看到了什麼呢?請儘可能精確。設置[mcve]也會有幫助。 – altocumulus

+0

我的期望是,如果我像上面點擊添加子對象,它應該展開子對象。但是,現在它不顯示。相反,父節點會斷開連接到其父節點。 – jessie820

+0

好吧,我成功地點擊添加一個新節點。但是,添加新節點後,圖形不會再次崩潰。會是什麼問題..? – jessie820

回答

0

好的我有一個解決方案!

var target = {id:nodes.length + 1,ciName:「test」};

 /* console.log('node in click'); 
     console.log(node); 
     console.log('link in click'); 
     console.log(link); */ 
     (d._children || (d._children = [])).push(target); 
0

好吧,我上點擊添加新節點成功。但是,添加新節點後,圖形不會再次崩潰。會是什麼問題..?

var width = 960,height = 500,root;

var force = d3.layout.force().linkDistance(80).charge(-120).gravity(.05) 
     .size([ width, height ]).on("tick", tick); 



var nodes; 
var link, node; 

d3.json("graph.json", function(error, json) { 
if (error) throw error; 

root = json; 
    nodes = flatten(root), 
links = d3.layout.tree().links(nodes); 
update(); 
}); 

function collapse(d) { 
    if (d.children) { 
     d._children = d.children; 
     d._children.forEach(collapse); 
     d.children = null; 
    } 
} 

function collapseAll(d) { 
    /* collapse(root); 
    update(); */ 

    if (d.children) { 
     d.children.forEach(collapseAll); 
     if (d.level < COLLAPSE_LEVEL) { 
      return; 
     } 
     collapse(d); 
     update(); 
    } 
} 

function update() { 
    /* nodes = flatten(root), 
    links = d3.layout.tree().links(nodes); 
    console.log('nodes'); 
    console.log(nodes); 
    console.log('links'); 
    console.log(links); 

    // Restart the force layout. 
    force.nodes(nodes).links(links).start(); 


    link = svg.selectAll(".link"), 

    node = svg.selectAll(".node"); 



    // Update links. 
    link = link.data(links, function(d) { 
     return d.target.id; 
    }); 

    link.exit().remove(); 

    var linkEnter = link.enter().insert("line", ".node").attr("class", "link"); 

    //link = linkEnter.merge(link); 

    // Update nodes. 
    node = node.data(nodes, function(d) { 
     return d.id; 
    }); 
    node.exit().remove(); 


    var nodeEnter = node.enter().append("g").attr("class", "node").on(
      "click", click).call(force.drag);//click 리스너 추가 

    nodeEnter.append("circle").attr("r", function(d) { 
     return Math.sqrt(d.size)/10 || 10; 
    }); 

    nodeEnter.append("text").attr("dy", ".35em").text(function(d) { 
     return d.ciName; 
    }); 

    nodeEnter.append("text").attr("dy", ".35em").attr("y", -10).text(
      function(d) { 

       if (d.childBox) { 

        console.log('d.childBox[0].childCiCount' 
          + d.childBox[0].childCiCount); 
        return d.childBox[0].childCiCount; 
       } 

       if (d.children) 
        return d.children.length; 
       else if (d._children) 
        return d._children.length; 
       else 
        return ''; 
      }); 

    node.select("circle").style("fill", color); 

    //node = nodeEnter.merge(node); 

} 

function tick() { 

    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 + ")"; 
    }); 
} 

function color(d) { 

    if (d._children) { 
     return "#3182bd"; 
    } else if (d.children) { 
     return "#c6dbef"; 
    } else { 
     if (d.ciStatusLevel == 1) { 
      console.log("ciStatusLevel:" + d.ciStatusLevel); 
      return "#FFF173"; 
     } 

     return "#fd8d3c"; 
    } 

    /* return d._children ? "#3182bd" // collapsed package 
    : d.children ? "#c6dbef" // expanded package 
    : "#fd8d3c"; // leaf node */ 
} 

//Toggle children on click. 
/* function click(d) { 
if (d3.event.defaultPrevented) return; // ignore drag 

if (d.children) { 
d._children = d.children; 
d.children = null; 
} else { 
d.children = d._children; 
d._children = null; 
} 
update(); 


} 
*/ 

function click(d) { 


    console.log('d'); 
    console.log(d); 

    if (!d.children && !d._children) { 


      var target = {id: nodes.length+1, ciName: "test"}; 

      /* console.log('node in click'); 
      console.log(node); 
      console.log('link in click'); 
      console.log(link); */ 
      (d._children || (d._children = [])).push(target); 
      nodes.push(target); 
      links.push({source: d, target: target}); 



     if (d.children) { 
       d._children = d.children; 
       d.children = null; 
      } else { 
       d.children = d._children; 
       d._children = null; 
      } 
      update(); 



    } else { 
     if (d.children) { 
      d._children = d.children; 
      d.children = null; 
     } else { 
      d.children = d._children; 
      d._children = null; 
     } 
     update(); 
    } 

} 

//Returns a list of all nodes under the root. 
function flatten(root) { 
    var nodes = [], i = 0; 

    function recurse(node) { 
     if (node.children) { 
      node.children.forEach(recurse); 
     } 
     if (!node.id) { 
      node.id = ++i; 
     } 
     nodes.push(node); 

    } 

    recurse(root); 
    return nodes; 
}