D3 有界平移

D3 Bounded Panning

我已经在这几天了,我无法让这张图表遵守平移界限。最初,数据可能会从页面上拉出负面和正面数据,但我已经能够通过关注 this 博客 post 来阻止负面数据。我将在此处粘贴我认为是相关代码的内容,但该文件太长而无法包含。

有问题的图表是由根据梯度着色的串联区域对象组成的海拔图。

注释掉的那一行引起了麻烦。我用问号代替了应该是最大界限的地方。由于某种原因,我找不到数据区域的最大界限。

这是一个Plunkr

// Set up the size of the chart relative to the div
var x = d3.scale.linear().range([0, (width-80)]);
var y = d3.scale.linear().range([height, 0]);
var y1 = d3.scale.linear().range([height, 0]);

// Define the look of the axis
var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(5);
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5);
var yAxisRight = d3.svg.axis().scale(y1).orient("left").ticks(5);

// Areas are segments of the chart filled with color
var area = d3.svg.area()
    .x(function(d) { return x(d.distance); })
    .y0(height)
    .y1(function(d) { return y(d.elevation); });

// Functions for handling zoom events
var gradientZoomListener = d3.behavior.zoom()
    .scaleExtent([1, 10])
    .on("zoom", gradientZoomHandler);

function gradientZoomHandler() {    
    var t = gradientZoomListener.translate(),
      tx = t[0],
      ty = t[1];
    tx = Math.min(tx, 0);
//  tx = Math.max(tx, ??);
    gradientZoomListener.translate([tx,ty])

    gradientChart.select(".x.axis").call(xAxis);
    gradientChart.select(".y.axis").call(yAxis);  
    gradientChart.selectAll('.area').attr('d', area);    
}

在这种情况下,最直观的方法是检查比例将输入域的边界映射到什么,而不是检查像素值。这个想法是域的下限应该映射到 0(输出范围的下限)或更小,上限映射到输出范围的上限或更多。

如果下限映射到小于 0,则该值位于图形的左侧,即显示的最低值大于下限。如果大于 0,则 y 轴和第一个值之间必须有一个间隙。同样对于上界,如果它映射到小于输出范围的上界,那么它和图的末尾之间一定有一个间隙。

在代码中,如下所示。

if(x(xExtent[0]) > 0) {
      tx = 0;
} else if(x(xExtent[1]) < x.range()[1]) {
      tx -= x(xExtent[1]) - x.range()[1];
}

唯一重要的事情是在最大值和图表末尾之间存在差距时调整平移值。这个差距的大小是最大输入值投影到的位置和最大输出值之间的差异。然后从当前翻译值中减去差距以关闭它。

完整示例here。请注意,我已经移动了一些代码以访问只有在读取数据时才知道的值。

y 轴的工作方式相同。