Javascript 将箭头颜色与D3中的线条颜色匹配

Javascript 将箭头颜色与D3中的线条颜色匹配,javascript,d3.js,svg,Javascript,D3.js,Svg,我试图做一件显而易见的事情,让我的有向图链接的箭头颜色与边颜色匹配。令人惊讶的是,我还没有找到一个完整的解决方案,尽管这似乎是一个很好的起点。我很乐意按照下面概述的方式调整该解决方案,或者如果有一种更好的方法来创建箭头,从而达到这种效果,我将非常感激 首先,我有一个线性渐变颜色函数,通过如下属性为边着色: var gradientColor = d3.scale.linear().domain([0,1]).range(["#08519c","#bdd7e7"]); 然后,像上一篇文章一样,我

我试图做一件显而易见的事情,让我的有向图链接的箭头颜色与边颜色匹配。令人惊讶的是,我还没有找到一个完整的解决方案,尽管这似乎是一个很好的起点。我很乐意按照下面概述的方式调整该解决方案,或者如果有一种更好的方法来创建箭头,从而达到这种效果,我将非常感激

首先,我有一个线性渐变颜色函数,通过如下属性为边着色:

var gradientColor = d3.scale.linear().domain([0,1]).range(["#08519c","#bdd7e7"]);
然后,像上一篇文章一样,我有一个添加标记的功能:

function marker (color) {
  var reference;
  svg.append("svg:defs").selectAll("marker")
    .data([reference]) 
   .enter().append("svg:marker")    
    .attr("id", String)
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 15)  // This sets how far back it sits, kinda
    .attr("refY", 0)
    .attr("markerWidth", 9)
    .attr("markerHeight", 9)
    .attr("orient", "auto")
    .attr("markerUnits", "userSpaceOnUse")
   .append("svg:path")
    .attr("d", "M0,-5L10,0L0,5")
    .style("fill", color);
  return "url(#" + reference + ")";    };
然后我的链接定义是基于

这不符合书面规定;浏览器给了我一个“Uncaught TypeError:无法读取未定义的属性'5'”(其中'd[5]'指链接具有的属性列表中的第五个属性)。在这种情况下,问题显然是将数据函数传递给标记函数。如果输入静态颜色,如“#FFCC33”,则箭头确实会改变颜色(现在)。不幸的是,1.5年前发布此“标记函数”解决方案的人根本没有包含将颜色传递给标记函数的内容

我不知道如何正确地输入链接的颜色。理想情况下,我将能够使用箭头所连接链接的颜色参考,而不是输入相同的颜色函数(因为最终我将通过基于按钮按下的不同方案为链接着色)


我已经创建了一个包含了所有必要的部分来查看和解决这个问题。目前我正在向标记传递一个静态颜色,但它应该是它所附加到的链接的任何颜色。我还为另一个关于正确定位箭头和边尾的问题提供了一些功能。

我认为您无法定义单个SVG标记并更改其颜色。相反,您需要多次定义标记(需要使用的每种颜色1个)。最近,
D3
网站上出现了一个不错的例子

这样做的方式是,如果有很多不同的标记,每个标记定义标记的颜色。以下是定义的所有标记的屏幕截图:

然后,在这个特定的示例中,循环路径上的CSS类。每个路径使用的特定彩色标记在CSS类中定义,该类在任何给定时间应用于路径

我已经修改了您的示例,为每个路径添加了一个新的
标记
(并稍微更改了渐变中的颜色,以证明它有效)。以下是我得到的:

var-width=960,
高度=500;
var color=d3.scale.category20();
var gradientColor=d3.scale.linear().domain([0,15]).range([“#ff0000”,“#0000ff”);
var-force=d3.layout.force()
.linkDistance(10)
.联系强度(2)
.尺寸([宽度、高度]);
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
var defs=svg.append(“svg:defs”);
d3.json(“http://bost.ocks.org/mike/miserables/miserables.json,函数(错误,图形){
如果(错误)抛出错误;
功能标记(颜色){
defs.append(“svg:marker”)
.attr(“id”,color.replace(“#”),“”)
.attr(“视图框”,“0-5 10”)
.attr(“refX”,15)//这设置了它的位置,有点像
.attr(“参考文献”,0)
.attr(“markerWidth”,9)
.attr(“markerHeight”,9)
.attr(“方向”、“自动”)
.attr(“markerUnits”、“userSpaceOnUse”)
.append(“svg:path”)
.attr(“d”,“M0,-5L10,0L0,5”)
.样式(“填充”,颜色);
返回“url(“+color+”);
};
var nodes=graph.nodes.slice(),
链接=[],
bilinks=[];
graph.links.forEach(函数(link){
var s=节点[link.source],
t=节点[link.target],
i={},//中间节点
linkValue=link.value//用于将值从链接传输到BILINK
;
节点推送(i);
links.push({
资料来源:s,
目标:我
}, {
资料来源:我,
目标:t
});
推送([s,i,t,linkValue]);
});
force.nodes(节点)
.链接(links)
.start();
var link=svg.selectAll(“.link”)
.data(bilinks).enter().append(“路径”)
.attr(“类”、“链接”)
.style(“填充”、“无”)
.style(“不透明度”、“0.5”)
.样式(“笔划宽度”、“2”)
.每个功能(d){
var color=gradientColor(d[3]);
console.log(d[3]);
d3.选择(此).样式(“笔划”,颜色)
.attr(“标记结束”,标记(颜色));
});
var node=svg.selectAll(“.node”)
.数据(图.节点)
.enter().append(“g”)
.attr(“类”、“节点”)
.呼叫(强制拖动);
node.append(“圆”)
.attr(“r”,函数(d){
返回2+d组;
})
.样式(“不透明度”,0.5)
.样式(“填充”,功能(d){
返色(d组);
});
node.append(“标题”)
.文本(功能(d){
返回d.name;
});
强制打开(“勾号”,函数(){
link.attr(“d”,函数(d){
返回“M”+d[0].x+,“+d[0].y+“S”+d[1].x+,“+d[1].y+”+d[2].x+,“+d[2].y;
});
node.attr(“转换”,函数(d){
返回“translate”(“+d.x+”,“+d.y+”);
});
});
});

这让我想知道,为什么你链接到的旧答案得到了任何支持票。尽管这个想法可能是正确的,但由于以下原因,代码无法工作:1
val
从未分配任何值,因此返回值将是
“url(#未定义)”
;2.
id
将始终是一个空字符串;3.当传递函数时var link = svg.selectAll(".link") .data(bilinks) .enter().append("path") .attr("class", "link") .style("fill", "none") .style("opacity", "0.5") .style("stroke-width", "2") .style("stroke", function(d) { return gradientColor(d[3]); } ) .attr("marker-end", marker( "#FFCC33" ) );