d3.js-在svg中添加从json文件读取的矩形 [英] d3.js - adding rectangles reading from json file in a svg
问题描述
我在svg上添加了图例(通过矩形).从每个图例组的不同json文件中读取数据.我想在相同的svg中绘制矩形.但是,仅添加了一组图例.仅第一个json数据绘制为矩形.第二个被忽略.
I am adding legends(through rectangles) on a svg. The data is read from different json files for each group of legend. I would like to draw the rectangles in the same svg. However only one set of legend is being added. Only the first json data is drawn as rectangles. The second is ignored.
我的代码是:
svgcheckins= d3.select("#legend").append("svg").attr("id","svgcheckins")
.attr("width", 250)
.attr("height", 200)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("checkins.json", function(data)
{
CreateLegend('#legend',svgcheckins,"checkins",data,'A - Checkins','');
});
d3.json("builds.json", function(data)
{
CreateLegend('#legend',svgcheckins,"Builds",data,'B - Builds','');
});
function CreateLegend(div,svg,svgid,data,header,trail)
{
var traillength=0;
var svgelem;
jsondata = data;
console.log(data);
rectangle= svg.selectAll("rect").data(data).enter().append("rect");
var RectangleAttrb = rectangle
.attr("id", function (d,i) { return svgid + "id" + i ; })
.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("stroke", function (d) { return d.border;})
.style("fill", function(d) { return d.color; });
var textparam = svg.selectAll("text").data(data).enter().append("text");
var yearheader = d3.select("#header");
if(yearheader.empty())
{
var textheader = svg.append("text").attr("dx",20).attr("dy",5).text(header).attr("id",header).attr("style","margin-bottom:21px;border-bottom: solid 2px #ffd97f; font-size:12px;")
}
if (trail.length == 0)
{
d3.select(header).attr("style","font-size:15.1px;text-decoration:underline");
}
var text = textparam .attr("x", function (d) { traillength = d.x_axis + d.width +10; return d.x_axis + d.width +10; })
.attr("y", function (d) { return d.y_axis + d.height-5; })
.attr("width",30 )
.attr("height",20)
.attr("style", "text-decoration:none")
.text(function(d) { return d.text; });
var yearheader = d3.select("#trail");
if (trail.length > 0 && yearheader.empty() )
{
svg.append("text").attr("id","trail").attr("dx",traillength-10).attr("dy",5).text(trail).attr("style","margin-bottom:21px;border-bottom: solid 2px #ffd97f; font-size:12px;" )
}
}
json数据为:
checkins.json
[
{ "x_axis":10, "y_axis": 10,"width":20,"height":15,"color" : "#FE2E2E","border":"#000000"},
{ "x_axis":30, "y_axis": 10,"width":20,"height":15,"color" : "#FE9A2E","border":"#000000"},
{ "x_axis":50, "y_axis": 10,"width":20,"height":15,"color" : "#FFFF00","border":"#000000"},
{ "x_axis":70, "y_axis":10,"width":20,"height":15,"color" : "#D0FA58","border":"#000000"},
{ "x_axis":90, "y_axis":10,"width":20,"height":15,"color" : "#01DF01","border":"#000000"}
]
builds.json
[
{ "x_axis":10, "y_axis":60,"width":20,"height":15,"color" : "#424242","border":"#000000"},
{ "x_axis":30, "y_axis":60,"width":20,"height":15,"color" : "#D8D8D8","border":"#000000"},
{ "x_axis":50, "y_axis":60,"width":20,"height":15,"color" : "#FFFF00","border":"#000000"},
{ "x_axis":70, "y_axis":60,"width":20,"height":15,"color" : "#FAFAFA","border":"#000000"},
{ "x_axis":90, "y_axis":60,"width":20,"height":15,"color" : "#81DAF5","border":"#000000"}
]
推荐答案
这是因为D3的数据匹配是如何工作的.特别是,我指的是以下行:
This is because of how D3's data matching work. In particular, I'm referring to the following line:
rectangle= svg.selectAll("rect").data(data).enter().append("rect");
这将选择所有rect
元素并将data
与其匹配.对于第一个图例,没有rect
,因此没有任何匹配项,它可以按您期望的方式工作.但是,如果已经有rect
,它将与data
匹配,并且您的输入选择为空.这是因为D3默认情况下会根据数组索引进行匹配.
This selects all rect
elements and matches data
to them. For the first legend, no rect
s are there, so nothing is matched and it works as you expect. However, if there's a rect
already, it is matched to data
and your enter selection is empty. This is because D3 matches based on array index by default.
基本上有两种方法可以解决此问题.您可以使用.data()
的第二个可选参数来告诉D3如何匹配,或者将一个区分类分配给要在.selectAll()
中使用的图例.您的数据似乎没有任何区别属性,但是您可以为此使用svgid
:
There are basically two ways around this. You could either use the optional second argument to .data()
to tell D3 how to match, or assign a distinguishing class to the created legend to be used in the .selectAll()
. Your data doesn't seem to have any distinguishing attributes in it, but you can use svgid
for this purpose:
rectangle= svg.selectAll("rect." + svgid).data(data).enter().append("rect");
rectangle.attr("class", svgid);
// rest of code
这篇关于d3.js-在svg中添加从json文件读取的矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!