【发布时间】:2018-02-13 20:32:52
【问题描述】:
我正在尝试对 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函数,取自this Mike Bostock example:
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');
});
}
我在想我可以尝试提高换行功能的速度,或者,在最坏的情况下,只是放弃动画。但我很好奇具体问题是什么..
编辑--------
Mark 的回答确实有帮助,但是当我将 .call(wrap, 200) 更改为 .call(wrap, function(d) {return 200;}) 时,它再次中断。我假设这是时间问题,但这种行为对我来说似乎很奇怪,如此小的变化可能会产生如此大的影响。有什么想法吗?
【问题讨论】:
-
这听起来像是一个时间问题——如果您在调用
wrap函数之前结束转换语句,然后使用单独的blockLabels.call(wrap, 50);语句会发生什么? -
奇怪的是这并没有改变任何东西
标签: javascript d3.js transition word-wrap