2013-11-15 58 views
0

我正在將rect和文本添加到svg中。不過,我只想在空時添加。它不應該被添加多次。d3.js如何僅在尚未添加時添加rect

<!DOCTYPE html> 

<style></style> 

<header> 
</header> 

<h1>Legends Data</h1> 

<p id="legend"></p> 

<input type="submit" value="Generatelegend" onclick=CreateLegend();> 

<script src="http://d3js.org/d3.v2.js?2.8.1"></script> 

<script> 

    function CreateLegend() 
{ 

    var margin = {top: 29.5, right: 29.5, bottom: 29.5, left: 59.5}, 
    width = 460 - margin.right, 
    height = 200 - margin.top - margin.bottom; 


    //Create the SVG for legends. 
    var svglegend = d3.select("#legend").append("svg").attr("id","svglegend") 
    .attr("width", width) 
     .attr("height", height) 
    .append("g") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

     //check svg exists 



    // Create the SVG container and set the origin. 
    var svg = d3.select("#chart").append("svg") 
    .attr("width", width + margin.left + margin.right) 
     .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 



    d3.json("SbuLegendData.json", function(data) { 

    jsondata = data; 


     //CreateLegend('legend', svglegend); 
     rectangle= svglegend.selectAll("rect").data(data).enter().append("rect"); 
     var RectangleAttrb = rectangle.attr("x", function (d) { return d.x_axis; }) 
         .attr("y", function (d) { return d.y_axis; }) 
         .attr("width",function(d) { return d.width; }) 
        .attr("height",function(d) { return d.height; }) 
         .style("fill", function(d) { return d.color; }); 




    var textparam = svglegend.selectAll("text").data(data).enter().append("text"); 

     var text = textparam .attr("x", function (d) { return d.x_axis + d.width +10; }) 
         .attr("y", function (d) { return d.y_axis + d.height-5; }) 
         .attr("width",30) 
        .attr("height",20) 
         .text(function(d) { return d.text; }); 


    }); 
} 

</script> 

現在在這個函數中它會一直在調用函數時添加rect和text。

[ 
    { "x_axis":40, "y_axis": 10,"width":50,"height":20,"color" : "#1f77b4","text":"F&R"}, 
    { "x_axis":40, "y_axis": 30,"width":50,"height":20,"color" : "#ff7f0e","text":"Legal"}, 
    { "x_axis":40, "y_axis": 50,"width":50,"height":20,"color" : "#2ca02c","text":"GGO"}, 
    { "x_axis":40, "y_axis": 70,"width":50,"height":20,"color" : "#d62728","text":"IP&S"}, 
    { "x_axis":40, "y_axis": 90,"width":50,"height":20,"color" : "#9467bd","text":"CORP"}, 
    { "x_axis":40, "y_axis": 110,"width":50,"height":20,"color": "#8c564b","text":"TAX"}, 
    { "x_axis":40, "y_axis": 130,"width":50,"height":20,"color" : "#e377c2","text":"REUTERS ALL"} 
] 
+0

你傳遞給這個函數的數據是什麼?你能創建一個'jsfiddle'的獨立例子並重現問題嗎? –

回答

2

當使用D3的數據模式來告訴它什麼要與數據匹配時,您需要選擇相同類型的元素。也就是說,你應該運行

rectangle = svg.selectAll("rect").data(data).enter().append("rect"); 

這將告訴D3尋找rect元素(.selectAll("rect")),匹配data他們(.data(data)),和追加對那些沒有被匹配新rect元素(.enter().append("rect")) 。

您當前的代碼不允許D3正確匹配數據和元素,因爲您將錯誤的事情傳遞給.selectAll()。您需要稍後對text元素進行相同的更改。

另外,您總是在CreateLegend函數中添加新的SVG,然後使用它們來設置圖例。這意味着每次調用函數時都會添加新的圖例,而不管已經存在的是什麼。您可以通過將創建SVG的代碼移到該函數之外來輕鬆解決此問題。

完整示例here

+0

我做了同樣的事情,但它附加了矩形。我將代碼修改爲rectangle = svg.selectAll(「rect」).data(data).enter()。append(「rect」); 而不是矩形= svg.selectAll(div).data(data).enter()。append(「rect」); –

+0

請您發佈一個完整的工作示例嗎? –

+0

更新了工作拷貝lars –