D3.js erGroups=g.selectAll('g.layer')。数据(嵌套); layerGroups=layerGroups.enter().append('g').attr('class','layer')) .合并(图层组); layerGroups.each(函数(layerEntry,j){ 常量圆=选择(此) .selectAll('circle')。数据(layerry.values); circles.enter().append('circle') .合并(圆) .attr('cx',d=>xScale(xValue(d))) .attr('cy',d=>yScale(y值(d))) .attr('r',d=>radiuscale(radiusValue(d))) .attr('fill',j==0?'white':'black');//

D3.js erGroups=g.selectAll('g.layer')。数据(嵌套); layerGroups=layerGroups.enter().append('g').attr('class','layer')) .合并(图层组); layerGroups.each(函数(layerEntry,j){ 常量圆=选择(此) .selectAll('circle')。数据(layerry.values); circles.enter().append('circle') .合并(圆) .attr('cx',d=>xScale(xValue(d))) .attr('cy',d=>yScale(y值(d))) .attr('r',d=>radiuscale(radiusValue(d))) .attr('fill',j==0?'white':'black');//,d3.js,D3.js,我的解决方案是将此信息嵌入提供给d3js的数据中 data=[[1,2,3]、[4,5,6]、[7,8,9]] 扁平化数据=数据减少((acc,v,i)=>{ v、 forEach((d,j)=>{ 数据项={i,j,d}; acc.push(数据项); }); 返回acc; }, []); 然后可以从函数的数据arg访问i、j和d td.text(函数(d){ //可以在此处访问i、j和原始数据 返回“行”:+d.j; }); 我没有看到这个问题,所以谢谢你指出。使用.each()来规避这个

我的解决方案是将此信息嵌入提供给d3js的数据中

data=[[1,2,3]、[4,5,6]、[7,8,9]]
扁平化数据=数据减少((acc,v,i)=>{
v、 forEach((d,j)=>{
数据项={i,j,d};
acc.push(数据项);
});
返回acc;
}, []);
然后可以从函数的数据arg访问i、j和d

td.text(函数(d){
//可以在此处访问i、j和原始数据
返回“行”:+d.j;
});

我没有看到这个问题,所以谢谢你指出。使用
.each()
来规避这个限制会使我的代码非常难看,但我想在这一点上,没有其他方法了。但是如何在
中将索引添加到'someFunc'。append(“rect”)。on(“单击”,someFunc)
这只是给出DOM节点相对于其父DOM节点的位置。在某些情况下(如您的示例),它可能是正确的值,但往往是错误的。我需要的是绑定到DOM的数据数组的索引-事实上,这就是我首先使用d3.js的原因。一旦我的数据数组发生更改,或者当父节点包含其他子节点时,您的方法就会失败。非常好的一点。我认为在许多情况下,这可能会失败作为一个解决方案工作,但我同意你的观点,这不是一个固有的解决方案,因为它依赖于使用DOM索引/顺序作为数据索引的代理。我在阅读@gerardo的回答后写下了这个答案,作为一种可能的解决方法,之前的功能可能已经不存在了。我认为只有在结尾追加新行时,这才有效如果在中间插入一行,它将接收到错误的“j”索引。(这个代码也假设了一个特定的顺序,其中d3.js处理节点。因为这是没有记录在任何地方的,所以我会犹豫使用它。)同意。这或多或少是一个“杂乱”。如果需要像这样快速而肮脏的转换,guess就可以了,因为它不需要将数据元素包装到对象中以保存对其父对象的引用,而是使用闭包来访问索引。速度损失可能是由于在具有多行的表上发出大量selectAll/exit/enter命令,但这只是一个问题ss.这实际上是我现在在大部分代码中所做的。我希望d3.js提供一种访问索引的方法(就像过去一样),而不是将每个值都包装到一个额外的对象中。但现在已经没有了,我想我们必须使用这个解决方案(可能是一个很好的替代方案).使用箭头运算符时,是否有任何形式可访问父级?即.attr(“someAttr”,(d,I)=>?)
td.text(function(d,i,j) {
  return "Row: " + j;
});
k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode);
rowcols.enter().append("rect")
 .attr("x", function (d, i, j) { return CalcXPos(d, j); })
 .attr("fill", function (d, i, j) { return GetColor(d, j); })
var j = -1;
rowcols.enter().append("rect") 
 .attr("x", function (d, i) { if (i == 0) { j++ }; return CalcXPos(d, j); })
 .attr("fill", function (d, i) { return GetColor(d, j); })
update(matrix) {
        var self = this;
        var tr = table.selectAll("tr").data(matrix);

        tr.exit().remove();

        tr.enter().append("tr");

        tr.each(addCells);

        function addCells(data, rowIndex) {
            var td = d3.select(this).selectAll("td")
                .data(function (d) {
                    return d;
                });
            td.exit().remove();

            td.enter().append("td");

            td.attr("class", function (d) {
                return d === 0 ? "dead" : "alive";
            });

            td.on("click", function(d,i){
                matrix[rowIndex][i] = d === 1 ? 0 : 1; // rowIndex now available for use in callback.                   
            });
        }

        setTimeout(function() {
            update(getNewMatrix(matrix))
        }, 1000);
    },
var aInnerSelection = oSelection.selectAll(".someClass") //
    .data(d.values) //
    ...
var aInnerSelection = oSelection.selectAll(".someClass") //
    .data(function (d, i) {
        var aData = d.values.map(function mapValuesToIndexedValues(elem, index) {
                return {
                    outerIndex: i,
                    innerIndex: index,
                    datum: elem
                };
            })
            return aData;
    }, function (d, i) {
        return d.innerIndex;
    }) //
    ...
                  d                                i
------------------------------------------------------------------
root dummy X      {name "X", values: ["A", "B"]}    0
     dummy Y      {name "Y", values: ["C", "D"]}    1
             d       i
------------------------------------------------------------------
root X  A    "A"     0
        B    "B"     1
     Y  C    "C"     2
        D    "D"     3
             d                                              i
------------------------------------------------------------------
root X  A    {datum: "A", outerIndex: 0, innerIndex: 0}     0
        B    {datum: "B", outerIndex: 0, innerIndex: 1}     1
     Y  C    {datum: "C", outerIndex: 1, innerIndex: 0}     2
        D    {datum: "D", outerIndex: 1, innerIndex: 1}     3
svg.selectAll(".someClass")
    .data(nestedData)
  .enter()
  .append("g")
    .attr("class", "someClass")
  .selectAll(".nestedElt")
    .data(Object)
  .enter()
  .append("g")
    .attr("class", "nestedElt")
    .attr("someAttr", function(d, i, j) {

    });
svg.selectAll(".someClass")
    .data(nestedData)
  .enter()
  .append("g")
    .attr("class", "someClass")
    .attr("data-index", function(d, i) { return i; }) // make parent index available from DOM
  .selectAll(".nestedElt")
    .data(Object)
  .enter()
  .append("g")
    .attr("class", "nestedElt")
    .attr("someAttr", function(d, i) {
      var j = +this.parentNode.getAttribute("data-index");
    });
const nested = nest().key(layerValue).entries(data);

let layerGroups = g.selectAll('g.layer').data(nested);
layerGroups = layerGroups.enter().append('g').attr('class', 'layer')
  .merge(layerGroups);

layerGroups.each(function(layerEntry, j) {   
  const circles = select(this)
    .selectAll('circle').data(layerEntry.values);
  circles.enter().append('circle')
    .merge(circles)
      .attr('cx', d => xScale(xValue(d)))
      .attr('cy', d => yScale(yValue(d)))
      .attr('r', d => radiusScale(radiusValue(d)))
      .attr('fill', j === 0 ? 'white' : 'black'); // <---- Access parent index.
});