d3 单击时聚焦于节点

2024-04-26

我正在尝试实现一种力布局,其中单击节点将能够专注于节点周围的区域。我看过一些例子,但我收到一个错误,上面写着link.bounds is not defined。我认为边界没有为力布局定义,并且适用于我从中获取聚焦功能的示例http://bl.ocks.org/mbostock/9656675 http://bl.ocks.org/mbostock/9656675

值应该是什么var dx, dy, x and y?

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>

var width = 960,
    height = 500,
    active = d3.select(null);

var zoom = d3.behavior.zoom()
    .translate([0, 0])
    .scale(1)
    .scaleExtent([1, 8])
    .on("zoom", zoomed);    

var force = d3.layout.force()
    .size([width, height])
    .charge(-400)
    .linkDistance(40)
    .on("tick", tick);

var drag = force.drag()
    .on("dragstart", dragstart);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .on("click", reset);

var link = svg.selectAll(".link"),
    node = svg.selectAll(".node");

var g = svg.append("g");    

d3.json("miserables.json", function(error, graph) {
  if (error) throw error;

  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  link = link.data(graph.links)
    .enter().append("line")
      .attr("class", "link");

  node = node.data(graph.nodes)
    .enter().append("circle")
      .attr("class", "node")
      .attr("r", 12)
      .on("click", clicked)
      .call(drag);
});

function tick() {
  link.attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

  node.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
}

function clicked(d){
    if (active.node() === this) return reset();
  active.classed("active", false);
  active = d3.select(this).classed("active", true);

  var bounds = link.bounds(d),
      dx = bounds[1][0] - bounds[0][0],
      dy = bounds[1][1] - bounds[0][1],
      x = (bounds[0][0] + bounds[1][0]) / 2,
      y = (bounds[0][1] + bounds[1][1]) / 2,
      scale = Math.max(1, Math.min(8, 0.9 / Math.max(dx / width, dy / height))),
      translate = [width / 2 - scale * x, height / 2 - scale * y];

  svg.transition()
      .duration(750)
      .call(zoom.translate(translate).scale(scale).event);
} 

function reset() {
  active.classed("active", false);
  active = d3.select(null);

  svg.transition()
      .duration(750)
      .call(zoom.translate([0, 0]).scale(1).event);
}    


function dragstart(d) {
  d3.select(this).classed("fixed", d.fixed = true);
}

function zoomed() {
  g.style("stroke-width", 1.5 / d3.event.scale + "px");
  g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}    

</script>

您可以通过使用以下命令重写函数来重新创建强制布局上的缩放效果bbox单击的节点的:

function clicked(d){
  if (active.node() === this) return reset();
  active.classed("active", false);
  active = d3.select(this).classed("active", true);

  var bbox = active.node().getBBox(),
      bounds = [[bbox.x, bbox.y],[bbox.x + bbox.width, bbox.y + bbox.height]]; //<-- the bounds from getBBox

  var dx = bounds[1][0] - bounds[0][0],
      dy = bounds[1][1] - bounds[0][1],
      x = (bounds[0][0] + bounds[1][0]) / 2,
      y = (bounds[0][1] + bounds[1][1]) / 2,
      scale = Math.max(1, Math.min(8, 0.9 / Math.max(dx / width, dy / height))),
      translate = [width / 2 - scale * x, height / 2 - scale * y];

  svg.transition()
      .duration(750)
      .call(zoom.translate(translate).scale(scale).event);
} 

运行代码:

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>

var width = 960,
    height = 500,
    active = d3.select(null);

var zoom = d3.behavior.zoom()
    .scaleExtent([1, 8])
    .on("zoom", zoomed);    
    
var force = d3.layout.force()
    .size([width, height])
    .charge(-400)
    .linkDistance(40)
    .on("tick", tick);

var drag = force.drag()
    .on("dragstart", dragstart);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
   // .on("click", reset);

var g = svg.append("g");

var link = g.selectAll(".link"),
    node = g.selectAll(".node");

