d3.js强制有向图-使用图像代替节点的圆 [英] d3.js Force Directed Graph - Using Images instead of Circles for the Nodes

查看:516
本文介绍了d3.js强制有向图-使用图像代替节点的圆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用d3.js可视化动态网络拓扑.到目前为止,我可以通过将圆作为节点来使其工作,但是我必须为不同的节点类型放置不同的自定义图像.

I am trying to visualize a dynamic network topology by using d3.js. So far, I could make it work by putting circles as nodes, but I have to put different custom images for different node types.

我当前的代码如下:

 node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(jsonTry.nodes)
.enter().append("circle")
    .attr("r", 10)
    .attr("fill", function(d) { return color(d.group); })
    .call(d3.drag()
        .subject(dragsubject)
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));

首先,我想将图像放置到所有节点以查看其工作方式,如下所示:

As a start, I wanted to put an image to all nodes to see how it works like the following:

node = svg.append("g")
.attr("class", "nodes")
.data(graph.nodes)

node.append("svg:image")
.attr("xlink:href", "https://github.com/favicon.ico")
.attr("x", -8)
.attr("y", -8)
.attr("width", 16)
.attr("height", 16);

似乎无法正常工作,因为我只能看到链接,而节点却消失了.我找到了一些使用d3 v3的示例,但是目前我正在使用d3 v4,并希望相应地实现它(因为v3中没有包含forceLink()的问题)

It doesn't seem to be working this way since I can see just the links, and nodes just dissappeared. I found some examples using d3 v3, but currently I'm using d3 v4 and want to implement it accordingly (since I had problems with forceLink() not being included in v3)

谢谢.

推荐答案

如果将<image>附加到<g>,则可以使用您的方法.但是,您要将<image>附加到<circle>元素上,这将不起作用.

Your approach would work if you were appending the <image> to the <g>. However, you're appending the <image> to the <circle> element, and that won't work.

您有两种解决方案:

  1. image附加到组,而不是圈子;
  2. 保持圈子,但使用def:

  1. Append the image to the groups, not to the circles;
  2. Keep your circles, but use a def:

var defs = svg.append('svg:defs');

defs.append("svg:pattern")
    .attr("id", "myPattern")
    .attr("width", 1)
    .attr("height", 1)
    .append("svg:image")
    .attr("xlink:href", "https://github.com/favicon.ico")
    .attr("width", 16)
    .attr("height", 16)
    .attr("x", 0)
    .attr("y", 0);

这是一个演示:

var nodes = [{
    "id": 1,
}, {
    "id": 2,
}, {
    "id": 3,
}, {
    "id": 4,
}, {
    "id": 5,
}, {
    "id": 6,
}, {
    "id": 7,
}, {
    "id": 8,
}];

var links = [{
    source: 1,
    target: 2
}, {
    source: 1,
    target: 3
}, {
    source: 1,
    target: 4
}, {
    source: 2,
    target: 5
}, {
    source: 2,
    target: 6
}, {
    source: 1,
    target: 7
}, {
    source: 7,
    target: 8
}];

var index = 10;
var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    node,
    link;

var defs = svg.append('svg:defs');

defs.append("svg:pattern")
    .attr("id", "myPattern")
    .attr("width", 1)
    .attr("height", 1)
    .append("svg:image")
    .attr("xlink:href", "https://github.com/favicon.ico")
    .attr("width", 16)
    .attr("height", 16)
    .attr("x", 0)
    .attr("y", 0);

var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) {
        return d.id;
    }).distance(100))
    .force("collide", d3.forceCollide(50))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2));

link = svg.selectAll(".link")
    .data(links, function(d) {
        return d.target.id;
    })

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

node = svg.selectAll(".node")
    .data(nodes, function(d) {
        return d.id;
    })

node = node.enter()
    .append("g")
    .attr("class", "node")
    .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));

node.append("circle")
    .attr("r", 10)
    .style("fill", "url(#myPattern)")

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

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


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
        .attr("transform", function(d) {
            return "translate(" + d.x + ", " + d.y + ")";
        });
}

function dragstarted(d) {
    if (!d3.event.active) simulation.alphaTarget(0.3).restart()
}

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 = undefined;
    d.fy = undefined;
}

.link {
  stroke: #aaa;
}

.node {
  pointer-events: all;
  stroke: none;
  stroke-width: 40px;
}

<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="300"></svg>

这篇关于d3.js强制有向图-使用图像代替节点的圆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