10

我想知道您是否可以在以下小提琴中帮助我使用以下 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 回答 2

7

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

  • 我不确定您所说的超出图形区域是什么意思。标签应该在里面chart-area?如果您的意思是在平移时,标签延伸到轴之外,则可以通过clip-path明智地再使用两个 s 来解决问题,尽管这不允许优雅地淡化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);
    }
});

然后代替使用tickValuesfor xAxisand yAxis,使用tickValues2.

于 2013-05-26T11:28:57.820 回答
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) .orient("bottom") // .tickValues(tickValues) .tickFormat(function(d) { var ret = bpToChrMBP(d); return ret.chr; });

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

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

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

    函数 translateTo(p, l) { l = point(l); 翻译[0] += p[0] - l[0]; 翻译[1] += p[1] - l[1]; }

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

于 2013-05-24T08:54:41.403 回答