D3 Pan Zoom Overflow

时间:2013-05-22 01:49:19

标签: javascript svg d3.js zoom pan

我想知道你是否可以帮助我完成以下小提琴中的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. 有没有办法在刻度线之间“居中”轴标签。刻度线的间距不均匀。我尝试使用细分作为次要刻度线,但是没有正确地在刻度线之间进行细分。

  4. 非常感谢任何帮助!

    马特

2 个答案:

答案 0 :(得分:7)

这个小提琴解决了你的大部分问题:http://jsfiddle.net/CtTkP/ 解释如下:

  • 我不确定超出图表区域的含义。标签应 insde 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);
    }
});

然后使用tickValuesxAxis而不是yAxis使用tickValues2

答案 1 :(得分:2)

  1. 问题是您手动设置tickValues,而不是让x和y刻度为您做。尝试将其评论出来:// .tickValues(tickValues)

    var x = d3.scale.linear()。rangeRound([0,width])。domain(d3.extent(tickValues));

    var xAxis = d3.svg.axis()       .scale(x)的       。东方(“底部”)       // .tickValues(tickValues)       .tickFormat(function(d){           var ret = bpToChrMBP(d);           return ret.chr;       });

  2. 允许明确设置tickValues的快速而肮脏的修复可能是为每个轴定义一个clippingPath。

    您也不需要make_x_axis功能(y轴相同)。看看这个可缩放的散点图示例:http://bl.ocks.org/ameliagreenhall/raw/d30a9ceb68f5b0fc903c/

    1. 为防止左/右平移超过截止点,您必须重新实施d3.behavior.zoom()。现在有一个名为mousemove的函数调用translateTo,此函数没有限制:

      function translateTo(p,l){   l = point(l);   translate [0] + = p [0] - l [0];   translate [1] + = p [1] - l [1]; }

    2. 您可以在定义轴时尝试使用dxdy属性。