本文介绍了D3.js-在Force-Layout中用图像标记节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Codepen中有以下代码,能够渲染sprites标志(来自CSS),但它不在应基于节点位置的位置.

I have the following code in my Codepen that's able to render the sprites flags (from CSS), yet it's not in the position where it should be based on the nodes's position.

实际上,我能够从顶部将标志精灵中的节点拖动!

In fact, I am able to drag the nodes from the flags sprites from the top!

从一些console.logs来看,当节点位于以下位置时,似乎似乎没有通过 function ticked()函数中的 dx dy 位置叫.

Looking at some console.logs, it seems that d.x and d.y position from function ticked() is not passing when the nodes are called.

我不确定如何解决此问题

I am not sure how to fix this issue

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

推荐答案

您超级亲密!这花了我一段时间才弄清楚.

You are super close! This took me quite a while to figure out.

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

I ended up creating a flag folder filled with country pngs in my project directory. Then dynamically loaded them using the country code.

这是我解决问题的方法:

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))

这篇关于D3.js-在Force-Layout中用图像标记节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 15:41