以Mike Bostock为例,d3版本4路径平滑过渡

时间:2016-09-04 18:36:55

标签: d3.js svg

我第一次在这里发帖提问。我正在将我的第3版d3路径转换代码转换为版本4,我很难过。

首先,我看到了迈克的例子(发布了大约两天的时间)和版本4的非时间x轴的平滑线转换,所以我做了与他的第3版的例子类似的事情x轴。路径线平滑移动,但x轴不是。另外,对于我的工作,我不能触发他在这个例子中所做的过渡,所以我不能使用变量"这个"在tick函数中。这是代码:

<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <script src="//d3js.org/d3.v4.min.js"></script>
    <style>
        .line {
            fill: none;
            stroke: #000;
            stroke-width: 1.5px;
        }
    </style>
</head>
<body>
    <svg width="960" height="500"></svg>
    <script>
        (function() {
            var n = 243,
                duration = 750,
                now = new Date(Date.now() - duration),
                count = 0,
                data = d3.range(n).map(function() { return 0; });
                random = d3.randomNormal(0, .2),
                data = d3.range(n).map(random);

            var margin = {top: 6, right: 0, bottom: 20, left: 40},
                width = 960 - margin.right,
                height = 120 - margin.top - margin.bottom;

            var x = d3.scaleTime()
                .domain([now - (n - 2) * duration, now - duration])
                .range([0, width]);

            var y = d3.scaleLinear()
                .range([height, 0]);

            var line = d3.line()
                .x(function(d, i) { return x(now - (n - 1 - i) * duration); })
                .y(function(d, i) { return y(d); });

            var svg = d3.select("body").append("p").append("svg")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
                .style("margin-left", -margin.left + "px")
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

            svg.append("defs").append("clipPath")
                .attr("id", "clip")
              .append("rect")
                .attr("width", width)
                .attr("height", height);

            var axis = svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(x.axis = d3.axisBottom().scale(x));

            var timeline = svg.append("g")
                .attr("clip-path", "url(#clip)")
                .append("path")
                .datum(data)
                .attr("class", "line")
                .transition()
                .duration(500)
                .ease(d3.easeLinear)
                .on("start", tick);


            var transition = d3.select({}).transition()
                .duration(750)
                .ease(d3.easeLinear);


            function tick() {
                data.push(random());
                now = new Date();
                x.domain([now - (n - 2) * duration, now - duration]);
                y.domain([0, d3.max(data)]);

                // redraw the line
                svg.select(".line")
                    .attr("d", line)
                    .attr("transform", null);

                // slide the x-axis left
                axis.call(x.axis);

                // slide the line left
                d3.active(this)
                    .attr("transform", "translate(" + x(now - (n - 1) * duration) + ")")
                    .transition().on("start", tick);

                // pop the old data point off the front
                data.shift();
            }

        })()
    </script>
</body>

在tick函数中,有一个&#34;这个&#34;,来自调试,我发现它是一个路径,所以我试图用d3.active替换它(d3.selectAll(&#) 34; path&#34;))或d3.active(d3.selectAll(&#34; .line&#34;)),都不起作用。我还尝试为路径分配一个可变时间轴,以便我尝试d3.active(时间轴)。它也不起作用。

我在我的智慧&#39;结束这个问题。我发布在d3谷歌组,没有人回答。我希望有人能给我一些建议。

由于

黛安娜

1 个答案:

答案 0 :(得分:0)

过渡到v4确实不容易。和你有同样的问题。请尝试以下代码:

&#13;
&#13;
<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <script src="//d3js.org/d3.v4.min.js"></script>
    <style>
        .line {
            fill: none;
            stroke: #000;
            stroke-width: 1.5px;
        }
    </style>
</head>
<body>
<svg width="960" height="500"></svg>
<script>
    (function() {
        var n = 243,
                duration = 750,
                now = new Date(Date.now() - duration),
                count = 0,
                data = d3.range(n).map(function() {
                    return 0;
                });
        random = d3.randomNormal(0, .2),
                data = d3.range(n).map(random);

        var margin = {top: 6, right: 0, bottom: 20, left: 40},
                width = 960 - margin.right,
                height = 120 - margin.top - margin.bottom;

        var x = d3.scaleTime()
                .domain([now - (n - 2) * duration, now - duration])
                .range([0, width]);

        var y = d3.scaleLinear()
                .range([height, 0]);

        var line = d3.line()
                .x(function(d, i) {
                    return x(now - (n - 1 - i) * duration);
                })
                .y(function(d, i) {
                    return y(d);
                });

        var svg = d3.select("body").append("p").append("svg")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
                .style("margin-left", -margin.left + "px")
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        svg.append("defs").append("clipPath")
                .attr("id", "clip")
                .append("rect")
                .attr("width", width)
                .attr("height", height);

        var axis = svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(x.axis = d3.axisBottom().scale(x));

        var timeline = svg.append("g")
                .attr("clip-path", "url(#clip)")
                .append("path")
                .datum(data)
                .attr("class", "line")
                .transition()
                .duration(500)
                .ease(d3.easeLinear);


        var transition = d3.select({}).transition()
                .duration(750)
                .ease(d3.easeLinear);


        (function tick() {
            transition = transition.each(function() {

                data.push(random());
                now = new Date();
                x.domain([now - (n - 2) * duration, now - duration]);
                y.domain([0, d3.max(data)]);

                // redraw the line
                svg.select(".line")
                        .attr("d", line)
                        .attr("transform", null);

                // slide the x-axis left
                axis.call(d3.axisBottom(x));

                // slide the line left
                //d3.active(this).attr("transform", "translate(" + x(now - (n - 1) * duration) + ")");

                // pop the old data point off the front
                data.shift();

            }).transition().on("start", tick);
        })();
    })()
</script>
</body>
&#13;
&#13;
&#13;

诀窍是链转换并使用transition().on而不是transition().each。要更新轴,您需要以与实例化轴相同的方式调用d3.axisBottom(x)