控制线长d3.js

时间:2016-12-27 23:49:20

标签: javascript d3.js

我使用以下代码生成一个由其他圆圈包围的圆圈,这些圆圈都通过<line>元素连接到主圆圈。我试图让它们与圆圈不均匀,但无论我尝试什么,我都会遇到某种混乱。代码如下:

var width = 500,
    height = 500;
var force = d3.layout.force()
    .size([width, height])
    .charge(-400)
    .linkDistance(190)
    .on("tick", tick);
var drag = force.drag()
    .on("dragstart", dragstart);
var svg = d3.select("#orb").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("class", "mainsvg");
var link = svg.selectAll(".link"),
    node = svg.selectAll(".node");


d3.json("graph.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("a")      
      .attr("href", "3");

    node.append("g")
      .attr("class", "node");



    node.append("circle")
      .attr("class", "circle")
      .attr("r", function(d) { return d.r })
      .attr("fill", function(d) { return d.color })
      .attr("stroke", function(d){ return d.color })
      .on("dblclick", dblclick);

    node.append("text")
      .attr("class", "text")
      .attr("fill", "white")
      .attr("stroke", "none")
      .attr("x", function(d) { return d.x; })
      .attr("y", function(d) { return d.y; })
      .text( function (d) { return d.name; });


});

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

  svg.selectAll(".circle").attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
  svg.selectAll(".text").attr("x", function(d) { return d.x+d.xoffs; })
      .attr("y", function(d) { return d.y+d.yoffs; });
}

我已经尝试控制<line>元素的x1 / y1和x2 / y2但是如果我移动线,则圆圈保持不变。有没有办法说,取消相等的链接距离,并为每个圆圈单独设置?

1 个答案:

答案 0 :(得分:4)

有几种方法可以达到你想要的效果。但最重要的是记住linkDistance接受一个函数。

例如,在这个片段中,我在链接的数据数组中设置距离:

var links = [{
    source: 1,
    target: 0,
    distance: 50
}, {
    source: 2,
    target: 0,
    distance: 20
}, {
    source: 3,
    target: 0,
    distance: 150
}, {
    source: 4,
    target: 0,
    distance: 80
}, {
    source: 5,
    target: 0,
    distance: 40
}]

并在力量中使用它:

.linkDistance(d=>d.distance)

检查代码段:

var nodes = [{
        name: "a"
    }, {
        name: "b"
    }, {
        name: "c"
    }, {
        name: "d"
    }, {
        name: "e"
    }, {
        name: "f"
    }];

    var links = [{
        source: 1,
        target: 0,
        distance: 50
    }, {
        source: 2,
        target: 0,
        distance: 20
    }, {
        source: 3,
        target: 0,
        distance: 150
    }, {
        source: 4,
        target: 0,
        distance: 80
    }, {
        source: 5,
        target: 0,
        distance: 40
    }]

    var width = 400
    height = 300;

    var force = d3.layout.force()
        .nodes(nodes)
        .links(links)
        .size([width, height])
        .linkDistance(d => d.distance)
        .charge(-1000)
        .on("tick", tick)
        .start();

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

    var link = svg.selectAll(".link")
        .data(force.links())
        .enter().append("line")
        .attr("stroke", "black")
        .attr("class", "link");

    var node = svg.selectAll(".node")
        .data(force.nodes())
        .enter().append("g")
        .attr("class", "node")
        .call(force.drag);

    node.append("circle")
        .attr("r", (d,i) => i ? 10 : 16)
        .style("fill", (d,i) => i ? "teal" : "brown");

    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("transform", function(d) {
            return "translate(" + d.x + "," + d.y + ")";
        });
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>