2017-01-02 63 views
0

我對D3很新,我不明白它的所有邏輯。如何動態更新d3包

我嘗試使用的例子,但它似乎是這麼多的方式做的事情,它混淆了我...

無論如何,我儘量讓這個example動態。

這裏是我現在所擁有的代碼:

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 

text { 
    font: 12px sans-serif; 
    text-anchor: middle; 
} 
.titre { 
    font-size: 18px; 
} 

.node--hover circle { 
    stroke: #000; 
    stroke-width: 1.2px; 
} 
#csv { 
    float: left; 
} 
</style> 
<form> 
    <textarea name="csv" id="csv" cols="50" rows="30">id,taille,titre 
D3, 
D3.one,2000 
D3.two,2000</textarea> 
</form> 
<svg width="400" height="400"><g transform="translate(1,1)"></g></svg> 
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script> 
<script src="https://d3js.org/d3.v4.min.js"></script> 
<script> 

var svg = d3.select("svg"), 
    width = +svg.attr("width"), 
    height = +svg.attr("height"); 

var format = d3.format(",d"); 

    var color = d3.scaleSequential(d3.interpolateMagma) 
     .domain([-4, 4]); 
    var stratify = d3.stratify() 
     .parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); }); 
    var pack = d3.pack() 
     .size([width - 2, height - 2]) 
     .padding(3); 

    var csv = $("#csv").val(); 

    data = d3.csvParse(csv); 

     var root = stratify(data) 
      .sum(function(d) { return d.taille; }) 
      .sort(function(a, b) { return b.taille - a.taille; }); 

     pack(root); 

     var node = svg.select("g") 
     .selectAll("g") 
     .data(root.descendants()) 
     .enter().append("g") 
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) 
      .attr("class", function(d) { return "node" + (!d.children ? " node--leaf" : d.depth ? "" : " node--root"); }) 
      .each(function(d) { d.node = this; }); 


     node.append("circle") 
      .attr("id", function(d) { return "node-" + d.id; }) 
      .attr("r", function(d) { return d.r; }) 
      .style("fill", function(d) { 
       return color(d.depth); 
      }); 

     var leaf = node.filter(function(d) { return !d.children; }); 

     leaf.append("clipPath") 
      .attr("id", function(d) { return "clip-" + d.id; }) 
     .append("use") 
      .attr("xlink:href", function(d) { return "#node-" + d.id + ""; }); 

     leaf.append("text") 
      .attr("clip-path", function(d) { return "url(#clip-" + d.id + ")"; }).attr("class", function(d) { return d.data.titre=="1" ? "titre" : ""}) 
     .selectAll("tspan") 
     .data(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1).split(/(?=[A-Z][^A-Z])/g); }) 
     .enter().append("tspan") 
      .attr("x", 0) 
      .attr("y", function(d, i, nodes) { return 13 + (i - nodes.length/2 - 0.5) * 20; }) 
      .text(function(d) { return d; }); 

$(function() { 
    $("#csv").blur(function() 
    { 
     update(); 
    }); 
}); 

function update() 
{ 
    var csv = $("#csv").val(); 

    data = d3.csvParse(csv); 

     var root = stratify(data) 
      .sum(function(d) { return d.taille; }) 
      .sort(function(a, b) { return b.taille - a.taille; }); 

     pack(root); 

    //console.log(root.descendants()); 
     node = node.data(root.descendants(), function(d) {return d}); 
     console.log(node); 
     //node.exit().remove(); 
     node.enter().append("g") 
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) 
      .attr("class", function(d) { return "node" + (!d.children ? " node--leaf" : d.depth ? "" : " node--root"); }) 
      .each(function(d) { d.node = this; }); 

     node.append("circle") 
      .attr("id", function(d) { return "node-" + d.id; }) 
      .attr("r", function(d) { return d.r; }) 
      .style("fill", function(d) { 
       return color(d.depth); 
      }); 

     var leaf = node.filter(function(d) { return !d.children; }); 

     leaf.append("clipPath") 
      .attr("id", function(d) { return "clip-" + d.id; }) 
     .append("use") 
      .attr("xlink:href", function(d) { return "#node-" + d.id + ""; }); 

     leaf.append("text") 
      .attr("clip-path", function(d) { return "url(#clip-" + d.id + ")"; }).attr("class", function(d) { return d.data.titre=="1" ? "titre" : ""}) 
     .selectAll("tspan") 
     .data(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1).split(/(?=[A-Z][^A-Z])/g); }) 
     .enter().append("tspan") 
      .attr("x", 0) 
      .attr("y", function(d, i, nodes) { return 13 + (i - nodes.length/2 - 0.5) * 20; }) 
      .text(function(d) { return d; }); 
} 



</script> 

您可以測試它bl.ocks: https://bl.ocks.org/matthieubrunet/79ef9968e2eaaba7f0718a373d240025

更新應該在模糊的情況發生。

我認爲我的問題是圍繞輸入函數(在更新函數中),它返回所有元素,而不是僅返回新元素。

正如你可以看到的,我評論了出口,因爲它刪除了所有孩子圈子。

