在箭头函数中解决 JS ES6 Map

Address JS ES6 Map in arrow functions

Observable 中,我有一个名为 dataByHub 的地图,目前看起来像:

"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 的键中寻址对象以迭代它们并使用对象的值?

您可以使用 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>

您想要 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>

作为补充说明,值得一提的是 D3 data 方法在内部对映射、集合和字符串使用 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。