【问题标题】:D3.js - Labeling nodes with image in Force-LayoutD3.js - 在 Force-Layout 中使用图像标记节点
【发布时间】:2017-02-15 22:36:21
【问题描述】:

我的 Codepen 中有以下代码可以渲染精灵标志(来自 CSS),但它不在应该基于节点位置的位置。

事实上,我可以从顶部的标志精灵中拖动节点!

查看一些console.logs,似乎function ticked()中的d.xd.y位置在调用节点时没有通过。

我不知道如何解决这个问题

const width = w - (margin.left + margin.right);
const height = h - (margin.top + margin.bottom);

let flagNodes = d3.select("#canvas")
                  .append("div")
                  .classed("flag-nodes",true)

let svg = d3.select("#canvas")
              .append("svg")
              .attr("id","chart")
              .attr("width", w)
              .attr("height", h)

let chart = svg.append("g")
                .classed("display", true)
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d,i) {
      return i;
      }))
    .force("charge", d3.forceManyBody().strength(-4))
    .force("center", d3.forceCenter(width/2, height/2))

let node = flagNodes.selectAll(".flag-nodes")
        .data(data.nodes)
        .enter()
          .append("div")
          .attr("class", function(d,i){
            return `flag flag-${d.code}`
          })
          .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended)
        )

let link = chart.append("g")
        .classed("links",true)
        .selectAll("line")
        .data(data.links)
        .enter()
          .append("line")


node.append("title")
.text(function(d) { return d.country; });

simulation
    .nodes(data.nodes)
    .on("tick", ticked);

simulation.force("link")
    .links(data.links);

//functions provided by D3.js
//
function ticked() {
    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
        .style("left", function(d) {return d.x})
        .style("top", function(d) {return d.y});
  }

function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
  d.fx = d.x;
  d.fy = d.y;
}

function dragged(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}

function dragended(d) {
  if (!d3.event.active) simulation.alphaTarget(0);
  d.fx = null;
  d.fy = null;
}

Codepen

【问题讨论】:

    标签: javascript d3.js force-layout


    【解决方案1】:

    你超级亲密!我花了很长时间才弄明白。

    我最终在我的项目目录中创建了一个充满国家/地区 png 的标志文件夹。然后使用国家代码动态加载它们。

    这是我解决问题的方法:

    const node = svg.selectAll(".flag")
        .data(data.nodes)
        .enter().append("image")
        .attr("xlink:href", d => require(`./flag/${d.code}.png`))
        .attr("width", radius)
        .attr("height", radius)
        .call(d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended))
    

    【讨论】:

      猜你喜欢
      • 2011-11-10
      • 1970-01-01
      • 2013-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      • 2017-08-06
      相关资源
      最近更新 更多