Я пытаюсь удалить оболочку вокруг построенного сетевого графика D3. Моя сеть основана на этом JSFiddle . Мое требование - показать все дочерние узлы в группе, окружив их заштрихованным цветом. Мой график начинается с одного родительского узла, при событии щелчка он расширяется, чтобы показать дочерние узлы. Кроме того, если дочерний узел имеет вложенный дочерний узел, то при щелчке он снова развернется и покажет эти внутренние дочерние узлы. Узлы имеют свойство переключения. Событие щелчка на развернутом узле скрывает дочерний узел. Прямо сейчас я застрял на удалении корпуса, когда я хочу скрыть дочерний узел. Ниже приведены снимки. 1. Родительский узел Родительский узел
Расширенные узлы (нажмите на родительский узел). Родительский и дочерний узел. расширенная сеть
Снова нажмите на root родительский узел. изображение после скрытия дочернего узла .
Здесь я хочу удалить область корпуса, когда скрываю дочерний узел при событии щелчка. Я попытался удалить разметку 'path' для оболочки внутри элемента тега SVG в функции щелчка, но она не работает. Любая помощь будет высоко оценена.
var width = 700,
height = 300,
root;
var force = d3.layout.force()
.gravity(.02)
.charge(function(d) { return d._children ? -d.size / 160 : -30; })
.linkDistance(function(d) { return d.target._children ? 120 : 80; })
.size([width, height])
.on("tick", tick);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var link = svg.selectAll(".link"),
node = svg.selectAll(".node");
var fill = d3.scale.category10();
function getDepth(n) { return n.depth; }
//var color = d3.scale.linear().domain([-2, 4]).range(["#252525", "#cccccc"]), //This is used to scale the gray color based on the propertyValue
var groupHullColor = "#e7cb94", //d3.scale.category10(),
subgroupHullColor = " #9ecae1",
subsubgroupHullColor = "#ff9896";
var groups = [[14,17]];
var subgroups = [[15,16,17],[14,5,11,13]];
var subsubgroups = [[14,13,12],[14,5,1,2,3,4],[14,11,6,7,8,9,10]];
var minNodeSize = 2
//function radiusOf(element) {return (minNodeSize + (8 * Math.sqrt(element.depth))) };
function radiusOf(element) {return (minNodeSize + (8 * Math.sqrt(2))) };
var groupPath = function(d) {
var fakePoints = [];
d.forEach(function(element) { fakePoints = fakePoints.concat([ // "0.7071" is the sine and cosine of 45 degree for corner points.
[(element.x), (element.y + (radiusOf(element) - minNodeSize))],
[(element.x + (0.7071 * (radiusOf(element) - minNodeSize))), (element.y + (0.7071 * (radiusOf(element) - minNodeSize)))],
[(element.x + (radiusOf(element) - minNodeSize)), (element.y)],
[(element.x + (0.7071 * (radiusOf(element) - minNodeSize))), (element.y - (0.7071 * (radiusOf(element) - minNodeSize)))],
[(element.x), (element.y - (radiusOf(element) - minNodeSize))],
[(element.x - (0.7071 * (radiusOf(element) - minNodeSize))), (element.y - (0.7071 * (radiusOf(element) - minNodeSize)))],
[(element.x - (radiusOf(element) - minNodeSize)), (element.y)],
[(element.x - (0.7071 * (radiusOf(element) - minNodeSize))), (element.y + (0.7071 * (radiusOf(element) - minNodeSize)))]
]); })
return "M" + d3.geom.hull( fakePoints ).join("L") + "Z";
};
var groupHullFill = function(d, i) { return groupHullColor; };
var subgroupHullFill = function(d, i) { return subgroupHullColor; };
var subsubgroupHullFill = function(d, i) { return subsubgroupHullColor; };
var groupNodes,subgroupNodes,subsubgroupNodes;
//d3.json("readme.json", function(error, json) {
// if (error) throw error;
//root = json;
// update();
root = {
"name": "flare",
"depth": 1,
"size": 45000,
"children": [
{
"name": "analytics",
"depth": 2,
"size": 33700,
"children": [
{
"name": "cluster",
"depth": 3,
"size": 9700,
"children": [
{"name": "AgglomerativeCluster", "size": 4000, "depth": 4},
{"name": "CommunityStructure", "size": 2000, "depth": 4},
{"name": "HierarchicalCluster", "size": 3000, "depth": 4},
{"name": "MergeEdge", "size": 700, "depth": 4}
]
},
{
"name": "graph",
"depth": 3,
"size": 21000,
"children": [
{"name": "BetweennessCentrality", "size": 4000,"depth": 4},
{"name": "LinkDistance", "size": 5000,"depth": 4},
{"name": "MaxFlowMinCut", "size": 7000,"depth": 4},
{"name": "ShortestPaths", "size": 3000,"depth": 4},
{"name": "SpanningTree", "size": 2000,"depth": 4}
]
},
{
"name": "optimization",
"depth": 3,
"size": 3000,
"children": [
{"name": "AspectRatioBanker", "size": 3000,"depth": 4}
]
}
]
},
{
"name": "anamyers",
"depth": 2,
"size": 12000,
"children": [
{"name": "AspectRatio1", "size": 3000,"depth": 3},
{"name": "Aspect2", "size": 9000,"depth": 3}
]
}
]
}
var nd = flatten(root); //to set ids
// This takes the list of group members and converts into lists lof lists of nodes
groupNodes = groups.map(function(group,index){
return group.map(function(member){return nd[member-1] });
});
subgroupNodes = subgroups.map(function(group,index){
return group.map(function(member){return nd[member-1] });
});
subsubgroupNodes = subsubgroups.map(function(group,index){
return group.map(function(member){return nd[member-1] });
});
//console.log("groupNodes : " + groupNodes);
setParents(root, null);
collapseAll(root);
//root.children = root._children;
// root._children = null;
update();
//});
function update() {
var nodes = flatten(root),
links = d3.layout.tree().links(nodes);
// Restart the force layout.
force
.nodes(nodes)
.links(links)
.start();
//Update the links…
link = svg.selectAll("line.link")
.data(links, function(d) { return d.target.id; });
// Exit any old links.
link.exit().remove();
// Enter any new links.
link.enter().insert("line", ".node")
.attr("class", "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; });
// Update the nodes…
node = node.data(nodes, function(d) { return d.id; })
.style("fill", color)
// Exit any old nodes.
node.exit().remove();
//new code
node.transition()
.attr("r", function(d) { return d.children ? 8.5 : Math.sqrt(d.size) / 10; })
.style("stroke", function(d) { return 'steelblue'})
.style("stroke-width", function(d) { if (d.children) { return 2.5 } else { return 0.5 }})
.style("stroke-dasharray", function(d) { if (d.children) { return "10,3" } else { return "0,0" }});// make the stroke dashed
// Enter any new nodes.
node.enter().append("circle")
.attr("class", "node")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", function(d) { return d.children ? 8.5 : Math.sqrt(d.size) / 10;})
// .style("fill", color)
.on("click", click)
.call(force.drag);
node.append("title")
.text(function(d) { return d.name });
}
function tick() {
var flag = true;
var nodes = flatten(root),
links = d3.layout.tree().links(nodes);
// this updates the convex hulls
svg.selectAll("path").remove();
svg.selectAll("path#group")
.data(groupNodes)
// .attr("d", drawCluster)
.enter().insert("path", "circle")
.attr("class", "group")
.style("fill", groupHullFill)
.style("stroke", groupHullFill)
.style("stroke-width", 45)
.style("stroke-linejoin", "round")
.style("opacity", .5)
.attr("ID","group")
.attr("d", groupPath);
svg.selectAll("path#subgroup")
.data(subgroupNodes)
.enter().insert("path", "circle")
.style("fill", subgroupHullFill)
.style("stroke", subgroupHullFill)
.style("stroke-width", 25)
.style("stroke-linejoin", "round")
.style("opacity", .2)
.attr("ID","subgroup")
.attr("d", groupPath);
svg.selectAll("path#subsubgroup")
.data(subsubgroupNodes)
.enter().insert("path", "circle")
.style("fill", subsubgroupHullFill)
.style("stroke", subsubgroupHullFill)
.style("stroke-width", 15)
.style("stroke-linejoin", "round")
.style("opacity", 0.2)
.attr("ID","subsubgroup")
.attr("d", groupPath);
// this redraws the links on top of the convex hulls
link = svg.selectAll("line.link")
.data(links, function(d) { return d.target.id; });
// Exit any old links.
link.exit().remove();
// Enter any new links.
link.enter().insert("line", ".node")
.attr("class", "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; });
// Update the nodes…
node = node.data(nodes, function(d) { return d.id; })
.style("fill", color);
// Exit any old nodes.
node.exit().remove();
// Enter any new nodes.
node.enter().append("circle")
.attr("class", "node")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", function(d) { return d.children ? 8.5 : Math.sqrt(d.size) / 10;})
//.style("fill", color)
.on("click", click)
.call(force.drag);
node.append("title")
.text(function(d) { return d.name });
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("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
// Color leaf nodes orange, and packages white or blue.
function color(d) {
return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}
// Toggle children on click.
function click(d) {
if (!d3.event.defaultPrevented) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update();
}
}
//Returns a list of all nodes under the root.
function flatten(root) {
var nodes = [], i = 0;
function recurse(node) {
//if (node.children) node.size = node.children.reduce(function(p, v) { return p + recurse(v); }, 0);
if (node.children) node.children.forEach(recurse);
if (!node.id) node.id = ++i;
nodes.push(node);
return node.size;
}
root.size = recurse(root);
console.log("nodes : - : " + nodes);
return nodes;
}
function collapseAll(d){
//svg.selectAll("path").remove();
if (d.children){
d.children.forEach(collapseAll);
d._children = d.children;
d.children = null;
}
else if (d._children){
d._children.forEach(collapseAll);
d.children = d._children;
d._children = null;
}
}
function setParents(d, p){
d._parent = p;
if (d.children) {
d.children.forEach(function(e){ setParents(e,d);});
} else if (d._children) {
d._children.forEach(function(e){ setParents(e,d);});
}
}
.node {
cursor: pointer;
stroke: #000;
stroke-width: .5px;
}
.link {
fill: none;
stroke: #9ecae1;
stroke-width: 1.5px;
}
<!DOCTYPE html>
<html>
<head>
<title>Force-Directed Graph</title>
<script src="https://d3js.org/d3.v3.min.js"></script>
</head>
<body>
</body>
</html>