【问题标题】:d3.js zoom xScale / xAxisd3.js 缩放 xScale / xAxis
【发布时间】:2013-02-18 07:01:01
【问题描述】:

我正在尝试创建一个允许缩放功能的简单图表,到目前为止我发现的示例手动生成轴和刻度:http://bl.ocks.org/1182434

然而,我使用的是内置轴对象,我不知道如何转换比例以使其工作 - 有什么想法吗?

var xScale = d3.scale.linear().
    domain([0, 80]). // your data minimum and maximum
    range([0, width]); // the pixels to map to, e.g., the width of the diagram.

var yScale = d3.scale.linear().
    domain([100, 0]). 
    range([0, height]); 

var xAxis = d3.svg.axis().orient("bottom").scale(xScale).ticks(10, d3.format(",d")),
    yAxis = d3.svg.axis().orient("left").scale(yScale);


var chart = d3.select("#chart").append("svg")
    .attr("class", "chart")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .attr("pointer-events", "all")
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .call(d3.behavior.zoom().on("zoom", redraw))
    .append("g")

chart.append('svg:rect')
    .attr('width', width)
    .attr('height', height)
    .attr('fill', 'white');

// x-axis
var xaxis = chart.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

// y-axis
var yaxis = chart.append("g")
    .attr("class", "y axis")
    .call(yAxis);

// omitted code to draw the path, it's just a path object that uses a line and passes data to it

function redraw() 
{
    console.log("here", d3.event.translate, d3.event.scale);
    path.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");

    // d3.event.transform(xScale, yScale);
    // HERE is where I need to figure out how to scale the x and y axes!    

    xAxis.scale(xScale);
    yAxis.scale(yScale);

    xaxis.call(xAxis);
    yaxis.call(yAxis);
}

【问题讨论】:

    标签: zooming d3.js


    【解决方案1】:

    这就是我最终的做法,以防有人感兴趣:

    function redraw() 
    {
    
        console.log("here", d3.event.translate, d3.event.scale);
        path.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");     
    
        var xoffset = (xMax + xMin) / 2;
        var yoffset = (yMax + yMin) / 2;
    
        var xTemp = [(0 - xoffset) * (1/d3.event.scale), (0 + xoffset) * (1/d3.event.scale)];
        var yTemp = [(0 - yoffset) * (1/d3.event.scale), (0 + yoffset) * (1/d3.event.scale)];
    
        xMin = xTemp[0] + xoffset;
        xMax = xTemp[1] + xoffset;
        yMin = yTemp[0] + yoffset;
        yMax = yTemp[1] + yoffset;
    
        console.log("", xMin, xMax, yMin, yMax);
    
        xScale.domain([xMin, xMax]);
        yScale.domain([yMax, yMin]);
    
        xaxis.call(xAxis);
        yaxis.call(yAxis);
    
        path.attr("d", line)
            .attr("transform", null)
            .transition()       
            .ease("linear")     
            ;
    }
    

    请注意,我还必须设置比例限制:

    var chart = d3.select("#chart").append("svg")
    .attr("class", "chart")
    .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
    .attr("pointer-events", "all")
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .call(d3.behavior.zoom().scaleExtent([0.2, 5]).on("zoom", redraw))
    .append("g");
    

    【讨论】:

      【解决方案2】:

      您可以通过使用单独的图表查看我所做的包含缩放功能的图表,同样的方法可以放大现有图表。该图表可在http://bl.ocks.org/1962173 获取。

      这是我缩放的方式:

      var rects, labels
        , minExtent = d3.time.day(brush.extent()[0])
        , maxExtent = d3.time.day(brush.extent()[1])
        , visItems = items.filter(function (d) { return d.start < maxExtent && d.end > minExtent});
      
      mini.select('.brush').call(brush.extent([minExtent, maxExtent]));       
      
          // modify the domain (this is what actually does the 'zoom')
      x1.domain([minExtent, maxExtent]);
      
      // then redraw the updated axis which are based on the modified domain
      main.select('.main.axis.date').call(x1DateAxis);
      main.select('.main.axis.month').call(x1MonthAxis)
          .selectAll('text')
              .attr('dx', 5)
              .attr('dy', 12);
      
      // upate the item rects that are visible
      rects = itemRects.selectAll('rect')
          .data(visItems, function (d) { return d.id; })
          .attr('x', function(d) { return x1(d.start); })
          .attr('width', function(d) { return x1(d.end) - x1(d.start); });
      
          // append any new data that is now in view
      rects.enter().append('rect')
          .attr('x', function(d) { return x1(d.start); })
          .attr('y', function(d) { return y1(d.lane) + .1 * y1(1) + 0.5; })
          .attr('width', function(d) { return x1(d.end) - x1(d.start); })
          .attr('height', function(d) { return .8 * y1(1); })
          .attr('class', function(d) { return 'mainItem ' + d.class; });
      
          // remove any data that is no longer in view
      rects.exit().remove();
      

      所有代码都可以在我上面提供的链接中找到。

      【讨论】:

      • 谢谢!你所拥有的很酷,但你在底部也有一个参考框架,我试图在没有参考框架的情况下做到这一点:p
      【解决方案3】:

      您可以将图表附加到敏感事件区域(必须是最后一个附加):

      var rect = svg.append("svg:rect")
          .attr("class", "pane")
          .attr("width", w)
          .attr("height", h);
      

      之后(不包括)在该区域添加事件管理

      rect.call(d3.behavior.zoom().x(x).scaleExtent([0.5, 4]).on("zoom", draw));
      

      添加类似的绘图功能

      function draw() {
          svg.select("g.x.axis").call(xAxis);
          svg.select("g.y.axis").call(yAxis);
          svg.select("path.area").attr("d", area);
          svg.select("path.line").attr("d", line);
      }
      

      看这个例子:https://groups.google.com/forum/?fromgroups=#!topic/d3-js/6p7Lbnz-jRQ%5B1-25-false%5D

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-06-21
        • 1970-01-01
        • 2019-05-02
        • 2015-01-18
        • 2016-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多