svg
    .call(zoom) // delete this line to disable free zooming
    .call(zoom.event);

d3.json("https://rawgit.com/d3/d3-plugins/master/graph/data/miserables.json", function(error, graph) {
  if (error) throw error;
  
  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  link = link.data(graph.links)
    .enter().append("line")
      .attr("class", "links")
      .style("stroke", "#999");

  node = node.data(graph.nodes)
    .enter().append("circle")
      .attr("class", "node")
      .attr("r", 12)
      .on("click", clicked)
      //.call(drag);
});

function tick() {
  link.attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

  node.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
}

function clicked(d){
  if (active.node() === this) return reset();
  active.classed("active", false);
  active = d3.select(this).classed("active", true);

  var bbox = active.node().getBBox(),
      bounds = [[bbox.x, bbox.y],[bbox.x + bbox.width, bbox.y + bbox.height]];

  var dx = bounds[1][0] - bounds[0][0],
      dy = bounds[1][1] - bounds[0][1],
      x = (bounds[0][0] + bounds[1][0]) / 2,
      y = (bounds[0][1] + bounds[1][1]) / 2,
      scale = Math.max(1, Math.min(8, 0.9 / Math.max(dx / width, dy / height))),
      translate = [width / 2 - scale * x, height / 2 - scale * y];

  svg.transition()
      .duration(750)
      .call(zoom.translate(translate).scale(scale).event);
} 

function reset() {
  active.classed("active", false);
  active = d3.select(null);

  svg.transition()
      .duration(750)
      .call(zoom.translate([0, 0]).scale(1).event);
}    


function dragstart(d) {
  d3.select(this).classed("fixed", d.fixed = true);
}

function zoomed() {
  console.log(d3.event)
  g.style("stroke-width", 1.5 / d3.event.scale + "px");
  g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}    

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

