D3.js 具有多个链接和淡入淡出的D3力有向图
尝试将不透明度添加到此d3强制定向图,但失败。有人能给我指出正确的方向吗 当我选择节点时,我希望它使未连接的其他节点淡出 如果可能的话,下一步就是为标签和值添加过滤器 这是一个新手问题,所以要友善。我真的很喜欢这个viz,如果我能像我脑子里看到的那样让这个部件工作,它会很有用 谢谢下面的代码D3.js 具有多个链接和淡入淡出的D3力有向图,d3.js,directed-graph,D3.js,Directed Graph,尝试将不透明度添加到此d3强制定向图,但失败。有人能给我指出正确的方向吗 当我选择节点时,我希望它使未连接的其他节点淡出 如果可能的话,下一步就是为标签和值添加过滤器 这是一个新手问题,所以要友善。我真的很喜欢这个viz,如果我能像我脑子里看到的那样让这个部件工作,它会很有用 谢谢下面的代码 var data = { edges: [{ source: { id: 0, label: "from" }, target: { id:
var data = {
edges: [{
source: {
id: 0,
label: "from"
},
target: {
id: 1,
label: "to"
},
value: "after you"
}, {
source: {
id: 0,
label: "from"
},
target: {
id: 1,
label: "to"
},
value: "follow my lead"
}, {
source: {
id: 0,
label: "from"
},
target: {
id: 1,
label: "to"
},
value: "over this way"
},
{
source: {
id: 2,
label: "outside"
},
target: {
id: 3,
label: "lonely"
},value:"helloooooo"
}
]
};
function myGraph() {
this.addNode = function(n) {
if (!findNode(n.id)) {
nodes.push({
"id": n.id,
"label": n.label
});
update();
}
};
this.addLink = function(source, target, value) {
links.push({
"source": findNode(source.id),
"target": findNode(target.id),
"value": value
});
update();
};
this.initialize = function() {
data.edges.forEach(function(d) {
graph.addNode(d.source);
graph.addNode(d.target);
graph.addLink(d.source, d.target, d.value);
});
};
var findNode = function(nodeId) {
for (var i in nodes) {
if (nodes[i].id === nodeId) {
return nodes[i];
}
};
};
var countSiblingLinks = function(source, target) {
var count = 0;
for (var i = 0; i < links.length; ++i) {
if ((links[i].source.id == source.id && links[i].target.id == target.id) || (links[i].source.id == target.id && links[i].target.id == source.id))
count++;
};
return count;
};
var getSiblingLinks = function(source, target) {
var siblings = [];
for (var i = 0; i < links.length; ++i) {
if ((links[i].source.id == source.id && links[i].target.id == target.id) || (links[i].source.id == target.id && links[i].target.id == source.id))
siblings.push(links[i].value);
};
return siblings;
};
var w = window.innerWidth - 20,
h = window.innerHeight,
middle = w / 2;
var linkDistance = 300;
var colors = d3.scale.category20();
var svg = d3.select("body")
.append("svg:svg")
.attr("width", w)
.attr("height", h)
.style("z-index", -10)
.attr("id", "svg");
svg.append('svg:defs').selectAll('marker')
.data(['end'])
.enter()
.append('svg:marker')
.attr({
'id': "arrowhead",
'viewBox': '0 -5 10 10',
'refX': 22,
'refY': 0,
'orient': 'auto',
'markerWidth': 20,
'markerHeight': 20,
'markerUnits': "strokeWidth",
'xoverflow': 'visible'
})
.append('svg:path')
.attr('d', 'M0,-5L10,0L0,5')
.attr('fill', '#ccc');
var force = d3.layout.force();
var nodes = force.nodes(),
links = force.links();
var update = function() {
var path = svg.selectAll("path.link")
.data(force.links());
path.enter().append("svg:path")
.attr("id", function(d) {
return d.source.id + "-" + d.value + "-" + d.target.id;
})
.attr("class", "link")
.attr('marker-end', 'url(#arrowhead)');
path.exit().remove();
var pathInvis = svg.selectAll("path.invis")
.data(force.links());
pathInvis.enter().append("svg:path")
.attr("id", function(d) {
return "invis_" + d.source.id + "-" + d.value + "-" + d.target.id;
})
.attr("class", "invis");
pathInvis.exit().remove();
var pathLabel = svg.selectAll(".pathLabel")
.data(force.links());
pathLabel.enter().append("g").append("svg:text")
.attr("class", "pathLabel")
.append("svg:textPath")
.attr("startOffset", "50%")
.attr("text-anchor", "middle")
.attr("xlink:href", function(d) {
return "#invis_" + d.source.id + "-" + d.value + "-" + d.target.id;
})
.style("fill", "#cccccc")
.style("font-size", 10)
.text(function(d) {
return d.value;
});
var node = svg.selectAll("g.node")
.data(force.nodes());
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.call(force.drag);
nodeEnter.append("svg:circle")
.attr("r", 10)
.attr("id", function(d) {
return "Node;" + d.id;
})
.attr("class", "nodeStrokeClass")
.attr("fill", "#0db7ed")
nodeEnter.append("svg:text")
.attr("class", "textClass")
.attr("x", 20)
.attr("y", ".31em")
.text(function(d) {
return d.label;
});
node.exit().remove();
function arcPath(leftHand, d) {
var x1 = leftHand ? d.source.x : d.target.x,
y1 = leftHand ? d.source.y : d.target.y,
x2 = leftHand ? d.target.x : d.source.x,
y2 = leftHand ? d.target.y : d.source.y,
dx = x2 - x1,
dy = y2 - y1,
dr = Math.sqrt(dx * dx + dy * dy),
drx = dr,
dry = dr,
sweep = leftHand ? 0 : 1;
siblingCount = countSiblingLinks(d.source, d.target)
xRotation = 0,
largeArc = 0;
if (siblingCount > 1) {
var siblings = getSiblingLinks(d.source, d.target);
console.log(siblings);
var arcScale = d3.scale.ordinal()
.domain(siblings)
.rangePoints([1, siblingCount]);
drx = drx / (1 + (1 / siblingCount) * (arcScale(d.value) - 1));
dry = dry / (1 + (1 / siblingCount) * (arcScale(d.value) - 1));
}
return "M" + x1 + "," + y1 + "A" + drx + ", " + dry + " " + xRotation + ", " + largeArc + ", " + sweep + " " + x2 + "," + y2;
}
force.on("tick", function(e) {
var q = d3.geom.quadtree(nodes),
i = 0,
n = nodes.length,
k = .1 * e.alpha;
while (++i < n) q.visit(collide(nodes[i]));
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
path.attr("d", function(d) {
return arcPath(true, d);
});
pathInvis.attr("d", function(d) {
return arcPath(d.source.x < d.target.x, d);
});
});
force
.charge(-10000)
.friction(0.5)
.linkDistance(linkDistance)
.size([w, h])
.start();
keepNodesOnTop();
}
update();
function collide(node) {
var r = node.radius + 16,
nx1 = node.x - r,
nx2 = node.x + r,
ny1 = node.y - r,
ny2 = node.y + r;
return function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = node.radius + quad.point.radius;
if (l < r) {
l = (l - r) / l * .5;
node.x -= x *= l;
node.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
};
}
}
function drawGraph() {
graph = new myGraph();
graph.initialize();
}
drawGraph();
function keepNodesOnTop() {
$(".nodeStrokeClass").each(function(index) {
var gNode = this.parentNode;
gNode.parentNode.appendChild(gNode);
});
function fade(opacity) {
return function(d) {
node.style("stroke-opacity", function(o) {
thisOpacity = isConnected(d,o) ? 1 :opacity;
this.setAttribute('fill-opacity',thisOpacity);
return thisOpacity;
});
}
}; //end of function
}
var数据={
边缘:[{
资料来源:{
id:0,
标签:“来自”
},
目标:{
id:1,
标签:“至”
},
价值观:“在你之后”
}, {
资料来源:{
id:0,
标签:“来自”
},
目标:{
id:1,
标签:“至”
},
价值观:“跟随我的领导”
}, {
资料来源:{
id:0,
标签:“来自”
},
目标:{
id:1,
标签:“至”
},
价值:“这边走”
},
{
资料来源:{
id:2,
标签:“外部”
},
目标:{
id:3,
标签:“孤独”
},值:“helloooo”
}
]
};
函数myGraph(){
this.addNode=函数(n){
如果(!findNode(n.id)){
nodes.push({
“id”:n.id,
标签
});
更新();
}
};
this.addLink=函数(源、目标、值){
links.push({
“源”:findNode(source.id),
“目标”:findNode(target.id),
“价值”:价值
});
更新();
};
this.initialize=函数(){
数据.edges.forEach(函数(d){
graph.addNode(d.source);
graph.addNode(d.target);
图.addLink(d.source,d.target,d.value);
});
};
var findNode=函数(nodeId){
for(节点中的变量i){
if(节点[i].id==nodeId){
返回节点[i];
}
};
};
var countSiblingLinks=函数(源、目标){
var计数=0;
对于(变量i=0;i1){
var sibles=getSiblingLinks(d.source,d.target);
console.log(兄弟);
var arcScale=d3.scale.ordinal()
.域(兄弟)
.范围点([1,同级计数]);
drx=drx/(1+(1/同级计数)*(弧标(d值)-1);
干=干/(1+(1/同级计数)*(弧标(d值)-1);
}
返回“M”+x1+、“+y1+”A“+drx+”、“+dry+”、“+X旋转+”、“+largeArc+”、“+sweep+”+x2+