I've some code inside a selection.join()
pattern:
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} )`;
});
}
);
as you can see, in the enter
and update
section I need to call a couple of functions to calculate several nodes transformations. In particular, the code stores in the accumulation var offset
the length of the previous text element. This properly spaces text elements (ie, text0 <- 10 px -> text1 <- 10 px -> ...).
As you can see, the "transform functions" in the enter
and update
section are identical. I'm trying to define them just in one place and call them where I need. E.g.,
(update) => {
update.attr('transform', foo);
selection.attr('transform', bar);
}
However, I cannot refactor the code this way because it looks like I cannot pass in neither the offset
value nor this
to the function passed to attr()
.
Is there a way to do it?
EDIT:
As per Gerardo Furtado's hint (if I got it right), you can define foo
as follows:
const foo = function(d, i, n, offset) {
let x = offset;
offset += nodeWidth(n[i]) + 10;
return `translate(${x}, 0)`;
}
then in the selection.join¡
you have to call foo
this way:
(update) => {
let offset = 0;
update.attr('transform', (d, i, n) => foo(d, i, n, offset));
}
However, refactoring this way, offset is ever equal to 0. A possibile solution here: https://stackoverflow.com/a/21978425/4820341