我无法为一维数组中的每个数据条目创建一个组 g 以及两个子 SVG 组件(text 和 rect)。
allCorrespondingYValues 是一个类似 [1,2,3,4] 的数组
selection.selectAll("g.y-crosshair-tooltip").data(allCorrespondingYValues)
.join('g')
.attr("class", "y-crosshair-tooltip")
.attr("transform", d => "translate(" + (width - margin.right) + "," + (yScale(d)) + ")")
//.select("text").join('text') // Method 1: Nothing appears, just 1 'g' per data
//.join("text") // Method 2: Nothing appears, just 1 'g' per data
//.append("text") // Method 3: this will continuously append a new text element inside the parent 'g' every time the crosshair moves and the function this code is contained in is called
//.selectAll("text").data(d => d).join("text") // Method 4: Throws errors.
.selectAll("text").data([null]).join("text") // Method 5: This works and creates only 1 child text element for the 'g', but the text is always null because its referencing the null dataset, not the parent dataset.
.attr("dx", -15) // position relative to its group
.attr("dy", -15)
.attr("fill", "black")
.text(d => "$" + d)
我尝试的四种方法都在上面的代码中,每个方法旁边的注释都解释了它们的问题。最令我惊讶的是方法 1 不起作用,因为 Mike's Selection Guide 提到“select 还会将数据从父级传播到子级,而 selectAll 则不会”和“数据绑定到元素...通过追加从父级继承” 、插入或选择。”所以我希望通过使用
.select("text").join('text')
,我可以只引用来自父级的数据。相反,生成的 DOM 显示 nothing 已添加到父级“g”中。
所以我的两个问题是...
我发现了几个类似的 stackoverflow 问题,但大多数都比较旧,并且使用 Enter() 而不是 join(),或者有 2D 数据数组,所以像方法 4 这样的东西可以工作......而对我来说,我试图参考从父母到孩子的完全相同的数据。
谢谢!
您正在尝试使用join
的“简写”版本,这不适合您的目的,并且您的尝试只会使代码变得复杂。相反,请使用常规版本,您可以在其中指定显式函数:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.js"></script>
</head>
<body>
<svg></svg>
<script>
d3.select("svg")
.attr("width", 300)
.attr("height", 300)
.selectAll("g")
.data([1,2,3,4])
.join(
(enter) => {
const g = enter.append("g")
.attr("transform", (d, i) => "translate(" + (i * 16) + ", 20)");
g.append("text")
.text(d => d);
});
</script>
</body>
</html>