javascript - 有什么方法可以捕获缩放/刷过的 d3.js 多线图位置吗?

标签 javascript angular d3.js

我使用具有缩放和画笔功能的 d3.js 创建了一个多线图。所有功能都运行良好,除了当我刷新我的浏览器选项卡时,我在图表中完成的缩放/画笔被重置并且图表以其初始状态显示。 有什么方法可以使用任何 d3.js 函数记录缩放/画笔位置,并且每当我刷新浏览器页面时,我都可以看到上次缩放/画笔状态的图形。 附上我用于缩放和画笔的代码片段。

const brush = d3.brushX()
        .extent([[0, 0], [this.width, this.height2]])
        .on("brush end", () => {
          if (d3.event.sourceEvent && d3.event.sourceEvent.type === "zoom") {
            return;
          } // ignore brush-by-zoom
          const s = d3.event.selection || this.x2.range();
          this.x.domain(s.map(this.x2.invert, this.x2));
          legendDataLine.selectAll(".line").attr("d", (d: any) => line(d.values));
          focus.select(".axis--x").call(d3.axisBottom(this.x));
          this.svg.select(".zoom").call(zoom.transform, d3.zoomIdentity
              .scale(this.width / (s[1] - s[0]))
              .translate(-s[0], 0));
        });

const zoom = d3.zoom()
        .scaleExtent([1, Infinity])
        .translateExtent([[0, 0], [this.width, this.height]])
        .extent([[0, 0], [this.width, this.height]])
        .on("zoom", () => {
          if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") {
            return;
          } // ignore zoom-by-brush
          const t = d3.event.transform;
          this.x.domain(t.rescaleX(this.x2).domain());
          legendDataLine.selectAll(".line").attr("d", (d: any) => line(d.values));
          focus.select(".axis--x").call(d3.axisBottom(this.x));
          context.select(".brush").call(brush.move, this.x.range().map(t.invertX, t));
        });

最佳答案

想到了一种方法,使用 URL 查询字符串。在您的示例代码或规范的画笔和缩放示例中 here , 只有缩放变换的两个部分很重要:比例 (k) 和 x 值。

我们可以记录每个缩放事件的xk,并在URL查询字符串中添加或修改它们。我们不需要担心在画笔事件中执行此操作,因为画笔事件会触发缩放(并且每次缩放都会触发画笔)。为了避免无限循环,画笔引起的缩放事件被忽略:

  if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush 

因此,我们可以在此之前设置 URL 参数:

function zoomed() {
  var t = d3.event.transform;
  // Update url:
  window.history.replaceState( {} , '', '?k='+t.k+"&x="+t.x )

  // ... rest of zoom functionality
}

这会更新查询字符串和 URL,并且不会重新加载页面,还有其他选项可能会提供更好的兼容性但不那么简洁(如果我没记错的话这不适用于 IE) . 由于有许多更好的资源可用于设置查询字符串参数的方法,因此我不会在这里详细介绍。

现在我们应该在更新的 URL 中存储了 xk 值。

使用更新后的 URL,重新加载页面将加载地址中包含缩放状态参数的页面。剩下的就是在页面加载时应用它们,当然,如果它们已设置的话。

加载数据并创建所有内容后,我们可以检查 URL 中是否提供了缩放参数并应用适当的缩放转换:

 var url = (new URL(document.location)).searchParams;
 if(url.has("k") && url.has("x")) {
   svg.select(".zoom").call(zoom.transform, d3.zoomIdentity.translate(+url.get("x"),0).scale(+url.get("k")));
 }

我对 URL 的检索是基本的,我不会再详细说明如何提取参数(有关此方法的更多信息,请参阅 MDN)。如果存在 xk 参数,它们将被强制转换为数字并用于创建 d3 缩放转换(使用 d3.zoomIdentity 作为基础),这是用于通过适当的变换触发缩放事件。通过这样做,存储在 URL 中的缩放参数用于在重新加载、后退、前进或使用更新的 URL 打开链接等时将图形更新到其最后状态。

因为这在 Stack Overflow 片段中可能不起作用,所以我创建了一个示例 here .

关于javascript - 有什么方法可以捕获缩放/刷过的 d3.js 多线图位置吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56983969/

相关文章:

javascript - 在 php echo javascript 中使用 onclick

html - 如何访问 *ngFor 中的 'index' 并对其进行编辑(无法删除列表中的多个项目)

javascript - 如何返回 d3.js 中路径的 y 坐标?

javascript - 用ES6绘制饼图

javascript - 如何使用 java 在 Jquery ajax 调用中下载 PDF

javascript - 无法正确获取下拉列表的值

javascript - 使用 withRouter() 重定向时显示所有组件

javascript - XMLHttpRequest 错误 - "No ' Access-Control-Allow-Origin' header 出现在请求的资源上。”

angular2 react 形式 |未捕获的类型错误 : Cannot set property stack of [object Object] which has only a getter

javascript - jquery .ready() 等同于 d3js?