Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript D3.js可折叠力布局:未生成链接_Javascript_Api_Svg_D3.js_Force Layout - Fatal编程技术网

Javascript D3.js可折叠力布局:未生成链接

Javascript D3.js可折叠力布局:未生成链接,javascript,api,svg,d3.js,force-layout,Javascript,Api,Svg,D3.js,Force Layout,我试图生成一个类似于此示例的可折叠力布局: 用于生成my force布局的数据是一个源于API的JSON对象。我能够成功地遍历数据结构,并生成附加到SVG的节点(根节点及其子节点) 但是,将父节点链接到其子节点时会出现问题没有生成链接,我的Links变量返回一个空数组。与示例相比,我非常确定这个问题与我的应用程序中的数据结构有关,因此我将发布我的JS代码和每个节点的数据结构 任何帮助都将不胜感激!提前谢谢 下面是我的代码: 以下是我的JS代码: //Force Layout Code var

我试图生成一个类似于此示例的可折叠力布局:

用于生成my force布局的数据是一个源于API的JSON对象。我能够成功地遍历数据结构,并生成附加到SVG的节点(根节点及其子节点)

但是,将父节点链接到其子节点时会出现问题没有生成链接,我的Links变量返回一个空数组。与示例相比,我非常确定这个问题与我的应用程序中的数据结构有关,因此我将发布我的JS代码和每个节点的数据结构

任何帮助都将不胜感激!提前谢谢


下面是我的代码:

以下是我的JS代码:

//Force Layout Code
var w = 607,
    h = 500,
    node,
    link,
    root;

var force = d3.layout.force()
    .on("tick", tick)
    .size([w, h]);

var vis = d3.select("#chart").append("svg:svg")
    .attr("width", w)
    .attr("height", h);

function initiateForceJS(currentURL) {
    //Generate the URL
    forceURL = currentURL + ".json?jsonp=?";
    $('#commentArea').show();
    $.getJSON(forceURL,handleRequest2);
    function handleRequest2(json) {
        //Set the root as the first object returned
        root = json[1]['data']['children'][0];
        update();
    }
}

function update() {
  nodes = flatten(root),
  links = d3.layout.tree()
            .sort(null)
            .children(function(d) {return (!d['replies']['data']['children']|| d['replies']['data']['children'].length === 0) ? null : d['replies']['data']['children'];})
            .links(nodes);

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

  // Update the links…
  link = vis.selectAll("line.link")
      .data(links, function(d) { return d.target.id; });

  // Enter any new links.
  link.enter().insert("svg:line", ".node")
      .attr("class", "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; });

  // Exit any old links.
  link.exit().remove();

  // Update the nodes…
  node = vis.selectAll("circle.node")
      .data(nodes, function(d) {return d.id; })
      .style("fill", color);

  // Enter any new nodes.
  node.enter().append("svg:circle")
      .attr("class", "node")
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; })
      .attr("r", function(d) { return Math.sqrt(d.ups) || 4.5; })
      .style("fill", color)
      //.on("click", click)
      .call(force.drag);

  // Exit any old nodes.
  node.exit().remove();
  //This will add the name of the character to the node

  node.append("comment").text(function(d) { return d.body });
  //This will put the comment in the Comment Area div
  node.on("mouseover", function() {
    var currentNode = d3.select(this);
    var currentTitle = currentNode.select("comment").text();
    $('#commentArea').html('<p>' + currentTitle + '</p>')  
  });
} 


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("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
}

// Color leaf nodes orange, and packages white or blue.
function color(d) {
  return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}
