gpt4 book ai didi

javascript - 额外传奇礼物

转载 作者:行者123 更新时间:2023-12-02 22:38:26 25 4
gpt4 key购买 nike

我在条形图中添加了两个图例,但我不知道为什么会出现一个额外的图例。我不知道我的代码的哪一部分是错误的,因为我只在代码中定义了两个图例。

var color_hash = {  0 : ["Male", "blue"],
1 : ["Female", "pink"]}

var legend = svg.append("g")
.attr("class", "legend")
.attr("x", width - 65)
.attr("y", 25)
.attr("height", 100)
.attr("width", 100);

legend.selectAll('g').data(data)
.enter()
.append('g')
.each(function(d, i) {
var g = d3.select(this);
g.append("rect")
.attr("x", width - 65)
.attr("y", i*25)
.attr("width", 10)
.attr("height", 10)
.style("fill", color_hash[String(i)][1]);
g.append("text")
.attr("x", width - 50)
.attr("y", i * 25 + 8)
.attr("height", 30)
.attr("width", 100)
.style("fill", color_hash[String(i)[1]])
.text(color_hash[String(i)][0]);

});

黑色矩形是多余的:

enter image description here

最佳答案

通过 D3 中的进入/更新/退出循环,您通常希望有一个数据数组,其中包含您想要绘制的每个元素的一项。你有:

  • 颜色有对象color_hash这是您真正想要用来绘制图例的对象,并且
  • 一些数据数组data,尽管我们不知道里面有什么。

我们使用data来可视化color_hash,这并不理想。

例如,您只想绘制 2 个元素,我可以告诉您 data 的长度至少为 3:

您创建一个空的g:

var legend = svg.append("g")

然后选择其中的子 g 元素:

legend.selectAll('g')

由于没有,所以这是一个空选择。然后将数据分配给该选择并输入新的 HTML/SVG 元素:

legend.selectAll('g')
.data(data)
.enter()
.append('g')

由于 legend 是一个空选择,因此输入选择将为数据数组中的每一项创建一个 HTML/SVG 元素。进入(和/或退出)后,HTML/SVG 元素的数量应等于数据数组中的项目数量。因此,data 中必须至少有 3 个项目(如果创建了额外的元素,它可能会有更多的项目,但它们超出了 SVG/容器的范围。这也解释了为什么第三个框没有颜色或文本:颜色散列没有键为 2 或更大的值)。

D3是根据数据创建元素,通常元素和项目之间是一对一的关系。要创建我们的图例,数据数组应该是我们想要绘制的。因此,我们需要将颜色哈希转换为数组:

var legendData = [
{name: "A", color:"crimson"},
{name: "B", color:"steelblue"}
];

现在我们只需将其提供给 selection.data()

而且,由于我们现在将要绘制的数据绑定(bind)到图例条目,因此我们还可以简化代码,而不是:

 .style("fill", color_hash[String(i)][1]);

 .text(color_hash[String(i)][0]);

我们可以使用:

  .style("fill",d.color);

  .text(d.name);

这给了我们:

var color_hash = {  0 : ["Male", "blue"],
1 : ["Female", "pink"]}

var width = 300;
var height = 200;

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

var legendData = [
{name:"A",color:"crimson"},
{name:"B",color:"steelblue"}
]

var legend = svg.append("g")

legend.selectAll('g')
.data(legendData)
.enter()
.append('g')
.each(function(d, i) {
var g = d3.select(this);
g.append("rect")
.attr("x", width - 65)
.attr("y", i*25+25)
.attr("width", 10)
.attr("height", 10)
.style("fill", d.color);
g.append("text")
.attr("x", width - 50)
.attr("y", i * 25 + 33)
.attr("height", 30)
.attr("width", 100)
.style("fill", d.color)
.text(d.name);

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>

我在这里只关注输入周期:可能会对放置进行进一步修改,并且与使用 .each 附加子项相比,不同的嵌套附加方法可以带来好处

关于javascript - 额外传奇礼物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58666452/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com