1 回答
TA贡献1777条经验 获得超3个赞
您将希望选择菜单具有代表每个上下文的值:
<select>
<option value="Jira">01 - Jira</option>
<option value="Ivis">02 - Ivis</option>
<option value="All" selected>Whatever</option>
</select>
然后你会想听听这种情况的改变。当它发生变化时,您会将所有节点恢复为正常状态,并过滤那些具有与所选节点匹配的上下文的节点。
由于您有两个不同的子元素,因此您可能想要以不同的方式更改颜色和不透明度。下面我首先更改了标签和圆的不透明度,然后选择每个节点的圆并更改填充:
d3.select("select").on("change", function() {
var value = this.value;
// Reset every node:
node.style("opacity", 1) // change opacity back for every node
.select("circle") // select the circle to alter its color
.style("fill", function(d) { return color(d.group); });
// If "All" isn't selected, filter for the selected value:
if(value != "All") {
node.filter(function(d) { return d.kontext != value; })
.style("opacity", 0.5) // Change the opacity of text and circle for filtered items
.select("circle") // select the circle to alter its color
.style("fill","#aaa");
}
})
综合起来我们得到:
var graph = {
nodes:[
{id: "0001", name: "s02vmware", kontext: "Jira", group: 1},
{id: "0002", name: "v133atlas", kontext: "Jira", group: 2},
{id: "0003", name: "Linux", kontext: "Jira", group: 2},
{id: "0004", name: "PostgreSQL", kontext: "Jira", group: 2},
{id: "0005", name: "OpenSSH", kontext: "Jira", group: 2},
{id: "0006", name: "Nginx", kontext: "Jira", group: 2},
{id: "0007", name: "Confluence", kontext: "Jira", group: 3},
{id: "0008", name: "Tomcat", kontext: "Jira", group: 3},
{id: "0009", name: "Java", kontext: "Jira", group: 3},
{id: "0010", name: "Test1", kontext: "Ivis", group: 1},
{id: "0011", name: "Test2", kontext: "Ivis", group: 2},
{id: "0012", name: "Test3", kontext: "Ivis", group: 2},
],
links:[
{source: "0001", target: "0002"},
{source: "0002", target: "0003"},
{source: "0004", target: "0003"},
{source: "0005", target: "0003"},
{source: "0006", target: "0003"},
{source: "0007", target: "0003"},
{source: "0008", target: "0007"},
{source: "0009", target: "0007"},
{source: "0010", target: "0012"},
{source: "0011", target: "0010"},
{source: "0012", target: "0011"},
]
};
var svg = d3.select("svg"),
width = 500,
height = 300;
var color = d3.scaleOrdinal(d3.schemeCategory20);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.id; }).distance(100))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.force("attraceForce",d3.forceManyBody().strength(10));
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", 2);
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.on("mouseover", mouseover)
.on("mouseout", mouseout)
/*
.on("click", function(d) {
div.transition()
.duration(200)
.style("opacity", 0.9);
div .html((d.name) + "<br/>" + d.close)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px")*/
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
node.append("circle")
.attr("r", 15)
.attr("fill", function(d) { return color(d.group); });
node.append("text")
.attr("dy", -20)
.text(function(d) { return d.name; });
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.links);
function ticked() {
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("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
function mouseover() {
d3.select(this).select("circle").transition()
.duration(100)
.attr("r", 20);
}
function mouseout() {
d3.select(this).select("circle").transition()
.duration(500)
.attr("r", 15);
}
d3.select("select").on("change", function() {
var value = this.value;
// Reset every node:
node.style("opacity", 1) // change opacity back for every node
.select("circle") // select the circle to alter its color
.style("fill", function(d) { return color(d.group); });
// If "All" isn't selected, filter for the selected value:
if(value != "All") {
node.filter(function(d) { return d.kontext != value; })
.style("opacity", 0.5) // Change the opacity of text and circle for filtered items
.select("circle") // select the circle to alter its color
.style("fill","#aaa");
}
})
/* todo: add styles */
.vertical-grid{
stroke:#ccc;
}
.ordinate-text{
font-size:10px;
transform:translateY(10px);
}
div.tooltip {
position: absolute;
text-align: center;
width: auto;
height: auto;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
opacity:0;
padding:5px;
}
.right-align{
position:absolute;
right:100px;
}
.box,
.label{
display:inline-block;
}
.box{
width:10px;
height:10px;
margin:0px 10px;
}
<!DOCTYPE html>
<head>
<meta charset = "utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Ideal iDEP on D3.js</title>
</head>
<body>
<!-- Kontext Option Button -->
<select>
<option value="Jira">01 - Jira</option>
<option value="Ivis">02 - Ivis</option>
<option value="All" selected>Whatever</option>
</select>
<!-- SVG as a canvas area -->
<svg width="500" height="300"></svg>
<!--<svg id="canvas" width="100%" height="100%"></svg> -->
<!-- import d3.js library -->
<script src="https://d3js.org/d3.v4.js"></script>
<!-- where the magic is happening -->
<script type="" src="appv4.js"></script>
</body>
</html>
如果节点可以是多个上下文的一部分:
{id: "0002", name: "name1", kontext: ["ContextA"], group: 2}, {id: "0003", name: "name2", kontext: ["ContextA","ContextB"] , group: 2},
您需要检查所选上下文是否在 kontext 数组中,如果所有 kontext 属性都是数组(而不是某些字符串和数组),这也会更容易。如果 kontext 是一个数组,你会得到类似的东西:
node.filter(function(d) { return d.kontext.indexOf(value) == -1; })
添加回答
举报