繁体   English   中英

D3 过渡中断重绘

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM