D3 平移缩放溢出

Posted

技术标签:

【中文标题】D3 平移缩放溢出【英文标题】:D3 Pan Zoom Overflow 【发布时间】:2013-05-16 22:36:06 【问题描述】:

我想知道您是否可以在以下小提琴中帮助我使用以下 D3js 缩放和平移功能:http://jsfiddle.net/moosejaw/nUF6X/5/

我希望代码(虽然不是很好)是直截了当的。

我有一张总染色体长度乘以总染色体长度的图表。刻度值是每条染色体的单独长度(总和)。刻度被格式化为染色体的名称(对最终用户来说看起来不错)。

我遇到的问题是:

    x 轴和 y 轴标签延伸到图形区域之外。当我没有明确提供刻度值时,标签应该会“消失”。见:

    var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickValues(tickValues)
    .tickFormat(function(d)  
        var ret = bpToChrMBP(d);
        return ret.chr;
    );
    

    如何防止 x 轴在最小值之前不向左平移?也不会向右平移超过最大值?无论我是否放大都会发生这种情况。(y 轴相同,除了顶部和底部)。

    有没有办法让刻度线之间的轴标签“居中”。刻度线的间距不均匀。我尝试对次要刻度线使用细分,但不能正确地在刻度线之间细分。

任何帮助将不胜感激!

马特

【问题讨论】:

【参考方案1】:

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

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

那么对于xAxisyAxis,不要使用tickValues,而是使用tickValues2

【讨论】:

是的...我同意剪辑路径不会提供与轴相同的功能,但它是最好的替代方案/解决方法。感谢您的解决...我知道我错过了什么! 超级解决方案。像魅力一样工作。【参考方案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("底部") // .tickValues(tickValues) .tickFormat(函数(d) var ret = bpToChrMBP(d); 返回ret.chr; );

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

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

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

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

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

【讨论】:

感谢您尝试回答,但这并不能回答或解决我的问题/问题。我可以制作散点图并放大。那不是问题。问题是一旦放大就会限制平移。

以上是关于D3 平移缩放溢出的主要内容,如果未能解决你的问题,请参考以下文章

d3 v7 中的简单平移和缩放

D3.JS 具有实时数据、平移和缩放的时间序列折线图

使用canvas和d3.js分层圆结构计算缩放和平移的方法

html 使用D3在Scatterplot中演示缩放和平移

D3.js 缩放和平移可折叠树图

Javascript / D3.js - 绘制大型数据集 - 提高 d3.js 绘制的 svg 图表中的缩放和平移速度