2016-08-16 9 views
0

d3で折りたたみ可能なツリーグラフを作成しようとしています。 Web上には多くの例がありますが、私はJSやJavaのバックグラウンドから来るd3の専門家ではなく、私のニーズに完全に合ったものを見つけることができなかったので、多くのブログや要点に見られる異なるテンプレートから作成しました。d3jsツリーグラフをクリップする方法を解決する

問題は、グラフの下の部分がクリップされてしまうことです。私はsvgのサイズを増やすと、それはグラフを伸ばすだけで、まだクリップされます。私はコードを入れたplunkrへのリンクを掲示しています。 plunkrのにスクロールしてグラフを表示してください。

以下

ツリー

var CollapsibleTree = function(elt) { 

    var m = [20, 120, 20, 120], 
    w = 1280 - m[1] - m[3], 
    h = 780 - m[0] - m[2], 
    i = 0, 
    root; 

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

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

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

    var vis = d3.select(elt).append("svg:svg") 
    .attr("width", w + m[1] + m[3]) 
    .attr("height", h + m[0] + m[2]) 
    .append("svg:g") 
    .attr("transform", "translate("+w/6+","+h/2+")"); // bidirectional-tree 


    var that = { 
    init: function(url) { 
     var that = this; 
     var json = { 
     "name":"A", 
     "elementType":"ACTION", 
     "elementSubType":"ACTION-A", 
     "isparent":false, 
     "parents":[ 
      { 
       "name":"B", 
       "elementType":"RESOURCE", 
       "elementSubType":"RESOURCE-A", 
       "isparent":true 
      } 
     ], 
     "children":[ 
      { 
       "name":"C", 
       "elementType":"RESOURCE", 
       "elementSubType":"RESOURCE-C", 
       "isparent":false, 
       "children":[ 
        { 
        "name":"D", 
        "elementType":"ACTION", 
        "elementSubType":"ACTION-A", 
        "isparent":false, 
        "children":[ 
         { 
          "name":"E", 
          "elementType":"RESOURCE", 
          "elementSubType":"RESOURCE-A", 
          "isparent":false, 
          "children":[ 
           { 
           "name":"F", 
           "elementType":"ACTION", 
           "elementSubType":"ACTION-C", 
           "isparent":false, 
           "children":[ 
            { 
             "name":"G", 
             "elementType":"RESOURCE", 
             "elementSubType":"RESOURCE-C", 
             "isparent":false 
            } 
           ] 
           } 
          ] 
         } 
        ] 
        } 
       ] 
      } 
     ] 
     }; 
     root = json; 
     root.x = w/2; 
     root.y = h/2; 

     that.updateBoth(root); 
    }, 

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

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

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

     // 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) { 
     if(that.isParent(d)) { 
      return "translate(" + source.x + "," + -source.y + ")"; 
     } else { 
      return "translate(" + source.x + "," + source.y + ")"; 
     } 
     }) 
     .on("click", function(d) { that.toggle(d); that.updateBoth(d); }); 

     // Add images to node 
     nodeEnter.append("svg:image") 
     .attr("xlink:href", "img/file.png") 
     .attr("width", 35) 
     .attr("height", 35) 
     .attr("x",function(d) { return -20; }) // position the images 
     .attr("y",function(d) { return -20; }); 

     nodeEnter.append("text") 
     // .attr("x", function(d) { return d.children || d._children ? -10 : 10; }) 
     .attr("x", function(d) { 
     return -10; 
     }) 
     .attr("y", 20) 
     .attr("dy", ".35em") 
     .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) 
     .attr("text-anchor", function(d) { 
     return "middle"; 
     }) 
     .text(function(d) { 
     if (d.name.length > 10){ 
      return d.name.substring(0,10)+d.name.substring(10,d.name.length); 
     } 
     else { 
      return d.name; 
     } 
     }) 
     .style("fill", "black") 
     .style("fill-opacity", 1e-6); 

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

     nodeUpdate.select("text") 
     .style("fill-opacity", 1) 
     .attr("class", function(d){ 
     if (d.status==="incomplete" || d.status === "failed"){ 
      return "blink"; 
     } else { 
      return "non-blink" 
     } 
     }); 

     // 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 + ")"; }) 
     .attr("transform", function(d) { // custom code to fix error in node exit 
     if (that.isParent(d)){ 
      return "translate(" + source.x + "," + -source.y + ")"; // controls exit of parents 
     } 
     else{ 
      return "translate(" + source.x + "," + source.y + ")"; // controls exit of children 
     } 
     }) 
     .remove(); 

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

     // Update the links… 
     var link = vis.selectAll("path.link") 
     .data(tree.links_parents(nodes).concat(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") 
     .style("stroke", function(d) { 
     return "black"; 
     }) 
     .attr("d", function(d) { 
     var o = {x: source.x, y: source.y}; 
     if(that.isParent(d.target)) { 
      return parentdiagonal({source: o, target: o}); 
     } else { 
      return childdiagonal({source: o, target: o}); 
     } 
     }) 
     .transition() 
     .duration(duration) 
     .attr("d", function(d) { 
     if(that.isParent(d.target)) { 
      return parentdiagonal(d); 
     } else { 
      // return parentdiagonal(d); 
      return childdiagonal(d); 
     } 
     }) 

     // Transition links to their new position. 
     link.transition() 
     .duration(duration) 
     .attr("d", function(d) { 
     if(that.isParent(d.target)) { 
      return parentdiagonal(d); 
     } else { 
      return childdiagonal(d); 
     } 
     }) 

     // 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 parentdiagonal({source: o, target: o}); 
     if(that.isParent(d.target)) { 
      return parentdiagonal({source: o, target: o}); 
     } else { 
      return childdiagonal({source: o, target: o}); 
     } 
     }) 
     .remove(); 

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

    isParent: function(node) { 
     if(node.parent && node.parent != root) { 
     return this.isParent(node.parent); 
     } else 
     if(node.isparent) { 
     return true; 
     } else { 
     return false; 
     } 
    }, 

    // Toggle children or parents (one level). 
    toggle: function(d) { 
     if (d.children) { 
     d._children = d.children; 
     d.children = null; 
     } else { 
     d.children = d._children; 
     d._children = null; 
     } 
     if (d.parents) { 
     d._parents = d.parents; 
     d.parents = null; 
     } else { 
     d.parents = d._parents; 
     d._parents = null; 
     } 
    }, 

    // Toggle successors or aancestors (multiple level) 
    toggleAll: function(d) { 
     if (d.children) { 
     d.children.forEach(that.toggleAll); 
     that.toggle(d); 
     } 
     if (d.parents) { 
     d.parents.forEach(that.toggleAll); 
     that.toggle(d); 
     } 
    } 

    } 

    return that; 
} 

