【问题标题】:D3 Transition Breaking RedrawD3 转换中断重绘
【发布时间】: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


【解决方案1】:

您的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);
    });

【讨论】:

  • 仍然有同样的行为。不确定在.attr 调用之前调用.text().call(wrap, 50) 会如何改变任何事情。也许你打算先做blockLabels.text(...).call(...),然后再做blockLabels.attr(...?这种改变肯定有帮助。它仍然有点滞后,但我认为这可能只是因为wrap 需要多长时间。
  • @tgordon18 哎呀,这正是我的意思。
  • 看起来有效!我还为过渡添加了更长的持续时间,使其看起来更平滑一些。如果您编辑您的解决方案,我会接受它作为答案
猜你喜欢
  • 2013-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多