Javascript D3js力布局-节点之间具有渐变的线

Javascript D3js力布局-节点之间具有渐变的线,javascript,d3.js,svg,gradient,Javascript,D3.js,Svg,Gradient,这是我的d3部队布局: (请运行代码段) var宽度=600, 高度=600; var svg=d3。选择('body')。追加('svg')) .attr('width',width) .attr('高度'),高度; var color=d3.scale.category20(); var数据节点=[ {x:width/3,y:height/3,组:0,颜色:'blue'}, {x:2*width/3,y:height/3,组:1,颜色:'red'}, {x:width/2,y:2*heig

这是我的d3部队布局: (请运行代码段)

var宽度=600,
高度=600;
var svg=d3。选择('body')。追加('svg'))
.attr('width',width)
.attr('高度'),高度;
var color=d3.scale.category20();
var数据节点=[
{x:width/3,y:height/3,组:0,颜色:'blue'},
{x:2*width/3,y:height/3,组:1,颜色:'red'},
{x:width/2,y:2*height/3,组:2,颜色:'green'}
];
变量数据链接=[
{源:0,目标:1},
{源:1,目标:2},
{源:2,目标:0}
];
var-force=d3.layout.force()
。收费(-400)
.连接距离(高度/2)
.尺寸([宽度、高度])
.连接强度(1.3)
.摩擦力(0.8)
.重力(0.9);
力
.nodes(数据节点)
.链接(数据链接)
.start();
var link=svg.selectAll(“.link”)
.数据(数据链)
.enter().append(“行”)
.attr(“类”、“链接”);
var node=svg.selectAll(“.node”)
.数据(数据节点)
.enter().append(“圆”)
.attr(“类”,函数(d){return“node”+d.color})
.attr(“r”,宽度/20)
.呼叫(强制拖动);
node.append(“标题”)
.text(函数(d){返回d.color;});
force.on('tick',function(){
attr(“x1”,函数(d){返回d.source.x;})
.attr(“y1”,函数(d){返回d.source.y;})
.attr(“x2”,函数(d){返回d.target.x;})
.attr(“y2”,函数(d){返回d.target.y;});
attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;});
});
.node{
填充:#ccc;
冲程:#fff;
笔画宽度:0;
}
.node.blue{
填充:蓝色;
}
.node.red{
填充物:红色;
}
.node.green{
填充:绿色;
}
.链接{
填充:无;
笔画:黑色;
笔划宽度:20px;
}

您可以这样做,创建渐变并将渐变作为id传递:

var link = svg.selectAll(".link")
      .data(dataLinks)
    .enter().append("line")
      .attr("class", "link")
      .style("stroke",function(d){
          var id = "S"+d.source.index +"T" + d.target.index;
          var gradient1 = defs.append("linearGradient").attr("id",  id);
          gradient1.append("stop").attr("offset", "0%").attr("stop-color", d.target.color);
          gradient1.append("stop").attr("offset", "100%").attr("stop-color", d.source.color);
          return "url(#" + id + ")";
      });
工作代码

希望这有帮助

结果如下:

定义部分与@Cyril的几乎相同

var gradient = d3.select("svg").append("defs")
    .append("linearGradient")
    .attr("id", "gradient")
    .attr("spreadMethod", "pad");
  //start color white
  gradient.append("stop")
    .attr("offset", "0%")
    .attr("stop-color", "red")
    .attr("stop-opacity", 1);
  //end color steel blue
    gradient.append("stop")
    .attr("offset", "100%")
    .attr("stop-color", "green")
    .attr("stop-opacity", 1);
但在每一个滴答声中,都需要对x1、y1和x2、y2进行动态更新

这是“勾号”功能的代码:

var linkVector = new Vector2(d.target.x-d.source.x,d.target.y-d.source.y).getUnitVector();
var perpVector = linkVector.perpendicularClockwise().scale(radius);
var gradientVector = linkVector.scale(0.5);


gradient
    .attr("x1", 0.5-gradientVector.X)
    .attr("y1", 0.5-gradientVector.Y)
    .attr("x2", 0.5+gradientVector.X)
    .attr("y2", 0.5+gradientVector.Y);
0.5是路径的中间(正如您所猜测的),因为根据我的计算,这些是单位向量

gradientVector是缩放为0.5的单位向量

这是单位向量计算代码:

var Vector2 = function(x,y) {
  this.magnitude = Math.sqrt(x*x+y*y);
  this.X = x;
  this.Y = y;
};

Vector2.prototype.perpendicularClockwise = function(){
  return new Vector2(-this.Y, this.X);
};

Vector2.prototype.perpendicularCounterClockwise = function(){
  return new Vector2(this.Y, -this.X);
};

Vector2.prototype.getUnitVector = function(){
  return new Vector2(this.X/this.magnitude, this.Y/this.magnitude);
};

Vector2.prototype.scale = function(ratio){
  return new Vector2(ratio*this.X, ratio*this.Y);
};

注意:“勾号”内路径的sourceDelta/targetDelta计算与此问题无关。

当您旋转节点时,梯度似乎不会正确更新谢谢您的回答。但有时梯度的“方向”与节点的位置无关,如ee2Dev所述。有没有办法在旋转节点时改变渐变的方向?谢谢你指出…是的,在拖动节点时,渐变会被重置…sry无法修复…@Cyril我在你的原始答案中添加了一些代码,如果你仍然喜欢渐变的话,我不知道你是否已经解决了这个问题,但是我今天遇到了同样的问题,我想我得到了正确的代码。检查下面我的答案。