在Observable中,我有一个名为dataByHub的Map,目前看起来像:
"ST" => Array(19) [Object, Object, Object ...]
"FING" => Array(27) [Object, Object, Object ...]
我正在尝试迭代密钥(是ST、FING密钥吗?不确定命名法…(
d3.select("#hubs").selectAll(".hub")
.data(dataByHub)
.enter().append("g")
.attr("class", "hub")
.attr("id", (d,i) => d[i])
我想要:
<g class="hub" id="ST"></g>
<g class="hub" id="FING"></g>
我得到的结果是:
<g class="hub" id="ST"></g>
<g class="hub" id="[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"></g>
我怎样才能得到我想要的结果?
额外奖励:我如何在a=>迭代它们并使用对象的值?
您需要Map中每个键值对的键(您是对的,这是正确的命名法(。因此,您只需要为每个条目(即数据d
(使用索引0
即可获得其密钥:
.attr("id", d => d[0]);
这是演示:。
const svg = d3.select("svg");
const dataByHub = new Map();
dataByHub.set("ST", [1, 2, 3, 4, 5]);
dataByHub.set("FING", [6, 7, 8, 9, 10]);
svg.selectAll(null)
.data(dataByHub)
.enter()
.append("g")
.attr("class", "hub")
.attr("id", d => d[0]);
var mySVG = (new XMLSerializer()).serializeToString(svg.node());
console.log(mySVG)
<script src="https://d3js.org/d3.v6.min.js"></script>
<svg></svg>
作为额外的解释,值得一提的是,D3data
方法在内部使用Array.from
用于映射、集合和字符串。这就是为什么每个数据(d
(都是一个数组,原始Map键作为索引0
处的元素,原始Map值作为索引1
:处的元素
const dataByHub = new Map();
dataByHub.set("ST", [1, 2, 3, 4, 5]);
dataByHub.set("FING", [6, 7, 8, 9, 10]);
console.log(Array.from(dataByHub))
还值得一提的是,由于v6(我们现在在v7中(,D3接受迭代,如Maps和Sets。
您可以使用dataByHub.keys()
设置g
元素的id
:
const data = [
{hub: "ST", Xs: [1, 2]},
{hub: "FING", Xs: [2, 3]},
{hub: "ST", Xs: [3, 4]},
{hub: "FING", Xs: [4, 5]},
{hub: "ST", Xs: [5, 6]},
{hub: "FING", Xs: [6, 7]},
{hub: "ST", Xs: [7, 8]},
];
const dataByHub = d3.group(data, d => d.hub);
const svg = d3.select("svg");
const hubs = svg.selectAll(".hubs")
.data(dataByHub.keys())
.enter()
.append("g")
.attr("class", "hub")
.attr("id", d => d)
hubs.append("rect")
.attr("width", 160)
.attr("height", 140)
.attr("transform", (d, i) => `translate(${(i * 180) + 20}, 20)`);
hubs.append("text")
.text(d => `I am rect in ${d} <g>`)
.attr("x", (d, i) => (i * 180) + 25)
.attr("y", 90)
.attr("fill", "blue");
svg {
background: lightblue;
}
g.hub rect {
fill: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>
<svg width=380 height=180></svg>