[英]D3 Transition Breaking Redraw
我正在尝试为 D3 图表的更新设置动画,其中我有矩形,其中包含包装文本。 如果我在没有过渡的情况下执行此操作,则一切都会按预期运行。 但是,当我添加过渡时,文本根本不会换行。 如果从未调用 wrap 函数,它看起来会这样。
更奇怪的是,如果我单步调试调试器,我可以看到它实际上进入了 wrap 函数。 在 wrap 函数结束时,显示的结果实际上看起来应该如此。 但是,一旦我退出函数并返回 D3 库代码,它就会恢复到展开的视图。
我最好的猜测是 wrap 函数需要一段时间并导致某种转换问题,但我不确定。
以下是redraw
函数的相关代码片段,当我想更新页面时会调用该函数:
MyChart.prototype.redraw = function(taskList) {
var that = this;
var svg = d3.select("svg");
var chart = svg.select(".chart");
var blocks = chart.selectAll(".block")
.data(myData, this.keyFunction);
blocks.transition()
.attr("transform", function(d) {
return rectTransform(d, that.xScale, that.yScale);
})
.attr("height", function(d) {
return that.yScale.bandwidth() - GRIDLINE_WIDTH;
})
.attr("width", function(d) {
return Math.max(that.xScale(new Date(d.date).addDays(1)) -
that.xScale(new Date(d.date)) -
GRIDLINE_WIDTH, 0);
});
blocks.exit().remove();
// update block labels
var blockLabels = svg.selectAll('.blockLabel')
.data(myData, this.keyFunction);
blockLabels.transition()
.attr('visibility', function(d) {
if (new Date(d.date) < that.xScale.domain()[0] ||
new Date(d.date) >= that.xScale.domain()[1])
return 'hidden';
return 'visible';
})
.attr("transform", function(d) {
return rectLabelTransform(d, that.xScale, that.yScale);
})
.text(function(d) {
return getBlockText(d);
})
// 50 pixels for now, later will update to actual rect width
.call(wrap, 50);
return this;
}
这是wrap
函数,取自Mike Bostock 示例:
function wrap(text, width) {
text.each(function(d) {
var text = d3.select(this);
// quickly ignore short labels
if (text.text().length < 10) {
text.attr('dy', '0.35em');
return;
}
var words = text.text().split(/\s+/).reverse();
var word;
var line = [];
var lineNumber = 0;
var lineHeight = 0.9; // ems
var y = text.attr("y");
var dy = parseFloat(text.attr("dy"));
var tspan = text.text(null)
.append("tspan")
.attr("x", 0)
.attr("y", y)
.attr("dy", dy + "em");
while (!!(word = words.pop())) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan")
.attr("x", 0)
.attr("y", y)
.attr("dy", ++lineNumber * lineHeight + dy + "em")
.text(word);
}
}
// re-center if only one line
if (lineNumber < 1) tspan.attr('dy', '0.35em');
});
}
我在想我可以尝试提高 wrap 函数的速度,或者,在最坏的情况下,只是放弃动画。 但我很好奇具体问题是什么..
编辑 - - - -
马克的回答确实有帮助,但是当我将.call(wrap, 200)
更改为.call(wrap, function(d) {return 200;})
它再次中断。 我假设这是时间问题,但这种行为对我来说似乎很奇怪,如此小的变化可能会产生如此大的影响。 有任何想法吗?
您的wrap
函数在转换中被调用。 我想你的意思是这样的:
blockLabels.transition()
.text(function(d) {
return getBlockText(d);
})
.call(wrap, 50)
.attr('visibility', function(d) {
if (new Date(d.date) < that.xScale.domain()[0] ||
new Date(d.date) >= that.xScale.domain()[1])
return 'hidden';
return 'visible';
})
.attr("transform", function(d) {
return rectLabelTransform(d, that.xScale, that.yScale);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.