// Returns a list of all nodes under the root.
function flatten(root) {
  var nodes = [], i = 0;
  function recurse(node) {

    if (node['data']['replies'] != "" && node['kind'] != "more") {
        node['data']['replies']['data']['children'].forEach(recurse);
    }
    if (node['kind'] !="more") {
        //Add an ID value to the node starting at 1
        node.data.id = ++i;
        var comment = node.data;
        nodes.push(comment);
    }
  }
  recurse(root);
  return nodes;
}
//强制布局代码
var w=607,
h=500,
节点,
链接
根;
var-force=d3.layout.force()
.on(“滴答”,滴答)
.尺寸([w,h]);
var vis=d3.选择(“图表”).追加(“svg:svg”)
.attr(“宽度”,w)
.attr(“高度”,h);
函数initiateForceJS(当前URL){
//生成URL
forceURL=currentURL+“.json?jsonp=?”;
$('#commentArea').show();
$.getJSON(forceURL,handleRequest2);
函数handleRequest2(json){
//将根设置为返回的第一个对象
root=json[1]['data']['children'][0];
更新();
}
}
函数更新(){
节点=展平(根),
links=d3.layout.tree()
.sort(空)
.children(函数(d){return(!d['repries']['data']['children'].| d['repries']['data']['children'].['children'.]长度==0)?null:d['repries'.['data']['children'].})
.链接(节点);
//重新启动强制布局。
力
.节点(节点)
.链接(links)
.start();
//更新链接…
link=vis.selectAll(“line.link”)
.data(链接,函数(d){返回d.target.id;});
//输入任何新链接。
link.enter().insert(“svg:line”,“.node”)
.attr(“类”、“链接”)
.attr(“x1”,函数(d){返回d.source.x;})
.attr(“y1”,函数(d){返回d.source.y;})
.attr(“x2”,函数(d){返回d.target.x;})
.attr(“y2”,函数(d){返回d.target.y;});
//退出所有旧链接。
link.exit().remove();
//更新节点…
node=vis.selectAll(“circle.node”)
.data(节点,函数(d){return d.id;})
.样式(“填充”,颜色);
//输入任何新节点。
node.enter().append(“svg:circle”)
.attr(“类”、“节点”)
.attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;})
.attr(“r”,函数(d){return Math.sqrt(d.ups)| | 4.5;})
.样式(“填充”,颜色)
//.on(“单击”,单击)
.呼叫(强制拖动);
//退出所有旧节点。
node.exit().remove();
//这将向节点添加角色的名称
node.append(“comment”).text(函数(d){return d.body});
//这将把评论放在评论区div中
on(“mouseover”,function()){
var currentNode=d3.选择(此);
var currentTitle=currentNode.select(“comment”).text();
$('#commentArea').html(''+currentTitle+'

')) }); } 函数tick(){ attr(“x1”,函数(d){返回d.source.x;}) .attr(“y1”,函数(d){返回d.source.y;}) .attr(“x2”,函数(d){返回d.target.x;}) .attr(“y2”,函数(d){返回d.target.y;}); attr(“cx”,函数(d){return d.x;}) .attr(“cy”,函数(d){返回d.y;}); } //叶节点颜色为橙色,包装为白色或蓝色。 功能色(d){ 返回d.#children?#3182bd:d.children?#c6dbef:#fd8d3c; } //返回根目录下所有节点的列表。 函数展平(根){ var节点=[],i=0; 函数递归(节点){ 如果(节点['data']['replays']!=”&节点['kind']!=“more”){ 节点['data']['replies']['data']['children'].forEach(递归); } 如果(节点['kind']!=“more”){ //从1开始向节点添加ID值 node.data.id=++i; var comment=node.data; 节点。推送(注释); } } 递归(根); 返回节点; }
问题在于函数没有观察到您设置的子访问器;它仅依赖于节点的
子节点
属性。这在原始示例中起作用,因为该示例使用标准的分层节点结构(每个节点上都有一个
子节点
数组)。它在您的情况下不起作用,因为您使用的是非标准结构(由第三方API定义)

links方法不观察子访问器,因为当您对数据调用层次结构布局(如树布局)时,它会根据您定义的子访问器为您填充
子访问器
属性;它会自动将非标准输入数据映射到标准表单。但是,由于您没有在此处实际使用层次结构布局,因此没有机会将节点映射到标准格式,因此hierarchy.links不会返回任何结果。没有节点具有
子节点
数组

这里的另一个问题是,您的
根节点实际上没有任何回复,因此没有根节点的子节点。(有
root.data.repress.data.children
,但没有定义
root.repress.data.children
作为子访问器。)


我认为在这里最简单的做法是将数据映射到一个更简单的层次结构,其中子级定义为
子级
数组。您可能可以使用层次结构布局来帮助实现这一点,但鉴于您已经编写了一个展平函数(或至少修改了一个),您已经完成了大部分工作。

如果没有看到数据的完整结构,我认为不可能回答这个问题。例如,您的屏幕截图不会显示回复对象中的内容。你能