d3 单击时聚焦于节点 的相关文章

  • 如何使用 jsPDF 和 HTML2Canvas 从网站获取多页 pdf?

    我有一个使用 HTML2Canvas 来截取屏幕截图的脚本div在页面中 然后使用 jsPDF 将其转换为 pdf 问题是生成的 pdf 只有一页 而屏幕截图在某些情况下需要不止一页 例如 屏幕截图大于 8 5x11 宽度很好 但我需要它来
  • JavaScript RegEx 到 CamelCase 连字符的 CSS 属性

    我正在尝试更改 CSS 属性 如下所示 moz border radius 像这样的 JavaScript CSS 属性 MozBorderRadius 我正在使用这个正则表达式 var exp new RegExp a z gi cons
  • 通过 POST 将 JSON 编码的变量从 PHP 传递到 Javascript

    我有一个多维数组 我想将其发送到带有 Javascript 的 PHP 脚本 该脚本解析 JSON 数据并将其绘制在 Google 地图上 我正在尝试使用表单来模拟它
  • Cloud Functions for Firebase - 创建新用户时写入数据库

    我对 Firebase 和 javascript 语言的 Cloud Functions 非常陌生 我试图在每次创建用户写入数据库时 添加一个函数 这是我的代码 const functions require firebase functi
  • 如何将 React Native 按钮放置在屏幕底部以在多个 ios 设备上工作

    我还年轻 在网上搜索可以帮助我解决这个问题的教程 但没有找到任何东西 我知道如何将屏幕上的按钮从 A 点移动到 B 点 问题是我似乎无法将其固定在底部以在我的 ios 模拟器的不同外形尺寸上工作 到目前为止 我已经尝试过 marginTop
  • 调用 DynamoDB 中的用户数据时渲染得太晚

    所以我试图从dynamoDB 我正在使用一个GraphQL API访问我的数据库 在提供的代码的注释部分中 我提到我已经尝试过users 1 friends map 它确实返回正确的朋友列表数组 但用户似乎直到朋友列表渲染后才被设置 我应该
  • 如何滚动到 div 元素底部 Selenium Webdriver

    我有一个用例 其中网页上有一个 div 元素 只要您单击链接 它就会出现一个弹出对话框 它不是实际的弹出窗口 它类似于当您单击链接进行检查时在 Facebook 中打开的对话框 对您的帖子的反应等 我使用 Selenium WebDrive
  • 将画布输出图像调整为特定尺寸(宽度/高度)

    我有一个大画布 5000x5000 我想拍一张照片并在客户端创建一个缩略图 我可以使用捕获图像canvas toDataURL但我该如何调整它的大小 我必须创建一个新的吗
  • jQuery - 解析 JSON 数据 - 变量名称遇到问题

    我第一次深入研究 JSON 数据的使用 不过我有一些使用 jQuery 的经验 我发布到此 URL tumblr api jyoseph com api read json 我想做的是输出返回的 json 到目前为止我所拥有的 docume
  • Excel 到 JSON 的 JavaScript 代码?

    我想将excel表格数据转换为json 它必须是动态的 因此有一个上传按钮 用户可以在其中上传 Excel 工作表 然后将数据转换为 json 您能给我提供 javascript 代码吗 我尝试了 SheetJS 但无法弄清楚 我更喜欢直接
  • “对象不是函数” - onclick 事件

    在开始之前 不 我没有发现分号的问题 并且我没有向函数传递任何值 当我尝试从控制台执行函数 login 时 它工作得很好 但是当我单击 HTML 输入按钮来调用它时 我收到 Uncaught TypeError object is not
  • 为什么自动关闭脚本元素不起作用?

    浏览器无法正确识别的原因是什么 只有这一点是公认的 这是否打破了 XHTML 支持的概念 注意 此声明至少对于所有 IE 6 8 beta 2 都是正确的 XHTML 1 规范的非规范性附录 HTML 兼容性指南 指出 3 元素最小化和空元
  • React Native:如何在组件中添加脚本标签

    我正在尝试在 React Native 应用程序的组件内添加标签 下面是我的代码 它似乎不起作用 谁能告诉我如何解决这个问题 import React Component from react import PropTypes from p
  • 使用 Node.js 将对象写入文件

    我已经在 stackoverflow google 上搜索过这个 但似乎无法弄清楚 我正在抓取给定 URL 页面的社交媒体链接 该函数返回一个包含 URL 列表的对象 当我尝试将此数据写入不同的文件时 它会输出到该文件 object Obj
  • Javascript 沙箱模式示例实现

    在 Stoyan Stefanov 的伟大著作 JavaScript Patterns 的第 101 页中 他解释了沙箱模式 我非常喜欢他的书 但我真的错过了一些现实生活中的例子 然后更好地理解他所谈论的内容 我正在寻找一个现实生活中的工作
  • 给出 HTML 和 Xpath 时突出显示

    给定 HTML 作为字符串 Xpath 和偏移量 我需要强调这个词 在下面的例子中我需要强调Child 1 HTML 文本 h2 Children h2 Joe has three kids br ul li a href Child 1
  • MSIE 和 addEventListener Javascript 中出现问题?

    document getElementById container addEventListener copy beforecopy false 在Chrome Safari中 上面将在复制页面内容时运行 beforecopy 函数 MSI
  • 按数字字段排序,其中时间戳位于 Cloud Firestore 中的给定日期?

    在我的 Firestore 数据库中 我的集合中有一些文档 如下所示 name Item 1 count 2 timestamp January 29 2018 at 3 43 12 PM UTC 8 我正在尝试查询这个集合 以便文档按以下
  • JavaScript - 离焦事件?

    我想要做的是显示带有文本颜色的输入字段black 然后 当该人在输入字段内单击时 onfocus 我想将文本颜色更改为red 然后 当该人单击输入字段外部 不再焦点 时 我想将文本颜色更改回black 我知道如何处理 JavaScripto
  • 查找可以具有绝对定位元素的页面/文档内容的完整高度

    我试图获取页面的高度 可能会在 iframe 中加载 该页面具有绝对定位的元素 这些元素延伸到页面正常底部以下 以下是我尝试过的事情 document body scrollHeight document body offsetHeight

随机推荐