D3 Transform Rescale X跳到右边

时间:2018-01-06 14:43:33

标签: javascript d3.js zoom

我正在创建一个时间轴折线图,显示5或6个不同的线条,并希望能够放大和滚动(一旦缩放)。我使用了一些使用面积图的例子,但出于某种原因,当我第一次缩放时,我的折线图向右跳转,我将一些数据丢失到右边(我无法滚动查看它或在缩放时看到它完全出局)。当我缩放或滚动时,线条也会出现在y轴上。

我已将其复制到JSFiddle(see here),并使用我图表中其中一行的数据集。一旦使用缩放功能,为什么线条会向右跳?如何阻止线出现在y轴上?

如果你想在这里阅读,那么这是我的版本的JS:

function drawTimeline() {

    var margin = {top: 10, right: 0, bottom: 50, left: 60}
    var width = d3.select('#timeline').node().getBoundingClientRect().width/3*2;
    var height = 300;

    var svg = d3.select("#timeline").append("svg")
        .attr("width", width)
        .attr("height", height+margin.top+margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
        .attr("width", width - margin.left - margin.right)
        .call(d3.zoom()
                // .extent()
                .scaleExtent([1, 10])
                .translateExtent([[0, -Infinity], [width - margin.left - margin.right, Infinity]])
                .on("zoom", zoom)
        );

    var view = svg.append("rect")
        .attr("class", "view")
        .attr("width", width - margin.left - margin.right)
        .attr("height", height)
        .attr("fill", "white");

    var x = d3.scaleTime()
            .domain([
                d3.min(poll_data[0].avgpolls, function(p) { return p.date; }), 
                d3.max(poll_data[0].avgpolls, function(p) { return p.date; })
            ])
            .range([0, width - margin.left - margin.right]);

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


    var xAxis = d3.axisBottom(x);
    var yAxis = d3.axisLeft(y);

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

    var gY = svg.append("g")
                .attr("class", "axis yaxis")
                .call(yAxis);

    //All lines are drawn in the same way (x and y points)
    var line = d3.line()
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.poll); });

    //selectAll allows us to create and manipulate multiple groups at once
    var party = svg.selectAll(".party")
        .data(poll_data)
        .enter()
        .append("g")
        .attr("class", "party");

    //Add path to every country group at once
    var pollPaths = party.append("path")
        .attr("class", "line")
        .attr("d", function(d) { return line(d.avgpolls); })
        .attr("fill", "none")
        .attr("stroke-width", 2)
        .style("stroke", function(d) { return returnPartyColour(d.party); });

    function zoom() {
      console.log("zooming: " + d3.event.transform);
      var new_x = d3.event.transform.rescaleX(x);
      gX.call(d3.axisBottom(new_x));
      //view.attr("transform", d3.event.transform);

      //Redraw lines
      //pollPaths.select(".line").attr("d", function(d) { return line(d.avgpolls); });
      var newline = d3.line()
        .x(function(d) { return new_x(d.date); })
        .y(function(d) { return y(d.poll); });

      pollPaths.attr("d", function(d) { return line(d.avgpolls); });
    }

}

数据在我的版本中格式如下,但不是JSFiddle:

poll_data = [
    {
        'party' : 'Party 1',
        'avgpolls' : [
            {'date' : new Date(year, month, day), 'poll' : 0, },
        ],

]

由于

1 个答案:

答案 0 :(得分:1)

解决这些问题需要两件事。

线条在缩放时跳跃的原因是因为未设置缩放范围。这已设置并且translateExtent的值已更新:

d3.zoom()
    .scaleExtent([1, 10])
    .translateExtent([[0, 0], [width - margin.left - margin.right, Infinity]])
    .extent([[0, 0], [width - margin.left - margin.right, height]])
    .on("zoom", zoom)

要防止路径溢出剪切路径。在创建svg之后,在添加其他元素之前,我添加了一个剪辑路径,如下所示:

svg.append("defs").append("clipPath")
    .attr("id", "clip")
    .append("rect")
    //Same dimensions as the area for the lines to appear
    .attr("width", width - margin.left - margin.right)
    .attr("height", height);

然后必须将其添加到每条路径中。

var pollPaths = party.append("path")
    ...
    .attr("clip-path", "url(#clip)");

最初的JSFiddle已updated反映这些变化。