【问题标题】:I want to distinguish the link of d3.js force graph by the thickness我想通过粗细来区分d3.js力图的链接
【发布时间】:2014-07-11 07:11:39
【问题描述】:

我想通过粗细来区分链接。

我有数据。

变量“value”表示“thickness”。

“值”的范围是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 来进行现场实验吗?谢谢。

标签: javascript svg d3.js force-layout


【解决方案1】:

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

stroke属性的默认值为none,表示从不绘制轮廓。

请参阅documentation for stroke。以下是如何完成的示例:

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

这是一个 jsfiddle 演示它的工作原理。

【讨论】:

    【解决方案2】:

    我相信@Oleg 的回答是完整且正确的,但是,我只想提请您注意一个广泛使用链接粗细和其他相关 svg 属性的示例:

    2013 Budget Visualization

    相关代码在这里:

            // 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 的用法以及一般的进入/更新/退出模式。

    希望这会有所帮助。

    【讨论】:

    • 感谢您的建议,Oleg 和 VividD!我解决了我的问题。原因是我在我的 css 文件中定义了 'stroke' 和 'stroke-width' 选项。所以我删除了它并添加了代码 .attr("stroke", "gray") .attr("stroke-width", function(d) { return d.value; })
    【解决方案3】:

    我认为这更多地与 style("stroke.width", 5) 而不是 attr("stroke.width", 5) 有关,但我不确定,我是 d3 的新手。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      • 2020-03-24
      • 2014-03-09
      • 1970-01-01
      相关资源
      最近更新 更多