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
);