You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

D3.js V4甘特图iPad端X轴缩放平移异常问题求助

修复iPad端D3.js甘特图缩放平移异常问题

问题分析

iPad端出现的缩放时内容上移、恢复后下移,且无法精准针对区块缩放的问题,核心原因是:

  • 触摸设备的默认浏览器行为(如滚动、缩放)干扰了D3的触摸事件处理
  • d3-xyzoom在触摸操作下会产生y轴方向的意外平移/缩放,虽然代码中强制ky=1但未锁定y轴平移
  • 触摸事件的preventDefault未正确生效(默认passive: true导致无法阻止默认行为)

修复方案及代码修改

1. 完善触摸事件拦截,阻止浏览器默认行为

修改SVG的触摸事件监听,覆盖touchstart和touchmove,并设置passive: false确保preventDefault生效:

const svg = d3.select("#chart").append("svg")
    .attr("width", WIDTH)
    .attr("height", HEIGHT)
    .on("touchstart touchmove", function () {
        d3.event.preventDefault();
    }, { passive: false }); // 关键:禁用passive模式,确保能阻止默认行为

2. 完全锁定y轴的平移与缩放

在zoomer函数中,不仅强制y轴缩放比例为1,还固定y轴平移值为初始位置(避免触摸操作产生y方向偏移):

function zoomer() {
    const FULL_DATE_RANGE_MILLISECS = 604800000;
    const WEEK_NUMBER_RANGE_MILLISECS = 21427200000;

    let transform = d3.event.transform;

    // 完全锁定y轴:缩放比例固定为1,平移固定为0(对应g元素初始位置)
    transform.ky = 1;
    transform.y = 0; 

    g.attr("transform", `translate(${transform.x},${transform.y}) scale(${transform.kx},${transform.ky})`);

    // 以下原有逻辑保持不变
    var new_xScale = transform.rescaleX(xScale);
    var visibleTimeSpan = new_xScale.domain()[1] - new_xScale.domain()[0];
    if (visibleTimeSpan < FULL_DATE_RANGE_MILLISECS) {
        xAxis.tickFormat(d3.timeFormat('%b %d, %y'));
    } else if (visibleTimeSpan < WEEK_NUMBER_RANGE_MILLISECS) {
        xAxis.tickFormat(function (date) {
            return "#" + getWeekNumber(date) + ', \'' + d3.timeFormat('%y')(date);
        });
    } else {
        xAxis.tickFormat(d3.timeFormat('%b %Y'));
    }

    axisG.call(xAxis.scale(new_xScale));
}

3. 配置xyzoom限制y轴范围

在xyzoom初始化时,添加translateExtent限制y轴的平移范围,从根源上阻止y轴产生偏移:

svg.call(xyzoom
    .extent([[0, 0], [WIDTH, HEIGHT]])
    .scaleExtent([.5, 8])
    .translateExtent([[0, 0], [WIDTH, 0]]) // 限制y轴只能在0位置平移
    .on("zoom", zoomer));

4. 调整xyzoom的缩放比例配置

将原有的scaleRatio([1, 0])改为scaleRatio([1, 1]),确保y轴缩放比例固定为1,避免插件内部产生异常缩放逻辑:

var xyzoom = d3.xyzoom();
xyzoom.scaleRatio([1, 1]); // 固定x、y缩放比例为1,后续通过代码强制仅x轴缩放

验证效果

修改后,iPad端的触摸操作将仅触发x轴的平移与缩放,不会再出现y方向的偏移,同时可以精准针对特定区块进行缩放操作。

内容的提问来源于stack exchange,提问作者NoveltyPachyderm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:00:08