前端用D3.js繪製縱向流程圖(可摺疊,拖動,縮放)

 前端使用D3.JS繪製縱向流程圖(樹圖)(可節點摺疊,樹圖拖動,縮放)



// ************** Generate the tree diagram  *****************
//定義樹圖的全局屬性(寬高)
var margin = {top: 50, right: 20, bottom: 20, left: 20},
    width = 1600 - margin.right - margin.left,
    height = 1600 - 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.x, d.y]; });//創建新的斜線生成器


// Setup zoom and pan
var zoom = d3.behavior.zoom()
    .scaleExtent([.1,1])
    .on('zoom', function(){
        svg.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")");
});

//聲明與定義畫布屬性
var svg = d3.select("body").append("svg")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
    .call(zoom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

root = treeData[0];//treeData爲上邊定義的節點屬性
root.x0 = height / 2;
root.y0 = 0;

update(root);

d3.select(self.frameElement).style("height", "1600px");

function update(source) {

  // Compute the new tree layout.計算新樹圖的佈局
  var nodes = tree.nodes(root).reverse(),
      links = tree.links(nodes);

  // Normalize for fixed-depth.設置y座標點,每層佔180px
  nodes.forEach(function(d) { d.y = d.depth * 180; });

  // Update the nodes…每個node對應一個group
  var node = svg.selectAll("g.node")
      .data(nodes, function(d) { return d.id || (d.id = ++i); });//data():綁定一個數組到選擇集上,數組的各項值分別與選擇集的各元素綁定

  // Enter any new nodes at the parent's previous position.新增節點數據集,設置位置
  var nodeEnter = node.enter().append("g")  //在 svg 中添加一個g,g是 svg 中的一個屬性,是 group 的意思,它表示一組什麼東西,如一組 lines , rects ,circles 其實座標軸就是由這些東西構成的。
      .attr("class", "node") //attr設置html屬性,style設置css屬性
      .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" : "#357CAE"; });//d 代表數據,也就是與某元素綁定的數據。
  nodeEnter.append("rect")
    .attr("x",-30)
    .attr("y", -10)
    .attr("width",100)
    .attr("height",30)
    .attr("rx",10)
      .style("fill", "#dff0e7");//d 代表數據,也就是與某元素綁定的數據。// 小方塊的背景顏色綠色

  nodeEnter.append("text")
    .attr("x", function(d) { return d.children || d._children ? 13 : 13; })
    .attr("dy", "10")
    .attr("text-anchor", "middle")
    .text(function(d) { return d.name; })
    .style("fill", "#2dbb8a")
    .style("fill-opacity", 1);
  // Transition nodes to their new position.將節點過渡到一個新的位置-----主要是針對節點過渡過程中的過渡效果
  //node就是保留的數據集,爲原來數據的圖形添加過渡動畫。首先是整個組的位置
  var nodeUpdate = node.transition()  //開始一個動畫過渡
      .duration(duration)  //過渡延遲時間,此處主要設置的是圓圈節點隨斜線的過渡延遲
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });//YES


  // Transition exiting nodes to the parent's new position.過渡現有的節點到父母的新位置。
  //最後處理消失的數據,添加消失動畫
  var nodeExit = node.exit().transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + source.x + "," + source.y + ")"; })//YES
      .remove();

  // Update the links…線操作相關

  //再處理連線集合
  var link = svg.selectAll("path.link")
      .data(links, function(d) { return d.target.id; });


  // Enter any new links at the parent's previous position.
  //添加新的連線
  link.enter().insert("path", "g")
      .attr("class", "link")
      .attr("d", function(d) {
        var o = {y: source.x0, x: source.y0};//YES
        return diagonal({source: o, target: o});  //diagonal - 生成一個二維貝塞爾連接器, 用於節點連接圖.
      })
    .attr('marker-end', 'url(#arrow)');

  // 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};//NO
        return diagonal({source: o, target: o});
      })
      .remove();

  // Stash the old positions for transition.將舊的斜線過渡效果隱藏
  nodes.forEach(function(d) {
    d.x0 = d.y;
    d.y0 = d.x;
  });
}

//定義一個將某節點摺疊的函數
// Toggle children on click.切換子節點事件
function click(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
  update(d);
}

</script>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章