javascript - 以编程方式控制画笔并传递相关信息
问题描述
这是昨天这个问题的延伸。我正在尝试绘制和创建多个画笔。我使用的蛮力方法没问题,但我需要额外的功能来以编程方式控制这些新创建的画笔,
createBrush(){
//Brushes
var brushGroups = []
for(var i=0; i<this.uniqueCats.length; i++){
//BRUSH CONTAINER
brushGroups[i] = d3.select('#brushContainer')
.append('g')
.attr('id',`${this.uniqueCats[i]}brush`)
.attr('transform', `translate(${this.margin.left},0)`)
.attr('class','brush');
//BRUSH
var brushID = this.uniqueCats[i]
this[`${this.uniqueCats[i]}Brush`] = d3.brushX()
.extent([[0, (i*135)+38], [this.width,(i*135)+170]])
.on('end',(i)=>{
console.log('hi')
this.updateBubbles(i)
})
//CALL BRUSH from the brush container
brushGroups[i].call(this[`${this.uniqueCats[i]}Brush`])
}
}
正如您在上面看到的,我 1)创建一个画笔容器 2)创建一个画笔,3)从容器中调用该画笔。我让它将相关信息传递给on
for的主要问题this.updateBubbles()
。希望每个画笔都能传递特定信息updatebubbles()
,让我了解哪个画笔被激活。
从那里我决定使用更优雅的 d3 方法,enter()
但是,这种方法根本无法调用画笔,
createBrushv2(){var that =this
var brushContainer = d3.select('#brushContainer')
.selectAll('g')
.data(this.uniqueCats)
var brushContainerEnter = brushContainer
.enter()
.append('g')
.attr('id', d=> `${d}brush`)
brushContainer = brushContainerEnter.merge(brushContainer)
.attr('transform', `translate(${this.margin.left},0)`)
.attr('class','brush')
.each( function(d,i){
console.log(i)
d3.brushX()
.extent([[0,(i*135)+38], [that.width,(i*135)+170]])
.on('end',that.updateBubbles(d))
})
}
该updateBubbles()
功能是从每个画笔中唤起的,因此该功能需要能够了解选择了哪个画笔。
解决方案
您的代码中有几个问题,这使您的问题过于宽泛。因此,我将只处理未调用画笔的问题。
首先,恭喜您从方法#1(for
循环)移动到方法#2(D3 选择)。在 D3 代码中,使用循环附加任何内容几乎是一个非常糟糕的主意。
话虽如此,与您的第一个片段不同,您实际上并没有在第二个片段中调用画笔。
因此,这...
d3.brushX()
.extent([[0,(i*135)+38], [that.width,(i*135)+170]])
.on('end',that.updateBubbles(d))
应该:
d3.brushX()
.extent([[0,(i*135)+38], [that.width,(i*135)+170]])
.on('end', that.updateBubbles)(d3.select(this))
更好的是,您应该使用 a selection.call
,就像在您的第一种方法中一样。另外,请记住,这that.updateBubbles(d)
将立即调用该函数,这不是您想要的。
这是一个非常基本的片段作为演示:
const data = d3.range(5);
const svg = d3.select("svg");
createBrushv2();
function createBrushv2() {
var brushContainer = svg.selectAll(".brush")
.data(data)
var brushContainerEnter = brushContainer.enter()
.append('g');
brushContainer = brushContainerEnter.merge(brushContainer)
.attr('transform', function(d) {
return "translate(0," + (d * 25) + ")"
})
.attr('class', 'brush')
.each(function(d) {
d3.brushX()
.extent([
[0, 0],
[300, 20]
])
.on('end', updateBubbles)(d3.select(this))
})
.each(function() {
d3.brushX().move(d3.select(this), [0, 300])
})
};
function updateBubbles(brush) {
console.log(brush)
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>
推荐阅读
- c# - 为 pyCaffe 编写调试器可视化工具?
- javascript - Javascript 正则表达式主机名
- excel - 打开工作簿脚本卡在私有子中的循环中
- android - 为什么是 textView "Hello world!" 没有显示在屏幕上?
- javascript - 发出 HTTP SOAP 请求
- ios - 无法在 AVPlayer 中播放 RTMP url?
- r - R访问data.table的列
- python - 如何仅抓取唯一值并将其保存到数据库中
- api - 使用 Tyk.io 进行 API 监控
- jquery - 使用 Ajax 将数据插入数据库 - ASP.NET MVC