Javascript 为变换的每个帧运行自定义计算

Javascript 为变换的每个帧运行自定义计算,javascript,d3.js,transition,Javascript,D3.js,Transition,作为d3.treemap()的一部分: 在svg元素中有嵌套的组。每组有一个rect和text,子组为tspan。 像这样: <g><rect></rect><text><tspan>Text here</tspan></text></g> 如果矩形的高度和宽度不变,则此操作正常。但是用户可以选择一个不同的选项来更改矩形的大小并触发此d3.transition(): 这不会改变文本的位置,文本的位置

作为
d3.treemap()的一部分

svg
元素中有嵌套的
。每组有一个
rect
text
,子组为
tspan
。 像这样:

<g><rect></rect><text><tspan>Text here</tspan></text></g>
如果矩形的
高度
宽度
不变,则此操作正常。但是用户可以选择一个不同的选项来更改矩形的大小并触发此
d3.transition()

这不会改变文本的位置,文本的位置也需要改变-因此,作为一个临时解决方案,我提出了以下建议:

setInterval(
        () => {
            cell.selectAll('tspan')
                .attr('x', function() { return calculateCenterOfTextInRectangle(this).centerX; }) // center x and y. Not using Es6 function because of this context which is the tspan element.
                .attr('y', function() { return calculateCenterOfTextInRectangle(this).centerY; });
        },
        0.1
    );

问题在于,当使用
setInterval
方法时,Web应用程序的响应性较差。我是否可以在不使用
setInterval
的情况下在
transition
函数中实现文本居中?

在转换中使用
CalculateCenter/TransitionRectangle
的问题是,即使在为矩形设置新值后调用它,也会得到初始值,这是他期望的行为

让我们在这个演示中看到它,检查控制台:

var svg=d3.选择(“svg”);
var g=svg.append(“g”);
var rect=g.append(“rect”)
.attr(“笔划”、“黑色”)
.attr(“填充”、“白色”)
.attr(“x”,0)
.attr(“y”,0)
.attr(“宽度”,50)
.attr(“高度”,150);
var text=g.append(“文本”)
.文本(“foo”)
.attr(“x”,函数(){
返回CalculateCenter矩形(此).centerX
})
.attr(“y”,函数(){
返回CalculateCenter矩形(this).centerY
});
var gTransition=g.transition()
.期限(5000);
gTransition.select(“rect”)
.attr(“宽度”,150)
.attr(“高度”,40);
G转换。选择(“文本”)
.attr(“x”,函数(){
console.log(calculateCenter(this.centerX)
返回CalculateCenter矩形(此).centerX
})
.attr(“y”,函数(){
log(calculateCenter(this.centerY)
返回CalculateCenter矩形(this).centerY
})
函数CalculateCenter矩形(tspanNode){
const rectangleNode=tspanNode.previousSibling;
const centerX=(rectangleNode.getAttribute('width')/2)-(tspanNode.getComputedTextLength()/2);
const centerY=(rectangleNode.getAttribute('height')/2)+(19/2);//19是字体大小(以像素为单位)
返回{
centerX:centerX,
森蒂:森蒂
};
};

通过阅读d3文档,我不知道如何在一次转换中选择不同的元素。谢谢你详细的回答。我使用了
selection.tween()
方法,工作非常顺利。
treemap(root.sum(sum)); // new values
cell.transition()
    .duration(750)
    .attr('transform', (d) => 'translate(' + d.x0 + ',' + d.y0 + ')')
    .selectAll('rect')
    .attr('width', (d) => d.x1 - d.x0)
    .attr('height', (d) => d.y1 - d.y0);
setInterval(
        () => {
            cell.selectAll('tspan')
                .attr('x', function() { return calculateCenterOfTextInRectangle(this).centerX; }) // center x and y. Not using Es6 function because of this context which is the tspan element.
                .attr('y', function() { return calculateCenterOfTextInRectangle(this).centerY; });
        },
        0.1
    );