r2d3 可视化中的范围 - d3.selectAll 与 svg.selectAll
Scoping in r2d3 visualization - d3.selectAll vs svg.selectAll
为什么 d3.selectAll('rect')...
不能像下面脚本中的鼠标悬停功能那样工作,但 svg.selectAll('rect')...
可以?
svg
是 r2d3 的特殊预设选择器。
此外,我注意到 运行 例如d3.selectAll('rect').remove()
当 运行 来自 Rstudio 的可视化时,来自浏览器控制台的 d3.selectAll('rect').remove()
不起作用。
这来自 r2d3 示例,如 sample.js
:
// !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20)
var barHeight = Math.floor(height / data.length);
svg.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('width', function(d) { return d * width; })
.attr('height', barHeight)
.attr('y', function(d, i) { return i * barHeight; })
.attr('fill', 'steelblue')
.on('mouseover', function(d){
d3.select(this).attr('fill', 'red')
//svg.selectAll('rect').attr('fill', 'red')
d3.selectAll('rect').attr('fill', 'red')
})
运行 来自 R 通过 r2d3::r2d3("sample.js", data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20))
默认情况下,r2d3 将可视化置于阴影中 DOM。 d3.select 和 d3.select 都从 DOM 的根元素开始搜索,但不要冒险进入影子 DOM 的子节点。
select 和 selectAll 都不会从正在搜索的当前树交叉到影子树中。由于 svg
是阴影 DOM 内元素的 selection,可以使用 svg.selectAll("rect")
找到矩形,但不能使用 d3.selectAll("rect")
(矩形不是相对于 SVG 的“阴影”)。
最简单的解决方案是不创建阴影 DOM,方法是将 r2d3 阴影选项设置为 false。
例如(使用 r2d3 文档中的 base example):
r2d3(options(r2d3.shadow = FALSE), data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js")
当然,这样做会失去影子根提供的封装,但根据情况,这可能更可取或中立。
我发现有时 r2d3.shadow 选项并不总是有效,所以这是另一个可能的解决方案。事件目标的父级将是您放置它的 svg/g。
// !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20)
var barHeight = Math.floor(height / data.length);
svg.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('width', function(d) { return d * width; })
.attr('height', barHeight)
.attr('y', function(d, i) { return i * barHeight; })
.attr('fill', 'steelblue')
.on('mouseover', function(d){
const parent = d3.select(d.target.parentElement); // this is the original svg
//svg.selectAll('rect').attr('fill', 'red')
parent.selectAll('rect').attr('fill', 'blue')
d3.select(this).attr('fill', 'red')
})
为什么 d3.selectAll('rect')...
不能像下面脚本中的鼠标悬停功能那样工作,但 svg.selectAll('rect')...
可以?
svg
是 r2d3 的特殊预设选择器。
此外,我注意到 运行 例如d3.selectAll('rect').remove()
当 运行 来自 Rstudio 的可视化时,来自浏览器控制台的 d3.selectAll('rect').remove()
不起作用。
这来自 r2d3 示例,如 sample.js
:
// !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20)
var barHeight = Math.floor(height / data.length);
svg.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('width', function(d) { return d * width; })
.attr('height', barHeight)
.attr('y', function(d, i) { return i * barHeight; })
.attr('fill', 'steelblue')
.on('mouseover', function(d){
d3.select(this).attr('fill', 'red')
//svg.selectAll('rect').attr('fill', 'red')
d3.selectAll('rect').attr('fill', 'red')
})
运行 来自 R 通过 r2d3::r2d3("sample.js", data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20))
默认情况下,r2d3 将可视化置于阴影中 DOM。 d3.select 和 d3.select 都从 DOM 的根元素开始搜索,但不要冒险进入影子 DOM 的子节点。
select 和 selectAll 都不会从正在搜索的当前树交叉到影子树中。由于 svg
是阴影 DOM 内元素的 selection,可以使用 svg.selectAll("rect")
找到矩形,但不能使用 d3.selectAll("rect")
(矩形不是相对于 SVG 的“阴影”)。
最简单的解决方案是不创建阴影 DOM,方法是将 r2d3 阴影选项设置为 false。
例如(使用 r2d3 文档中的 base example):
r2d3(options(r2d3.shadow = FALSE), data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20), script = "barchart.js")
当然,这样做会失去影子根提供的封装,但根据情况,这可能更可取或中立。
我发现有时 r2d3.shadow 选项并不总是有效,所以这是另一个可能的解决方案。事件目标的父级将是您放置它的 svg/g。
// !preview r2d3 data=c(0.3, 0.6, 0.8, 0.95, 0.40, 0.20)
var barHeight = Math.floor(height / data.length);
svg.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('width', function(d) { return d * width; })
.attr('height', barHeight)
.attr('y', function(d, i) { return i * barHeight; })
.attr('fill', 'steelblue')
.on('mouseover', function(d){
const parent = d3.select(d.target.parentElement); // this is the original svg
//svg.selectAll('rect').attr('fill', 'red')
parent.selectAll('rect').attr('fill', 'blue')
d3.select(this).attr('fill', 'red')
})