表示されているデータをフィルタリングするドロップダウンボックスをいくつか使用して、力の図を作成しようとしています。最初のもの (私がほぼ今いる場所) はタイプをチェックし、タイプに一致するソースまたはターゲットを持つノードとリンクのみを表示します。
私が今持っているのは、フィルターを選択する機能であり、グラフが更新され、不要なノードが削除され、残りのノードが正しく再フォーマットされます。しかし、それは最初だけしか機能しません。「再フィルタリング」すると、おかしくなり始めます。
これが私の完全なコードです。私はjavascript(&d3)に非常に慣れていません。bl.ocks.orgから恥ずかしがらずに盗んできたので、お気軽に「noob」で答えてください。前もって感謝します。
また、これをjsfiddleに置きました:http://jsfiddle.net/J85Vu/
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Enterprise Collaboration Map</title>
<script type="text/javascript" src="d3.v3.js"></script>
<script type="text/javascript" src="jquery-1.10.2.min.js"></script>
<style type="text/css">
path.link {
fill: none;
stroke: #666;
stroke-width: 1.5px;
}
marker#a {
fill: green;
}
path.link.a {
stroke: green;
}
circle.a {
fill: green;
stroke: #333;
stroke-width: 1.5px;
}
marker#b {
fill: blue;
}
path.link.b {
stroke: blue;
}
circle.b {
fill: blue;
stroke: #333;
stroke-width: 1.5px;
}
marker#c {
fill: orange;
}
path.link.c {
stroke: orange;
}
circle.c {
fill: orange;
stroke: #333;
stroke-width: 1.5px;
}
circle {
fill: #ccc;
stroke: #333;
stroke-width: 1.5px;
}
text {
font: 10px sans-serif;
pointer-events: none;
}
text.shadow {
stroke: #fff;
stroke-width: 3px;
stroke-opacity: .8;
}
</style>
</head>
<body>
<select class="BU">
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
</select>
<script type="text/javascript">
var links = [
{source:"one",target:"two", type:"a", typeKBP:"a"},
{source:"two",target:"three", type:"a", typeKBP:"a"},
{source:"three",target:"four", type:"a", typeKBP:"a"},
{source:"four",target:"five", type:"a", typeKBP:"b"},
{source:"five",target:"six", type:"b", typeKBP:"b"},
{source:"six",target:"seven", type:"b", typeKBP:"b"},
{source:"seven",target:"eight", type:"b", typeKBP:"b"},
{source:"eight",target:"nine", type:"b", typeKBP:"c"},
{source:"nine",target:"ten", type:"c", typeKBP:"c"},
{source:"ten",target:"one", type:"c", typeKBP:"a"},
{source:"one",target:"three", type:"a", typeKBP:"a"},
{source:"two",target:"four", type:"a", typeKBP:"a"},
{source:"three",target:"five", type:"a", typeKBP:"b"},
{source:"four",target:"six", type:"a", typeKBP:"b"},
{source:"five",target:"seven", type:"b", typeKBP:"b"},
{source:"six",target:"eight", type:"b", typeKBP:"b"},
{source:"seven",target:"nine", type:"b", typeKBP:"c"},
{source:"eight",target:"ten", type:"b", typeKBP:"c"},
{source:"nine",target:"one", type:"c", typeKBP:"a"},
{source:"ten",target:"two", type:"c", typeKBP:"a"},
{source:"one",target:"four", type:"a", typeKBP:"a"},
{source:"two",target:"five", type:"a", typeKBP:"b"},
{source:"three",target:"six", type:"a", typeKBP:"b"},
{source:"four",target:"seven", type:"a", typeKBP:"b"},
{source:"five",target:"eight", type:"b", typeKBP:"b"},
{source:"six",target:"nine", type:"b", typeKBP:"c"},
{source:"seven",target:"ten", type:"b", typeKBP:"c"},
{source:"eight",target:"one", type:"b", typeKBP:"a"},
{source:"nine",target:"two", type:"c", typeKBP:"a"},
{source:"ten",target:"three", type:"c", typeKBP:"a"}
];
var inputlinks=[];
var nodes = {};
inputlinks.push(links);
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source, type:link.type});
link.target = nodes[link.target] || (nodes[link.target] = {name: link.target, type:link.typeKBP});
});
var w = 1024,
h = 800;
//setup initial force layout
var force = d3.layout.force()
.gravity(0.4)
.size([w, h])
.nodes(d3.values(nodes))
.links(links)
.linkDistance(100)
.charge(-1000)
.on("tick", tick)
.start();
var svg = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h);
// Per-type markers, as they don't inherit styles.
svg.append("svg:defs").selectAll("marker")
.data(["a","b","c"])
.enter().append("svg:marker")
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
var path = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("svg:path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
var circle = svg.append("svg:g").selectAll("circle")
.data(force.nodes())
.enter().append("svg:circle")
.attr("r", 6)
.attr("class", function(d) { return d.type; })
.call(force.drag);
var text = svg.append("svg:g").selectAll("g")
.data(force.nodes())
.enter().append("svg:g");
// A copy of the text with a thick white stroke for legibility.
text.append("svg:text")
.attr("x", 8)
.attr("y", ".31em")
.attr("class", "shadow")
.text(function(d) { return d.name; });
text.append("svg:text")
.attr("x", 8)
.attr("y", ".31em")
.attr("class","write")
.text(function(d) { return d.name; });
//jQuery update parts for drop downs.
$(document).ready(function(){
$('.BU').on('change',function(){
curBU=$('.BU').val();
//alert('The selected BU is ' + curBU);
//Filter links and rebuild nodes based on this.
minLinks={};
minLinks=links.filter(function(d){
if ((d.type==curBU) || (d.typeKBP==curBU)) {
return d
}
})
//new nodes
nodes2={};
nodes2=force.nodes().filter(function(d){return d3.keys(minLinks.filter(function(e){return e.source.name==d.name || e.target.name==d.name;})).length>0});
// minLinks.forEach(function(d) {
// d.source = nodes2[d.source] || (nodes2[d.source] = {name: d.source, type:d.type});
// d.target = nodes2[d.target] || (nodes2[d.target] = {name: d.target, type:d.typeKBP});
// });
force
.nodes(nodes2)
.links(minLinks)
.start();
//circle.remove();
newCirc=circle.data(force.nodes());
newCirc.enter().append("svg:circle")
.attr("r", 6)
.attr("class", function(d) { return d.type; })
.call(force.drag);
newCirc.exit().remove();
newPath=path.data(force.links());
newPath
.enter().append("svg:path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
newPath.exit().remove();
newText=text.data(force.nodes());
newText.exit().remove();
newText.select(".shadow").text(function(d){return d.name;});
newText.select(".write").text(function(d){return d.name;});
});
});
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt((dx * dx)/2 + (dy * dy));
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
});
circle.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
text.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
}
</script>
</body>
</html>