d3 同步 2 个独立的缩放行为

2024-05-06

我有以下 d3/d3fc 图表

https://codepen.io/parliament718/pen/BaNQPXx https://codepen.io/parliament718/pen/BaNQPXx

该图表的主要区域有缩放行为,y 轴有单独的缩放行为。 可以拖动 y 轴来重新缩放。

我无法解决的问题是,拖动 y 轴重新缩放并随后平移图表后,图表中出现“跳跃”。

显然,这两个缩放行为存在脱节,需要同步,但我正在绞尽脑汁试图解决这个问题。

const mainZoom = zoom()
    .on('zoom', () => {
       xScale.domain(t.rescaleX(x2).domain());
       yScale.domain(t.rescaleY(y2).domain());
    });

const yAxisZoom = zoom()
    .on('zoom', () => {
        const t = event.transform;
        yScale.domain(t.rescaleY(y2).domain());
        render();
    });

const yAxisDrag = drag()
    .on('drag', (args) => {
        const factor = Math.pow(2, -event.dy * 0.01);
        plotArea.call(yAxisZoom.scaleBy, factor);
    });

所需的行为是缩放、平移和/或重新缩放轴,以始终从上一个操作完成的位置应用变换,而无需任何“跳跃”。


好的,所以我又尝试了一次 - 正如我的之前的回答 https://stackoverflow.com/a/61073772/249933,您需要克服的最大问题是 d3-zoom 只允许对称缩放。这是已经存在的事情广泛讨论 https://github.com/d3/d3-zoom/issues/48,我相信 Mike Bostock 将在下一个版本中解决这个问题。

因此,为了解决这个问题,您需要使用多次缩放行为。我创建了一个包含三个图表,一个用于每个轴,一个用于绘图区域。 X 和 Y 缩放行为用于缩放轴。每当 X 和 Y 缩放行为引发缩放事件时,它们的平移值都会复制到绘图区域。同样,当绘图区域发生平移时,x 和 y 分量将被复制到各自的轴行为。

绘图区域的缩放有点复杂,因为我们需要保持纵横比。为了实现这一点,我存储之前的缩放变换并使用比例增量来计算出合适的比例以应用于 X 和 Y 缩放行为。

为了方便起见,我将所有这些都包装到一个图表组件中:


const interactiveChart = (xScale, yScale) => {
  const zoom = d3.zoom();
  const xZoom = d3.zoom();
  const yZoom = d3.zoom();

  const chart = fc.chartCartesian(xScale, yScale).decorate(sel => {
    const plotAreaNode = sel.select(".plot-area").node();
    const xAxisNode = sel.select(".x-axis").node();
    const yAxisNode = sel.select(".y-axis").node();

    const applyTransform = () => {
      // apply the zoom transform from the x-scale
      xScale.domain(
        d3
          .zoomTransform(xAxisNode)
          .rescaleX(xScaleOriginal)
          .domain()
      );
      // apply the zoom transform from the y-scale
      yScale.domain(
        d3
          .zoomTransform(yAxisNode)
          .rescaleY(yScaleOriginal)
          .domain()
      );
      sel.node().requestRedraw();
    };

    zoom.on("zoom", () => {
      // compute how much the user has zoomed since the last event
      const factor = (plotAreaNode.__zoom.k - plotAreaNode.__zoomOld.k) / plotAreaNode.__zoomOld.k;
      plotAreaNode.__zoomOld = plotAreaNode.__zoom;

      // apply scale to the x & y axis, maintaining their aspect ratio
      xAxisNode.__zoom.k = xAxisNode.__zoom.k * (1 + factor);
      yAxisNode.__zoom.k = yAxisNode.__zoom.k * (1 + factor);

      // apply transform
      xAxisNode.__zoom.x = d3.zoomTransform(plotAreaNode).x;
      yAxisNode.__zoom.y = d3.zoomTransform(plotAreaNode).y;

      applyTransform();
    });

    xZoom.on("zoom", () => {
      plotAreaNode.__zoom.x = d3.zoomTransform(xAxisNode).x;
      applyTransform();
    });

    yZoom.on("zoom", () => {
      plotAreaNode.__zoom.y = d3.zoomTransform(yAxisNode).y;
      applyTransform();
    });

    sel
      .enter()
      .select(".plot-area")
      .on("measure.range", () => {
        xScaleOriginal.range([0, d3.event.detail.width]);
        yScaleOriginal.range([d3.event.detail.height, 0]);
      })
      .call(zoom);

    plotAreaNode.__zoomOld = plotAreaNode.__zoom;

    // cannot use enter selection as this pulls data through
    sel.selectAll(".y-axis").call(yZoom);
    sel.selectAll(".x-axis").call(xZoom);

    decorate(sel);
  });

  let xScaleOriginal = xScale.copy(),
    yScaleOriginal = yScale.copy();

  let decorate = () => {};

  const instance = selection => chart(selection);

  // property setters not show 

  return instance;
};

这是一支带有工作示例的笔:

https://codepen.io/colineberhardt-the-bashful/pen/qBOEEGJ https://codepen.io/colineberhardt-the-bashful/pen/qBOEEGJ

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

