【D3.js数据可视化系列教程】(二十九)--折叠树

来源:互联网 发布:php页面静态化技术 编辑:程序博客网 时间:2024/06/05 14:38

 折叠

  

 展开

children和_children

 

(1)折叠函数

递归调用,有子孙的就把children(显示)给_children(不显示),便于折叠,

  function collapse(d) {    if (d.children) {  console.log(d);      d._children = d.children;      d._children.forEach(collapse);      d.children = null;    }  }//折叠根节点的每个孩子  root.children.forEach(collapse);  //折叠之后要更新    update(root);

(2)根据交互的情况更新布局并输出

function update(source) {  // (2-1)计算新树的布局,默认只有根节点,点击之后就是对应节点  var nodes = tree.nodes(root).reverse(),      links = tree.links(nodes);  //(2-2)树的深度归一 没有归一处理的话所有最终节点到根节点的水平距离相同了  //这里树d.y最大720要分四层,所以每层就乘180,平均化每层的最大水平位置  nodes.forEach(function(d) {     d.y = d.depth * 180;   });  //(2-3)更新节点id,默认只有根节点,点击之后就是对应节点,也就是只有子节点显示(默认显示根得,点击显示被点击的)  var node = svg.selectAll("g.node")      .data(nodes, function(d) {    return d.id //最初新点开的节点都没有id,分配之后就有了     || (d.id = ++i); //为没有id的节点添加上ID   });  // (2-4)点击时增加子节点  var nodeEnter = node.enter().append("g")      .attr("class", "node")      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })      .on("click", click);  nodeEnter.append("circle")      .attr("r", 1e-6)      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });  nodeEnter.append("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);  //(2-5)过渡到新位置  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);  // (2-6)转换被点击节点之外的节点到新位置  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);  // (2-7)更新链接  var link = svg.selectAll("path.link")      .data(links, function(d) { return d.target.id; });//对应子节点为目标节点  // (2-8)增加链接  link.enter().insert("path", "g")      .attr("class", "link")      .attr("d", function(d) {        var o = {x: source.x0, y: source.y0};        return diagonal({source: o, target: o});      });  // (2-9)过渡链接  link.transition()      .duration(duration)      .attr("d", diagonal);  // (2-10)过渡其他链接.  link.exit().transition()      .duration(duration)      .attr("d", function(d) {        var o = {x: source.x, y: source.y};        return diagonal({source: o, target: o});      })      .remove();  // 把旧位置存下来,用以过渡  nodes.forEach(function(d) {    d.x0 = d.x;    d.y0 = d.y;  });}

(3)切换折叠与否

function click(d) {  if (d.children) {    d._children = d.children;    d.children = null;  } else {    d.children = d._children;    d._children = null;  }  update(d);//要更新}

<!DOCTYPE html><html>  <head><meta charset="utf-8"><title>testD3-26-CollapsibleTree.html</title><script type="text/javascript" src="http://localhost:8080/spring/js/d3.v3.js"></script><style>.node circle {  fill:yellow ;  stroke: red;  stroke-width: 1.5px;}.node {  font: 10px sans-serif ;}.link {  fill: green;  stroke: #ccc;  stroke-width: 1.5px;}</style></head><body><script type="text/javascript">//位置参数var margin = {top: 20, right: 120, bottom: 20, left: 120},    width = 960 - margin.right - margin.left,    height = 800 - margin.top - margin.bottom;    var i = 0,    duration = 750,    root;// 声明树布局var tree = d3.layout.tree()    .size([height, width]);// 指定为径向布局var diagonal = d3.svg.diagonal()    .projection(function(d) { return [d.y, d.x]; });var svg = d3.select("body").append("svg")    .attr("width", width + margin.right + margin.left)    .attr("height", height + margin.top + margin.bottom)  .append("g")    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");d3.json("http://localhost:8080/spring/D3data/flare.json", function(error, flare) { //根节点和位置  root = flare;  root.x0 = height / 2;  root.y0 = 0;//(1)折叠函数,递归调用,有子孙的就把children(显示)给_children(不显示),便于折叠,  function collapse(d) {    if (d.children) {  console.log(d);      d._children = d.children;      d._children.forEach(collapse);      d.children = null;    }  }//折叠根节点的每个孩子  root.children.forEach(collapse);  //折叠之后要更新    update(root);});//(2)根据交互的情况更新布局并输出function update(source) {  // (2-1)计算新树的布局,默认只有根节点,点击之后就是对应节点  var nodes = tree.nodes(root).reverse(),      links = tree.links(nodes);  //(2-2)树的深度归一 没有归一处理的话所有最终节点到根节点的水平距离相同了  //这里树d.y最大720要分四层,所以每层就乘180,平均化每层的最大水平位置  nodes.forEach(function(d) {   d.y = d.depth * 180;   });  //(2-3)更新节点id,默认只有根节点,点击之后就是对应节点,也就是只有子节点显示(默认显示根得,点击显示被点击的)  var node = svg.selectAll("g.node")      .data(nodes, function(d) {return d.id //最初新点开的节点都没有id,分配之后就有了 || (d.id = ++i); //为没有id的节点添加上ID});  // (2-4)点击时增加子节点  var nodeEnter = node.enter().append("g")      .attr("class", "node")      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })      .on("click", click);  nodeEnter.append("circle")      .attr("r", 1e-6)      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });  nodeEnter.append("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);  //(2-5)过渡到新位置  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);  // (2-6)转换被点击节点之外的节点到新位置  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);  // (2-7)更新链接  var link = svg.selectAll("path.link")      .data(links, function(d) { return d.target.id; });//对应子节点为目标节点  // (2-8)增加链接  link.enter().insert("path", "g")      .attr("class", "link")      .attr("d", function(d) {        var o = {x: source.x0, y: source.y0};        return diagonal({source: o, target: o});      });  // (2-9)过渡链接  link.transition()      .duration(duration)      .attr("d", diagonal);  // (2-10)过渡其他链接.  link.exit().transition()      .duration(duration)      .attr("d", function(d) {        var o = {x: source.x, y: source.y};        return diagonal({source: o, target: o});      })      .remove();  // 把旧位置存下来,用以过渡  nodes.forEach(function(d) {    d.x0 = d.x;    d.y0 = d.y;  });}//(3)切换折叠与否function click(d) {  if (d.children) {    d._children = d.children;    d.children = null;  } else {    d.children = d._children;    d._children = null;  }  update(d);//要更新}</script></body></html>


 

 

 
原创粉丝点击