D3平移缩放溢出问题

10

我想知道您是否可以帮助我解决以下问题:在这个fiddle中实现D3js的缩放和平移功能:http://jsfiddle.net/moosejaw/nUF6X/5/

我希望代码(虽然不是很好)都很简单明了。

我的图表按总染色体长度绘制,刻度值是每条染色体的长度总和。 刻度已格式化为染色体名称(以使最终用户看起来更美观)。

我遇到的问题是:

  1. x轴和y轴标签超出了图形区域。 当我没有显式提供刻度值时,标签会“消失”,如下所示:

    var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickValues(tickValues)
    .tickFormat(function(d) { 
        var ret = bpToChrMBP(d);
        return ret.chr;
    });
    
  2. 如何防止x轴在最小值之前向左平移?同时不要让其在最大值之后向右平移?无论我是否缩放都会发生这种情况。 (y轴也是如此,除了顶部和底部)。

  3. 是否有一种方法可以在刻度标记之间“居中”轴标签。 刻度标记不是均匀分布的。 我尝试使用次刻度标记进行细分,但无法正确地在刻度标记之间进行细分。

非常感谢您的任何帮助!

Matt

2个回答

7
这个代码片段可以解决你的大部分问题:http://jsfiddle.net/CtTkP/。以下是一些解释:
  • 我不确定你所说的“超出图形区域”的意思是什么。标签应该放在chart-area里吗?如果你的意思是在拖动时,标签会超出轴线,这个问题可以通过巧妙地使用两个额外的clip-path来解决,但这不允许像svg.axis翻译那样优雅地淡化数值:
var clipX = svg.append("clipPath")
      .attr('id', 'clip-x-axis')
      .append('rect')
      .attr('x', 0)
      .attr('y', 0)
      .attr('width', width)
      .attr('height', margin.bottom);

svg.append("g")
    .attr("class", "x axis")
    .attr('clip-path', 'url(#clip-x-axis)')
    .attr("transform", "translate(0, " + height + ")")
    .call(xAxis);

// ...

var clipY = svg.append("clipPath")
      .attr('id', 'clip-y-axis')
      .append('rect')
      .attr('x', - margin.left)
      .attr('y', 0)
      .attr('height', height)
      .attr('width', margin.left);

svg.append("g")
    .attr("class", "y axis")
    .attr('clip-path', 'url(#clip-y-axis)')
    .call(yAxis);

为了防止缩放超出限制,您需要手动限制缩放的 translate 值:
function zoomed() {

     var trans = zoom.translate(),
         scale = zoom.scale();

     tx = Math.min(0, Math.max(width * (1 - scale), trans[0]));
     ty = Math.min(0, Math.max(height * (1 - scale), trans[1]));

     zoom.translate([tx, ty]);

    svg.select(".x.axis").call(xAxis);
    svg.select(".y.axis").call(yAxis);

    // ...

这将防止图形超出限制范围。

  • 由于您显式地覆盖了tickValues,因此您可以调整值以使其居中:
var tickValues2 = [];
tickValues.forEach(function (t, idx) {
    if (idx < tickValues.length - 1) {
        tickValues2.push((t + tickValues[idx + 1]) / 2);
    }
});

然后,不要使用xAxisyAxistickValues,而是使用tickValues2


是的...我同意clip-path不能像axis一样提供相同的功能,但它是最好的替代方案/解决方法。感谢您的解决方案...我知道我漏掉了什么! - mattjvincent
超级解决方案。运行得非常好。 - Ronak Bhandari

2
问题在于您手动设置了tickValues,而不是让x和y比例尺自动设置。尝试将其注释掉: // .tickValues(tickValues) var x = d3.scale.linear().rangeRound([0, width]).domain(d3.extent(tickValues)); var xAxis = d3.svg.axis() .scale(x) .orient("bottom") // .tickValues(tickValues) .tickFormat(function(d) { var ret = bpToChrMBP(d); return ret.chr; });
允许显式设置tickValues的快速解决方案可能是为每个轴定义剪切路径。
您也不需要make_x_axis函数(y轴同样)。请查看此可缩放散点图示例:http://bl.ocks.org/ameliagreenhall/raw/d30a9ceb68f5b0fc903c/ 为了防止左/右平移超过截止点,您需要重新实现
function translateTo(p, l) { l = point(l); translate[0] += p[0] - l[0]; translate[1] += p[1] - l[1]; }
您可以尝试在定义轴时调整dx和dy属性。

感谢您的回答,但这并没有回答或解决我的问题。我可以制作一个散点图并进行缩放,这不是问题。问题在于限制缩放后的平移。 - mattjvincent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接