2016-04-29 2 views
1

Я знаю, что на подобные вопросы уже был дан ответ, и я пробовал их перед публикацией здесь. Я пытаюсь создать Dendrogram, но получаю эту ошибку. Я полагаю, что он не может найти «детей», но я не понимаю, почему.D3 error - Uncaught TypeError: Не удается прочитать свойство 'children' undefined

Ниже мой json. Это действительно.

{ 
"name": "flare", 
"children": [{ 
    "name": "Animals & Pet Supplies", 
    "children": [{ 
     "name": "Live Animals" 
    }, { 
     "name": "Pet Supplies", 
     "children": [{ 
      "name": "Bird Supplies", 
      "children": [{ 
       "name": "Bird Cages & Stands" 
      }, { 
       "name": "Bird Food" 
      }, { 
       "name": "Bird Ladders & Perches" 
      }, { 
       "name": "Bird Toys" 
      }, { 
       "name": "Bird Treats" 
      }] 
     }, { 
      "name": "Cat Supplies" 
     }] 
    }] 
}] 

}

И ниже HTML-код.

<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> 
     <link type="text/css" rel="stylesheet" href="style.css"/> 
     <!--<script type="text/javascript" src="d3/d3.js"></script> 
     <script type="text/javascript" src="d3/d3.layout.js"></script>--> 
     <script src="http://d3js.org/d3.v3.min.js"></script> 
     <style type="text/css"> 
     .node circle { 
     cursor: pointer; 
     fill: #fff; 
     stroke: steelblue; 
     stroke-width: 1.5px; 
     } 
     .node text { 
     font-size: 11px; 
     } 
     path.link { 
     fill: none; 
     stroke: #ccc; 
     stroke-width: 1.5px; 
     } 
     </style> 
    </head> 
    <body> 
     <div id="body"> 
     <div id="footer"> 
      d3.layout.tree 
      <div class="hint">click or option-click to expand or collapse</div> 
     </div> 
     </div> 
     <script type="text/javascript"> 
     var m = [20, 120, 20, 120], 
      w = 1280 - m[1] - m[3], 
      h = 800 - m[0] - m[2], 
      i = 0, 
      root; 

     var tree = d3.layout.tree() 
      .size([h, w]); 

     var diagonal = d3.svg.diagonal() 
      .projection(function(d) { return [d.y, d.x]; }); 

     var vis = d3.select("#body").append("svg:svg") 
      .attr("width", w + m[1] + m[3]) 
      .attr("height", h + m[0] + m[2]) 
      .append("svg:g") 
      .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); 

     d3.json("flare_orig_reduced.json", function(json) { 
      root = json; 
      root.x0 = h/2; 
      root.y0 = 0; 

      function toggleAll(d) { 
      if (d.children) { 
       d.children.forEach(toggleAll); 
       toggle(d); 
      } 
      } 

      // Initialize the display to show a few nodes. 
      root.children.forEach(toggleAll); 
      toggle(root.children[1]); 
      toggle(root.children[1].children[2]); 
      toggle(root.children[9]); 
      toggle(root.children[9].children[0]); 

      update(root); 
     }); 

     function update(source) { 
      var duration = d3.event && d3.event.altKey ? 5000 : 500; 

      // Compute the new tree layout. 
      var nodes = tree.nodes(root).reverse(); 

      // Normalize for fixed-depth. 
      nodes.forEach(function(d) { d.y = d.depth * 180; }); 

      // Update the nodes… 
      var node = vis.selectAll("g.node") 
       .data(nodes, function(d) { return d.id || (d.id = ++i); }); 

      // Enter any new nodes at the parent's previous position. 
      var nodeEnter = node.enter().append("svg:g") 
       .attr("class", "node") 
       .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) 
       .on("click", function(d) { toggle(d); update(d); }); 

      nodeEnter.append("svg:circle") 
       .attr("r", 1e-6) 
       .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); 

      nodeEnter.append("svg:text") 
       .attr("x", function(d) { return d.children || d._children ? -10 : 10; }) 
       .attr("dy", ".35em") 
       .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) 
       .text(function(d) { return d.name; }) 
       .style("fill-opacity", 1e-6); 

      // Transition nodes to their new position. 
      var nodeUpdate = node.transition() 
       .duration(duration) 
       .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); 

      nodeUpdate.select("circle") 
       .attr("r", 4.5) 
       .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); 

      nodeUpdate.select("text") 
       .style("fill-opacity", 1); 

      // Transition exiting nodes to the parent's new position. 
      var nodeExit = node.exit().transition() 
       .duration(duration) 
       .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) 
       .remove(); 

      nodeExit.select("circle") 
       .attr("r", 1e-6); 

      nodeExit.select("text") 
       .style("fill-opacity", 1e-6); 

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

      // Enter any new links at the parent's previous position. 
      link.enter().insert("svg:path", "g") 
       .attr("class", "link") 
       .attr("d", function(d) { 
       var o = {x: source.x0, y: source.y0}; 
       return diagonal({source: o, target: o}); 
       }) 
      .transition() 
       .duration(duration) 
       .attr("d", diagonal); 

      // Transition links to their new position. 
      link.transition() 
       .duration(duration) 
       .attr("d", diagonal); 

      // Transition exiting nodes to the parent's new position. 
      link.exit().transition() 
       .duration(duration) 
       .attr("d", function(d) { 
       var o = {x: source.x, y: source.y}; 
       return diagonal({source: o, target: o}); 
       }) 
       .remove(); 

      // Stash the old positions for transition. 
      nodes.forEach(function(d) { 
      d.x0 = d.x; 
      d.y0 = d.y; 
      }); 
     } 

     // Toggle children. 
     function toggle (d) { 
      if (d.children) { 
      d._children = d.children; 
      d.children = null; 
      } else { 
      d.children = d._children; 
      d._children = null; 
      } 
     } 


     </script> 
    </body> 
</html> 

Любая помощь очень ценится.

ответ

1

Кажется, что вы хотите сначала открыть все узлы, открытые первоначально.

Вам не нужно писать функцию toggleAll, чтобы открыть все узлы, поскольку они открыты по умолчанию, поскольку все узлы имеют дочерние элементы.

Таким образом, вы можете удалить весь этот код:

function toggleAll(d) { 
    if (d.children) { 
     d.children.forEach(toggleAll); 
     toggle(d); 
    } 
    } 

    // Initialize the display to show a few nodes. 
    root.children.forEach(toggleAll); 
    toggle(root.children[1]); 
    toggle(root.children[1].children[2]); 
    toggle(root.children[9]); 
    toggle(root.children[9].children[0]); 

рабочий код here

+0

Works! Благодаря! Хотелось бы, чтобы я мог подняться, но у меня недостаточно очков:/Быстрый вопрос - как бы вы приблизились, если вы не хотите, чтобы у каждого узла были дети и не редактировали оригинальный json? – Testing123

+0

Моя ошибка, код будет запущен без детей http://plnkr.co/edit/4dZN4isO9X8E5HVdcJxq?p=preview, это было переключением всего, что вызывало ошибку. – Cyril

+1

Отлично! Я проверил это. Еще раз спасибо. – Testing123

Смежные вопросы