、ここをレンダリングするJavascriptをcss

body { 
    overflow: hidden; 
    margin: 0; 
    font-size: 14px; 
    font-family: "Helvetica Neue", Helvetica; 
} 

#chart, #header, #footer { 
    position: absolute; 
    top: 0; 
} 

#header, #footer { 
    z-index: 1; 
    display: block; 
    font-size: 36px; 
    font-weight: 300; 
    text-shadow: 0 1px 0 #fff; 
} 

#header.inverted, #footer.inverted { 
    color: #fff; 
    text-shadow: 0 1px 4px #000; 
} 

#header { 
    top: 80px; 
    left: 140px; 
    width: 1000px; 
} 

#footer { 
    top: 680px; 
    right: 140px; 
    text-align: right; 
} 

rect { 
    fill: none; 
    pointer-events: all; 
} 

pre { 
    font-size: 18px; 
} 

line { 
    stroke: #000; 
    stroke-width: 1.5px; 
} 

.string, .regexp { 
    color: #f39; 
} 

.keyword { 
    color: #00c; 
} 

.comment { 
    color: #777; 
    font-style: oblique; 
} 

.number { 
    color: #369; 
} 

.class, .special { 
    color: #1181B8; 
} 

a:link, a:visited { 
    color: #000; 
    text-decoration: none; 
} 

a:hover { 
    color: #666; 
} 

.hint { 
    position: absolute; 
    right: 0; 
    width: 1280px; 
    font-size: 12px; 
    color: #999; 
} 

.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; 
} 

/*svg { 
    border: 1px; 
    border-style: solid; 
    border-color: black; 
}*/ 

#foo { 
    border: 5px; 
    border-style: dashed; 
    border-color: black; 
    background-color: pink; 
} 

#categoryHierarchy{ 
    margin: 5px; 
    height: 700px; 
    width: auto; 
    border: 2px; 
    border-style: solid; 
    border-color: #000; 
    overflow: scroll; 

    /*padding: 10px;*/ 
} 

htmlファイル

<body> 
    <div id="categoryHierarchy"></div> 
    <script type="text/javascript"> 
      $(document).ready(function(event) { 
      var tree = CollapsibleTree("#categoryHierarchy"); 
      tree.init('sample.json'); 
      }); 
    </script> 
    </body> 
+0

行22、.attr( "height"、1000/* h + m [0] + m [2] * /)それは動作する可能性があります – silviagreen

+0

@ silviagreenええ、それは非常に大きな高さのコンテナを作成することによって動作するようです。このような長いコンテナの作成を避けるために、クリップされた場合はスクロールダウンできるソリューションがありますか? – mahacoder

答えて

0

あなたはそれぞれの間の距離を短くしてみてください可能性がありますされ'ノード'。

など。私は300を使って試しました。

nodes.forEach(function(d) { d.y = d.depth * 0.5*(h-300)/4; }); 
関連する問題