d3 同步 2 个独立的缩放行为 的相关文章

  • 在 d3.js 中操纵鼠标悬停在“点击区域”

    我想show and hideSVG 中的一个节点 当鼠标移到 mouseout 问题是我的节点内部的形状是一条宽度只有1 5px的路径 因此在鼠标悬停事件中不容易击中该区域 这对用户体验肯定不方便 我想知道是否有办法做到这一点打击范围更广
  • 在d3.js中将2D形状转换为3D,并根据ANGULAR中的值调整高度

    我正在使用 d3 js v6 创建以下 2D 图表表示的 3D 图表 这个圆圈中有多个正方形 每个正方形都根据值分配了一种颜色 值越大 正方形越暗 现在我想将其转换为 3D 形状 其中当值变高时 只有特定正方形的高度会增加 因此结果在某种程
  • 需要js、d3 和 nvd3 集成

    我面临整合的问题要求 questions tagged requirejs with d3 questions tagged d3 and nvd3 questions tagged nvd3 我找到了一个使用 require 的简单解决方
  • 当以编程方式触发 d3.behavior.zoom 事件时,如何设置平移和缩放的初始值?

    下面示例中的方块是具有初始平移和比例设置的 SVG 组的一部分 单击正方形会启动缩放过渡 但过渡设置的初始值与我的默认值不同 这一点从过渡开始时的不和谐就可以明显看出 如何在以编程方式启动的缩放过渡上设置平移和缩放的初始值 var svg
  • 为什么我的 D3 SVG 图上的轴不会更新?

    I have 简单的 D3 散点图 http www raxacoricofallapatorius com test scattertest html我在显示数据的几个不同属性之间切换 但是虽然我可以更改数据点 并按照我想要的方式进行转换
  • Javascript 将对象推送为克隆

    我将 d3 用于交互式网络应用程序 我需要绑定的数据在交互过程中发生变化 并且由 JSON 变量中的一些选定对象组成 为此 我在 JSON 变量上使用了映射 并进行了一些查询来选择适当的对象 对象被推送到列表中 并且该列表被绑定为新数据 我
  • dc lineChart 单击时弹出数据点信息

    我正在尝试检测折线图数据点上的点击 Per this answer dc scatter plot binding onClick event https stackoverflow com a 22772340 1873386 I am
  • 如何处理 d3 中 Beeswarm 图中的碰撞?

    我一直在玩这个例子here https gf neocities org co2bs co2bee html一会儿 我想做的是突出显示图中的单个节点 圆圈 通过使用边框使其变大 稍后我也想在其中添加文本或字母 目前 我已经圈了Bhutan图
  • d3 饼图中的文本被路径覆盖

    我正在尝试按照 d3 的饼图示例进行操作http bl ocks org mbostock 3887235 http bl ocks org mbostock 3887235 我的代码的最小示例 const container graph
  • D3 删除千位的逗号分隔符

    我有一个包含 3 列的 json 其中一列是 年份 该列仅包含年份 没有日期 当我在 x 轴上绘制它时 年份会以逗号分隔符表示数千 所以在 json 中 日期的格式是 Year 1990 在 x 轴上 结果是 1 990 我一直在试图弄清楚
  • 调整发散堆积条形图以使用通用更新模式

    我一直在使用可用的堆积条形图示例here https bl ocks org mbostock b5935342c6d21928111928401e2c8608使用以下代码 var data month Q1 2016 apples 384
  • D3.js 从 file:/// 加载本地数据文件

    我知道D3 js支持使用XHR和JSONP加载数据文件requests https github com mbostock d3 wiki Requests 但就我而言 我将通过从文件系统双击 html 文件来运行它们 这将像file fo
  • Typescript 中未定义的 d3.scale

    我是 Typescript 的新手 2 周 我正在从事包装 d3 js 框架的项目 我在使用 d3 d ts 命名空间 导出模块 导入时遇到问题 我的问题 当我尝试使用 d3 scale linear 时 浏览器控制台中出现错误 TypeE
  • 时间序列折线图与轴不同步

    本实验基于这个d3官方例子 http bost ocks org mike path 我想要实现的是可视化时间序列数据的最后 x 分钟 我有这个代码的副本jsfiddle http jsfiddle net 225dC 3 单击以添加新数据
  • 可以在 d3.js 中使用具有固定圆圈大小的圆圈包布局吗?

    此圆形包布局示例 http bl ocks org 4063269 http bl ocks org 4063269 非常适合我正在从事的项目 但是它会调整所有圆圈相对于彼此的大小 有没有一种简单的方法来指定每个圆的固定半径 我已经搜索了源
  • svg / d3.js 矩形一侧的圆角

    我知道 svg 有一个内置函数可以做圆角 但我只需要在四个角中的 2 个上做圆角 我知道我可以在彼此之上绘制多个矩形来模仿这一点 但这看起来有点俗气 有什么方法可以使用剪辑或任何 d3 js 方法来做到这一点吗 现在我有一个水平条形图 其中
  • 如何使用 d3.js 沿 GeoJSON 路径对对象进行动画处理?

    我正在使用 D3 js 从 GeoJSON 文件生成并渲染路径 效果很好 但现在我想沿着该路径为对象设置动画 我知道如何使用 D3 和标准 SVG 来做到这一点 创建过渡并设置其持续时间 对于过渡的每一帧 使用 Complete 查找沿路径
  • D3.js折线图溢出边距

    我有 d3 js 折线图 它作为 angular js 应用程序的指令包含在内 动态添加的线和 xAxis 以及缩放线上的边距溢出 我必须在图的顶部为每条加载的线创建 Ox 轴 并具有 Ox 和 Oy 单独的缩放可能性 Oy 缩放工作正常
  • SVG 文本在 IE 中消失,直到我单击它

    我在 Internet Explorer Edge 以 Win7 上的为准 中遇到与 SVG 创建和操作相关的问题 在我正在开发的应用程序中 我们使用 d3 生成 SVG 形式的图形 在 Chrome 和 Firefox 中 它们工作得很好
  • D3、TS 和 Angular 2

    我正在尝试将 D3 v4 与 Angular 2 Typescript 一起使用 我目前正在研究 D3 v4 我能够遵循 stackoverflow 中类似问题的一些答案 但没有成功 我已经导入了大部分 D3 库及其类型 我使用的是 TS

随机推荐