我在selection.join()
模式中有一些代码:
const nodeWidth = (node) => node.getBBox().width;
const toolTip = selection
.selectAll('g')
.data(data)
.join(
(enter) => {
const g = enter
.append('g')
g.append('text')
.attr('x', 17.5)
.attr('y', 10)
.text((d) => d.text);
let offset = 0;
g.attr('transform', function (d) {
let x = offset;
offset += nodeWidth(this) + 10;
return `translate(${x}, 0)`;
});
selection.attr('transform', function (d) {
return `translate(${
(0 - nodeWidth(this)) / 2
},${129.6484} )`;
});
},
(update) => {
update
.select('text')
.text((d) => d.text);
let offset = 0;
update.attr('transform', function (d) {
let x = offset;
offset += nodeWidth(this) + 10;
return `translate(${x}, 0)`;
});
selection.attr('transform', function (d) {
return `translate(${
(0 - nodeWidth(this)) / 2
},${129.6484} )`;
});
}
);
正如您所看到的,在enter
和update
部分中,我需要调用几个函数来计算几个节点的转换。特别地,该代码在累积变量offset
中存储先前文本元素的长度。这样可以适当地将文本元素隔开(即,text0<-10 px->text1<-10px->…(。
正如你所看到的;变换函数";在CCD_ 5和CCD_。我试着在一个地方定义它们,并在我需要的地方给它们打电话。例如,
(update) => {
update.attr('transform', foo);
selection.attr('transform', bar);
}
但是,我不能用这种方式重构代码,因为看起来我既不能向传递给attr()
的函数传递offset
值,也不能传递this
。
有办法做到吗?
编辑:
根据Gerardo Furtado的提示(如果我说得对的话(,你可以定义foo
如下:
const foo = function(d, i, n, offset) {
let x = offset;
offset += nodeWidth(n[i]) + 10;
return `translate(${x}, 0)`;
}
那么在selection.join¡
中,你必须这样调用foo
:
(update) => {
let offset = 0;
update.attr('transform', (d, i, n) => foo(d, i, n, offset));
}
然而,通过这种方式重构,偏移量永远等于0。这里有一个可能的解决方案:https://stackoverflow.com/a/21978425/4820341
看看Function.protype.bind((.
const doSomething = (d) => {
return `translate(${
(0 - nodeWidth(this)) / 2
},${129.6484} )`;
}
调用内部的函数(输入(和(更新(
selection.attr('transform', doSomething.bind(d));
通过这种方式,函数将在当前作用域中执行。
我想这就是你要找的。请注意,我无法测试我的代码!