【问题标题】:Add links to my nodes with d3.js使用 d3.js 将链接添加到我的节点
【发布时间】:2015-05-18 12:29:13
【问题描述】:

我是 testinf d3.js,我正在尝试在根节点(JsFiddle 中的中心节点)和子节点之间添加链接。我怎样才能简单地做到这一点?

这是我目前拥有的代码:http://jsfiddle.net/fLqekg12/2/

var container = d3.select("svg#svg");
var data = [2, 1, 1, 1, 1, 1, 1];

var dataTree = {
    id: "root",
    size: 12,
    children: data.map(function (d) {
        return {
            size: 10,
            parent: "root"
        };
    })
};

var maxRadius = 50,
    padding = 40;

var radiusScale = d3.scale.sqrt()
    .domain([0, 50 /* d3.max(data) */ ])
    .range([0, 50]); // maxRadius

var roughCircumference = d3.sum(data.map(radiusScale)) * 2 + padding * (data.length - 1),
    radius = roughCircumference / (Math.PI * 2);

// make a radial tree layouts
var tree = d3.layout.tree()
    .size([360, radius])
    .separation(function (a, b) {
    return radiusScale(a.size) + radiusScale(b.size);
});

// create a holder group for all the graph nodes
var svgGroup = container.append('g')
    .attr('transform', 'translate(' + 80 + ',' + 90 + ')');


var nodes = tree.nodes(dataTree),
    links = tree.links(nodes); // and then... ?

// declare the nodes (this creates placed groups)
var svgNodes = svgGroup.selectAll('.node')
    .data(nodes) // cut out the root node, we don't need it : nodes.slice(1)
.enter().append('g')
    .attr('class', 'node')
    .attr('transform', function (d) {
    return "rotate(" + (d.x - 90) + ") translate(" + d.y + ")";
});

// append a cirl to all nodes groups
svgNodes.append('circle').attr('r', function (d) {
    return d.size;
});

编辑

此代码取得了进展。

var diagonal = d3.svg.diagonal.radial()
        .projection(function (d) {
        return [d.y, d.x / 180 * Math.PI];
    });

var svgLinks = svgGroup.selectAll('path')
        .data(tree.links(nodes))
        .enter().append('svg:path')
        .attr('class', 'link')
        .attr('d', diagonal)
        .attr("fill", "none")
        .attr("stroke", "gray");

小提琴更新:http://jsfiddle.net/fLqekg12/4/ 我现在唯一需要的是直线而不是曲线。有人吗?

【问题讨论】:

  • 您创建“节点”,然后创建将节点作为类的元素。你必须对“链接”做同样的事情:使用源和目标的坐标创建 svg:line 元素。
  • 谢谢@Matthieu,我知道这一点并理解一般原则,但我对 d3 js 编写实际代码并使其工作不够满意(我一直在尝试已经有几个例子了);
  • 也许你可以直接使用强制布局:github.com/mbostock/d3/wiki/Force-Layout 或查看d3js svg line function
  • 我可以,但不会 ;-) 。我希望从我的代码中完成它以用于学习目的。

标签: d3.js


【解决方案1】:

计算并创建节点后,您必须将链接创建为 svg 线元素:

var link = svgGroup.selectAll('line.link')
    .data(links)
    .enter().append('svg:line')
        .attr("class", "link")
        .attr("style","stroke:black")
        .attr("x1", function(d) { return ... (x coordinate source node) })
        .attr("y1", function(d) { return ... (y coordinate source node) })
        .attr("x2", function(d) { return ... (x coordinate target node) })
        .attr("y2", function(d) { return ... (y coordinate target node) });

你必须找到从 x,y 极坐标计算位置的好公式。

【讨论】:

  • 你知道如何检索源/目标坐标吗?
  • 它们存储在 d.source(.x/y) 和 d.target(.x/y)
  • 其实不是数据(节点),而是数据(链接)。并且线条不是用正确的坐标绘制的(参见jsfiddle.net/fLqekg12/3)。我认为这是因为 - 如果您阅读我的代码 - 节点会被转换。所以他们的 x/y 位置仍然是他们现在的样子,但是变换给了他们另一个位置。你怎么看?
  • 是的,我的错:这是数据(链接)。而且您必须像对节点一样转换链接位置(在 x 上旋转,在 y 上进行距离)
  • 没有真正工作或我正在寻找的东西,但它为我指明了正确的方向。
【解决方案2】:

两个可行的解决方案是:

使用路径(最简单的一种,但不能将曲线转换为直线):http://jsfiddle.net/fLqekg12/4/

使用线条。诀窍是不能直接使用线条代替路径(see why here),如果你转换节点,它就不起作用。

我找到的解决方案是found from this post:如果你的节点被转换,线条也必须被转换:

y1y2 上使用d.target.x / 180 * Math.PI),因为我想要一个径向投影,最后再次转换线条:

svgLinks.attr("transform", function (d) {
        return "rotate(" + (d.target.x - 90) + ")";
});

此处的完整工作示例: http://jsfiddle.net/fLqekg12/6/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多