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。带条的旋转地球仪

    我正在尝试创建带有像这样的酒吧的旋转地球仪这个例子 http data arts appspot com globe 你可以看我的例子here http jsfiddle net zeleniy jrh5xucs 一切都很顺利 直到酒吧超出
  • D3:使用 d3-tile 缩放到边界框

    我已成功将 D3 矢量 地图分层到从 Mapbox 提取图块的 d3 tile 光栅 地图之上 手动缩放效果非常好 矢量和光栅都是同步的 我现在正在尝试实施迈克 博斯托克 缩放到边界框 https bl ocks org mbostock
  • 我可以补间 D3 弧的结束角度,但不能补间起始角度。我究竟做错了什么?

    我只是在玩这个演示并自己重新创建它 http bl ocks org mbostock 5100636 http bl ocks org mbostock 5100636 我可以定义一个新的 endAngle 并且它会很好地制作动画 但现在
  • D3js 多折线图 mouseOver

    我正在努力适应this http bl ocks org mbostock 3902569D3js 折线图示例 将鼠标悬停在我的多线图表上的使用情况 看起来d3 mouse this 0 on the mousemove函数生成以下错误 无
  • d3 地理投影从正交到 X 的过渡

    我正在开发一个教育地图项目 其中显示不同的地图投影 我想在选择不同投影之间实现变形过渡 我找到了一个很好的例子来实现它 并且我没有遇到太多的麻烦来重新创建它 不幸的是 我还需要裁剪投影的功能 这与目标状态完美配合 但在改变投影时则不然 当选
  • 如何使用 d3.v4 中的 JSON 数据创建树布局 - 不使用 stratify()

    我正在尝试将一些 d3 代码从 v3 更新到版本 4 我有一个使用 JSON 数据的树形图 d3 v4 示例展示了如何使用 stratify 将表格数据 例如flare csv 转换为分层数据https bl ocks org mbosto
  • 使用 d3 进行多级/分组轴标签

    我想知道是否有一种简单的方法可以在 d3 中添加多级 分层 分组轴标签 例如 如果我有一个折线图 其中 x 轴的月份名称跨越多年 那么我还希望将年份作为月份名称下方的标签 因此它看起来像这样 Oct Nov Dec Jan Feb Mar
  • 在 d3 中应用转换时出现错误

    我正在尝试对我在 d3 中设计的条形图应用一些过渡效果 这是我的代码 svg selectAll bar data data enter append g attr class bar append rect attr rx barRadi
  • 反转比例函数

    这对我来说很有趣 看下面的D3代码 var scale d3 scale linear domain 100 500 range 10 350 scale 100 Returns 10 scale 300 Returns 180 scale
  • D3 v4 在同一元素上进行画笔和缩放(鼠标事件不冲突)

    我的目标是构建一个使用两者的 D3 v4 图表d3 zoom https github com d3 d3 zoom and d3 brush https github com d3 d3 brush一起 如下 当鼠标位于 x 轴上时 用户
  • d3.event.translate 在触摸设备的缩放上包含 NaN

    我使用 d3 为我的 svg 编写了一个自定义缩放函数 如下所示 Zoom behavior function myzoom xpos d3 event translate 0 ypos d3 event translate 1 vis a
  • D3 将现有 SVG 字符串(或元素)追加(插入)到 DIV

    我到处寻找这个问题的答案 并找到了一些我认为可能有用的资源 但最终没有让我找到答案 这里有一些 外部SVG http bl ocks org mbostock 1014829 嵌入SVG https stackoverflow com qu
  • 根据边界动态设置初始 d3 缩放 - V4

    我要在页面上显示大量节点 大多数情况下 由于节点放置 圆圈会超出屏幕的可见区域 有没有办法根据节点的整个边界框动态设置初始缩放级别 以便所有节点都适合屏幕的可见区域 Updated 我为此添加了一个小提琴https jsfiddle net
  • 在d3.js中将2D形状转换为3D,并根据ANGULAR中的值调整高度

    我正在使用 d3 js v6 创建以下 2D 图表表示的 3D 图表 这个圆圈中有多个正方形 每个正方形都根据值分配了一种颜色 值越大 正方形越暗 现在我想将其转换为 3D 形状 其中当值变高时 只有特定正方形的高度会增加 因此结果在某种程
  • nvd3 格式化日期始终返回 1970-01-01

    我正在尝试使用构建折线图nvd3 for d3js但我在 x 轴上使用日期域时遇到了一些问题 这是我的代码 data lineChart key key1 values x 2014 04 20 y 6 x 2014 04 13 y 5 x
  • 如何根据D3中的数据创建元素?

    看着sample https github com mbostock d3 wiki Selections wiki data d3 select body selectAll div data 4 8 15 16 23 42 enter
  • c3js数据标签的位置

    有没有可能的方法来更改数据上方标签的位置c3条形图 在官方文档中 很好地解释了如何通过操作 y 和 x 整数来更改 x 和 y 测量轴上标签的位置 但我没有找到任何数据标签 我试图用简单的方式指出它d3其上c3是基于但是console lo
  • 如何在 Angular 2 中实现 D3

    我想将这段代码从 d3 js 实现到 Angular 2 组件 但我不知道如何将 js 文件调用到组件 ts 文件中 我找到了一些折线图的代码 包括index html和lineChart js 我怎样才能调用javascriptngAft
  • 将json解析为条形图d3js

    我正在尝试使用 json url 创建条形图 关于印象和时间 我认为我没有正确引用 data data 中的数据 如何从 d3 中的 json 文件访问印象字段 var url https script google com macros
  • 如何进行多个 d3 窗口大小调整事件

    我有三个svg一页上的元素 每个元素都由 D3 陪伴 每个都有自己的页面调整大小逻辑 由我写的简单模块 https github com TimeMagazine d3 base让他们做出反应 问题在于 只有最后一个调整大小事件被触发 因为

随机推荐