投稿記事

レイアウト - Cluster & Tree

30 May 2014

レイアウトの cluster と tree は、よく似ています。

下図の『行徳』ノードの位置を見てください。

treeの場合は、同じ深さのノードの位置にあります。

clusterの場合は、一番深いノードの位置にあります。

Cluster Layout

Tree Layout

fill属性

Collapsible Tree Layout

ノードをクリックしてください。

/**
  ApplicationViewModel (knockout.js)
**/
function AppViewModel() {
var width = 960,
    height = 700;

// Create a cluster & a tree layout 
var cluster = d3.layout.cluster()
    .size([height, width - 180]);
var tree    = d3.layout.tree()
    .size([height, width - 180]);

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

// Create SVG container
var svg01 = d3.select("#ins01").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(50,0)");
var svg02 = d3.select("#ins02").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(50,0)");

// selecter options (ko)
fillAttr = ['green', 'orange', 'none'];
selectedFillAttr = ko.observable('green');

// draw layouts
drawCluster();
drawTree();
  
  /*************************************
    click event (ko) 
  **************************************/
  // 
  self.draw = function() {
    svg01.selectAll(".link").remove();
    svg01.selectAll(".node").remove();
    svg01.selectAll("g").remove();
    svg02.selectAll(".link").remove();
    svg02.selectAll(".node").remove();
    svg02.selectAll("g").remove();
    
    drawCluster();
    drawTree();
  };

  /* Draw cluster layout */
  function drawCluster(){
    d3.json("/assets/json/mise.json", function(error, root) {
      var nodes = cluster.nodes(root),
          links = cluster.links(nodes);
      
      // 連結線の描画
      var link = svg01.selectAll(".link")
          .data(links)
        .enter().append("path")
          .attr("stroke","white")
          .attr("stroke-width", 3)
         .style("fill",function(){return selectedFillAttr();})
          .attr("class", "link")
          .attr("d", diagonal);
      
      //ノードの描画
      var node = svg01.selectAll(".node")
          .data(nodes)
        .enter().append("g")
          .attr("class", "node")
          .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
      // ノードに円を追加    
      node.append("circle")
          .attr("r", function(d){return (10 - d.depth * 2) < 4 ? 4 : (10 - d.depth * 2);})
          .attr("stroke","red")
          .attr("stroke-width", function(d){ return (3 - d.depth)===0 ? 1 : (3 - d.depth) })
          .style("fill","lime");
      // ノードにテキストを追加    
      node.append("text")
          .attr("dx", function(d) { return d.children ? -8 : 8; })
          .attr("dy", 3)
          .style("text-anchor", function(d) { return d.children ? "end" : "start"; })
          .text(function(d) { return d.name; })
          .style("fill","yellow");
    });
  
  };
  /* Draw tree layout */
  function drawTree(){
    d3.json("/assets/json/mise.json", function(error, root) {
      var nodes = tree.nodes(root),
          links = tree.links(nodes);

      var link = svg02.selectAll(".link")
          .data(links)
        .enter().append("path")
          .attr("stroke","white")
          .attr("stroke-width", 3)
         .style("fill",function(){return selectedFillAttr();})
          .attr("class", "link")
          .attr("d", diagonal);

      var node = svg02.selectAll(".node")
          .data(nodes)
        .enter().append("g")
          .attr("class", "node")
          .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })

      node.append("circle")
          .attr("r", function(d){return (10 - d.depth * 2) < 4 ? 4 : (10 - d.depth * 2);})
          .attr("stroke","red")
          .attr("stroke-width", function(d){ return (3 - d.depth)===0 ? 1 : (3 - d.depth) })
          .style("fill","lime");

      node.append("text")
          .attr("dx", function(d) { return d.children ? -8 : 8; })
          .attr("dy", 3)
          .style("text-anchor", function(d) { return d.children ? "end" : "start"; })
          .text(function(d) { return d.name; })
          .style("fill","yellow");
    });
 
  };
};

// Activates knockout.js
ko.applyBindings(new AppViewModel());