如何通过线条粗细区分d3.js力导向图中的链接?

7

我希望通过线条的粗细来区分链接。

我已经有了数据。

变量“value”表示“thickness”。

“value”的范围是0~1。

    {"nodes":[{"name":"A", "group":1},
              {"name":"B", "group":1},
              {"name":"C", "group":1},
              {"name":"D", "group":1},
              {"name":"E", "group":1}],
     "links":[{"source":0,"target":1,"value":0.9},
              {"source":0,"target":2,"value":0.8},
              {"source":0,"target":3,"value":0.7},
              {"source":1,"target":2,"value":0.7},
              {"source":2,"target":4,"value":0.2},
              {"source":0,"target":4,"value":0.5}]}

我的d3.js图形代码如下:

    <!DOCTYPE html>
    <meta charset="utf-8">

    <body><script src="../d3-master/d3.min.js"></script>
    <head><link rel="stylesheet" type="text/css" href="../D3css/D3css.css"></head>

    <script>

    var width = 960,
        height = 500

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

    var force = d3.layout.force()
        .gravity(.05)
        .distance(100)
        .charge(-100)
        .size([width, height]);

    d3.json("../data/cor_test.json", function(error, json) {

      force
        .nodes(json.nodes)
        .links(json.links)
        .start();

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

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

      node.append("circle")
          .attr("r", 5);

      node.append("text")
          .attr("dx", 12)
          .attr("dy", ".35em")
          .text(function(d) { return d.name });

      force.on("tick", function() {
        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>

我将代码修改为以下内容,但它并没有起作用。
      var link = svg.selectAll(".link")
          .data(json.links)
        .enter().append("line")
          .attr("class", "link")
          .attr("stroke-width", function(d) { return d.value; });

更简单的更改方式:.attr("stroke-width", "5px");也不起作用。
链接没有显示。
我该怎么办?

你能把你的示例转换成一个 jsfiddle,以便进行实时实验吗?谢谢。 - Delapouite
3个回答

6

首先,您需要指定'stroke'属性,因为:

stroke属性的默认值为none,这意味着轮廓永远不会被绘制。

请参阅 stroke文档。以下是示例:

selection
    .attr('stroke', 'red')
    .attr('stroke-width', 5);

这里有一个jsfiddle演示它是如何工作的。

1

我相信 @Oleg 的答案是完整和正确的,但是我想提醒您一个使用了链接粗细和其他相关svg属性的例子:

2013预算可视化

enter image description here

相关代码如下:

        // Enter any new links at the parent's previous position.
    link.enter().insert("svg:path", "g")
            .attr("class", "link")
            .attr("d", function(d) {
                if (Number(d.target[spendField]) > 0) {
                    var o = {x: source.x0, y: source.y0};
                    return diagonal({source: o, target: o});
                }
                else {
                    null;
                }
            })
            .style("stroke",function (d,i) {
                if (d.source.depth==0) {
                    rootCounter++;
                    return (d.source.children[rootCounter-1].linkColor);
                }
                else {
                    return (d.source) ? d.source.linkColor : d.linkColor;
                }
            })
            .style("stroke-width", function (d,i) {

                if (d.source.depth==0) {
                    var ret = level1Radius(d.target[spendField]) * 2;
                    return (isNaN(ret) ? 4 : ret);
                }
                else if (d.source.depth==1) {
                    var ret = level2Radius(d.target[spendField]) * 2;
                    return (isNaN(ret) ? 4 : ret);
                }
                else if (d.source.depth==2) {
                    var ret = level3Radius(d.target[spendField]) * 2;
                    return (isNaN(ret) ? 4 : ret);
                }
                else if (d.source.depth==3) {
                    var ret = level4Radius(d.target[spendField]) * 2;
                    return (isNaN(ret) ? 4 : ret);
                }
             })
            .style("stroke-opacity", function(d){
                var ret = ((d.source.depth+1)/4.5)
                if (d.target[spendField] <= 0) ret=.1;
                return ret;
            })
            .style("stroke-linecap","round")
            .transition()
            .duration(duration);
      //      .attr("d", diagonal);


    // Transition links to their new position.
     var linkUpdate = link.transition()
            .duration(duration)
            .attr("d", diagonal);

     linkUpdate
             .style("stroke-width", function (d,i) {
                 if (d.source.depth==0) {
                     var ret = level1Radius(Number(d.target[spendField])) * 2;
                     return (isNaN(ret) ? 4 : ret);
                 }
                 else if (d.source.depth==1) {
                     var ret = level2Radius(Number(d.target[spendField])) * 2;
                     return (isNaN(ret) ? 4 : ret);
                 }
                 else if (d.source.depth==2) {
                     var ret = level3Radius(Number(d.target[spendField])) * 2;
                     return (isNaN(ret) ? 4 : ret);
                 }
                 else if (d.source.depth==3) {
                     var ret = level4Radius(Number(d.target[spendField])) * 2;
                     return (isNaN(ret) ? 4 : ret);
                 }
            })
         //    .style("stroke-dasharray", function(d) {
         //       var ret=(d.target[spendField] > 0) ? "" : "5,8";
         //       return ret;
         //    })
             .style("stroke-opacity", function(d){
                 var ret = ((d.source.depth+1)/4.5)
                 if (d.target[spendField] <= 0) ret=.1;
                 return ret;
             })


    // Transition exiting nodes to the parent's new position.
    link.exit().transition()
            .duration(duration)
            .attr("d", diagonal)
            .remove();

除了使用strokestroke-width之外,您还可以注意到使用stroke-opacitystroke-linecap以及一般的enter/update/exit模式。

希望这有所帮助。


感谢您的建议,Oleg和VividD!我解决了我的问题。原因是我在CSS文件中定义了“stroke”和“stroke-width”选项。所以我将其删除并添加了代码.attr(“stroke”,“gray”)。attr(“stroke-width”,function(d){return d.value;}) - user3766479

1
我认为这与 style("stroke.width", 5) 有更多关联,而不是 attr("stroke.width", 5),但我不确定,因为我对d3不熟悉。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接