我正在为svg添加rect和text。但是我想只在空的时候添加。它不应该多次添加。
<!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 :(得分: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设置图例。这意味着每次调用函数时都会添加新的图例,而不管已存在的是什么。您可以通过在函数外部移动创建SVG的代码来轻松解决此问题。
完整示例here。