非常感謝

回答

2

其中最令人困惑的事情d3是如何處理enterupdateexit模式。我不會爲你提供教程,因爲那裏有很多很好的資源already - out我花時間重新因數您update功能,妥善處理情況:

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 
<style> 
 
    text { 
 
    font: 12px sans-serif; 
 
    text-anchor: middle; 
 
    } 
 
    
 
    .titre { 
 
    font-size: 18px; 
 
    } 
 
    
 
    .node--hover circle { 
 
    stroke: #000; 
 
    stroke-width: 1.2px; 
 
    } 
 
    
 
    #csv { 
 
    float: left; 
 
    } 
 
</style> 
 
<form> 
 
<textarea name="csv" id="csv" cols="50" rows="30">id,taille,titre 
 
D3, 
 
D3.one,2000 
 
D3.two,2000</textarea> 
 
</form> 
 
<svg width="400" height="400"> 
 
    <g transform="translate(1,1)"></g> 
 
</svg> 
 
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script> 
 
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<script> 
 
    var svg = d3.select("svg"), 
 
    width = +svg.attr("width"), 
 
    height = +svg.attr("height"); 
 

 
    var format = d3.format(",d"); 
 

 
    var color = d3.scaleSequential(d3.interpolateMagma) 
 
    .domain([-4, 4]); 
 
    var stratify = d3.stratify() 
 
    .parentId(function(d) { 
 
     return d.id.substring(0, d.id.lastIndexOf(".")); 
 
    }); 
 
    var pack = d3.pack() 
 
    .size([width - 2, height - 2]) 
 
    .padding(3); 
 

 
    update(); 
 

 
    $(function() { 
 
    $("#csv").blur(function() { 
 
     update(); 
 
    }); 
 
    }); 
 

 
    function update() { 
 
    var csv = $("#csv").val(); 
 

 
    data = d3.csvParse(csv); 
 

 
    var root = stratify(data) 
 
     .sum(function(d) { 
 
     return d.taille; 
 
     }) 
 
     .sort(function(a, b) { 
 
     return b.taille - a.taille; 
 
     }); 
 

 
    pack(root); 
 
    
 
    // data-binding 
 
    var node = svg.selectAll(".node").data(root.descendants(), function(d){ 
 
     return d; 
 
    }); 
 
    
 
    // exiting nodes 
 
    node.exit().remove(); 
 

 
    // entering nodes 
 
    var nodeEnter = node.enter().append("g") 
 
     .attr("class", function(d) { 
 
     return "node" + (!d.children ? " node--leaf" : d.depth ? "" : " node--root"); 
 
     }); 
 
     
 
    // add circles 
 
    nodeEnter.append("circle") 
 
     .attr("id", function(d) { 
 
     return "node-" + d.id; 
 
    }); 
 
    
 
    // update + enter 
 
    node = nodeEnter.merge(node); 
 
     
 
    // position everyone 
 
    node.attr("transform", function(d) { 
 
     return "translate(" + d.x + "," + d.y + ")"; 
 
    }); 
 
    
 
    // update circles 
 
    node.select("circle") 
 
     .attr("r", function(d) { 
 
     return d.r; 
 
     }) 
 
     .style("fill", function(d) { 
 
     return color(d.depth); 
 
     }); 
 
    
 
    // handle enter of leafs 
 
    var leafEnter = nodeEnter.filter(function(d) { 
 
     return !d.children; 
 
    }); 
 
    
 
    leafEnter.append("clipPath") 
 
     .attr("id", function(d) { 
 
     return "clip-" + d.id; 
 
     }) 
 
     .append("use") 
 
     .attr("xlink:href", function(d) { 
 
     return "#node-" + d.id + ""; 
 
     }); 
 
     
 
    leafEnter.append("text") 
 
     .attr("clip-path", function(d) { 
 
     return "url(#clip-" + d.id + ")"; 
 
     }).attr("class", function(d) { 
 
     return d.data.titre == "1" ? "titre" : ""; 
 
     }); 
 

 
    node.select("text") 
 
     .selectAll("tspan") 
 
     .data(function(d) { 
 
     return d.id.substring(d.id.lastIndexOf(".") + 1).split(/(?=[A-Z][^A-Z])/g); 
 
     }) 
 
     .enter().append("tspan") 
 
     .attr("x", 0) 
 
     .attr("y", function(d, i, nodes) { 
 
     return 13 + (i - nodes.length/2 - 0.5) * 20; 
 
     }) 
 
     .text(function(d) { 
 
     return d; 
 
     }); 
 
    } 
 
</script>

+0

非常感謝!更新確實有效,但多行文本停止工作。您可以在原始示例中看到它的工作原理:http://bl.ocks.org/mbostock/ca5b03a33affa4160321。我嘗試看代碼,但無法弄清楚什麼是錯的... – Matthieu

+0

@Matthieu,[它仍然適用於我](http://imgur.com/a/GXu6J) – Mark

+0

好吧,我只是明白它包裹在每個首都上,而不是每個單詞......再次感謝! – Matthieu