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');//
我的解决方案是将此信息嵌入提供给d3js的数据中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()来规避这个
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.
});