d3.js实现隐藏部分关系

如果用d3画人物图的话,这个问题会经常遇到。

例如:人物A和人物B之间的关系有:同学、亲戚、同事;人物A和人物C之间的关系有:同学、同事;

需求:不想看到亲戚关系。(为什么会有这样的需求:节点多了后,各种复杂关系都显示出来了,看着就密密麻麻,隐藏部分关系后,看起来就清爽多了)

原始图:                                                                                 隐藏“亲戚”关系后的图:

要实现这样的隐藏部分关系效果的解决方案:

(1)修改json文件:方法:把“亲戚”所在的关系进行处理,relation.replace("亲戚",“”),重新加载一次json文件。

缺点:界面相当于重新绘制了一遍,用户体验不太好,尤其是你的人物关系图是动态的时候。

难易程度:简单

(2)界面刷新:方法:遍历每条线上的关系,找到“亲戚”所在的关系,标记“亲戚”(添加一个类),然后设置该类不可见。

优点:界面没有进行刷新,用户体验比较好

优点:要给一个文字关系添加一个类

难易程度:困难

以上是我的两个解决问题的思路。

方案一代码:

<html>
<head>
    <meta charset="utf-8">  
    <title>隐藏部分关系通过切换json文件</title>  
  <style>

.nodetext {
    font-size: 12px ;
    font-family: SimSun;
    fill:#000000;
}

.linetext {
    font-size: 12px ;
    font-family: SimSun;
    fill:#1f77b4;
}

.circleImg {
  stroke: #ff7f0e;
  stroke-width: 1.5px;
}
</style></head> 

    <body>  
    	<div class="lay" style="position: fixed;top: 20px;left: 20px;">
			<button id="button">隐藏   亲戚  关系</button>
		</div>
		
        <script src="d3.js" type="text/javascript" charset="utf-8"></script>
        <script>     
        var data1 = "data1.json";
        var data2 = "data2.json";
        
        var width = 900;
        var height = 800;
        var img_w = 77;
        var img_h = 80;
        var radius = 30;    
        var svg = d3.select("body").append("svg")
                                .attr("width",width)
                                .attr("height",height);
        function updatesvg(soursefile){
        	d3.select("svg").selectAll("*").remove();
        	d3.json(soursefile,function(error,root){
            if( error ){
                return console.log(error);
            }
            console.log(root);
            //D3力导向布局
            var force = d3.layout.force()
                            .nodes(root.nodes)
                            .links(root.edges)
                            .size([width,height])
                            .linkDistance(200)
                            .charge(-1500)
                            .start();
            //边             
            var edges_line = svg.selectAll("line")
                                .data(root.edges)
                                .enter()
                                .append("line")
                                .style("stroke","#ccc")
                                .style("stroke-width",1);
            //边上的文字(人物之间的关系)            
            var edges_text = svg.selectAll(".linetext")
                                .data(root.edges)
                                .enter()
                                .append("text")
                                .attr("class","linetext")
                                .style("display","block")
                                .style("color","red")
                                .text(function(d){
                                    return d.relation;
                                });
            // 圆形图片节点(人物头像)
            var nodes_img = svg.selectAll("image")
                                .data(root.nodes)
                                .enter()
                                .append("circle")
                                .attr("class", "circleImg")
                                .attr("r", radius)
                                .attr("fill", function(d, i){
                                    //创建圆形图片
                                    var defs = svg.append("defs").attr("id", "imgdefs")
                                    var catpattern = defs.append("pattern")
                                                            .attr("id", "catpattern" + i)
                                                            .attr("height", 1)
                                                            .attr("width", 1)
                                    catpattern.append("image")
                                            .attr("x", - (img_w / 2 - radius))
                                            .attr("y", - (img_h / 2 - radius))
                                            .attr("width", img_w)
                                            .attr("height", img_h)
                                            .attr("xlink:href", d.image)
                                    return "url(#catpattern" + i + ")";

                                })
                                .call(force.drag);
            var text_dx = -20;
            var text_dy = 20;
            var nodes_text = svg.selectAll(".nodetext")
                                .data(root.nodes)
                                .enter()
                                .append("text")
                                .attr("class","nodetext")
                                .attr("dx",text_dx)
                                .attr("dy",text_dy)
                                .text(function(d){
                                    return d.name;
                                });
            force.on("tick", function(){
                 //更新连接线的位置
                 edges_line.attr("x1",function(d){ return d.source.x; });
                 edges_line.attr("y1",function(d){ return d.source.y; });
                 edges_line.attr("x2",function(d){ return d.target.x; });
                 edges_line.attr("y2",function(d){ return d.target.y; });
                 //更新连接线上文字的位置
                 edges_text.attr("x",function(d){ return (d.source.x + d.target.x) / 2 ; });
                 edges_text.attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; });
                 //更新结点图片和文字
                 nodes_img.attr("cx",function(d){ return d.x });
                 nodes_img.attr("cy",function(d){ return d.y });
                 //联系
                 nodes_text.attr("x",function(d){ return d.x });
                 nodes_text.attr("y",function(d){ return d.y + img_w/2; });
            });
        });
        }
        updatesvg(data1);
		var btn = document.getElementById("button");
		btn.onclick = function(){
			//这里应该要遍历json文件,找到"亲戚"再删除后生成新的json,再作为参数传递
			var data3 = "data3.json";
			updatesvg(data3);
		}
        </script>  
</body>
</html>

通过改动json文件来实现部分隐藏,此时要复原就基本不可能了。

于是测试第二种方案。目前我把包含“亲戚”的关系都隐藏起来了,并未实现部分隐藏,希望大家改进改进,共同学习。如果我解决了,也会及时更新。

以下是代码:

<html>
<head>
    <meta charset="utf-8">  
    <title>隐藏部分关系</title>  
  <style>

.nodetext {
    font-size: 12px ;
    font-family: SimSun;
    fill:#000000;
}

.linetext {
    font-size: 12px ;
    font-family: SimSun;
    fill:#1f77b4;
}

.baohan{
	display: none;
	opacity: 0;
}
.circleImg {
  stroke: #ff7f0e;
  stroke-width: 1.5px;
}

</style></head> 

    <body>  
    	<div class="lay" style="position: fixed;top: 20px;left: 20px;">
			<button id="button3">隐藏 亲戚 关系</button>
			<button id="button4">显示 亲戚 关系</button>
		</div>
		
        <script src="d3.js" type="text/javascript" charset="utf-8"></script>
        <script>     
        var data1 = "data1.json";
        var data2 = "data2.json";
        
        var width = 900;
        var height = 800;
        var img_w = 77;
        var img_h = 80;
        var radius = 30;    
        var svg = d3.select("body").append("svg")
                                .attr("width",width)
                                .attr("height",height);
        function updatesvg(soursefile){
        	d3.select("svg").selectAll("*").remove();
        	d3.json(soursefile,function(error,root){
            if( error ){
                return console.log(error);
            }
            console.log(root);
            //D3力导向布局
            var force = d3.layout.force()
                            .nodes(root.nodes)
                            .links(root.edges)
                            .size([width,height])
                            .linkDistance(200)
                            .charge(-1500)
                            .start();
            //边             
            var edges_line = svg.selectAll("line")
                                .data(root.edges)
                                .enter()
                                .append("line")
                                .style("stroke","#ccc")
                                .style("stroke-width",1);
            //边上的文字(人物之间的关系)            
            var edges_text = svg.selectAll(".linetext")
                                .data(root.edges)
                                .enter()
                                .append("text")
                                .attr("class","linetext")
                                .style("display","block")
                                .style("color","red")
                                .text(function(d){
                                    return d.relation;
                                });
            // 圆形图片节点(人物头像)
            var nodes_img = svg.selectAll("image")
                                .data(root.nodes)
                                .enter()
                                .append("circle")
                                .attr("class", "circleImg")
                                .attr("r", radius)
                                .attr("fill", function(d, i){
                                    //创建圆形图片
                                    var defs = svg.append("defs").attr("id", "imgdefs")
                                    var catpattern = defs.append("pattern")
                                                            .attr("id", "catpattern" + i)
                                                            .attr("height", 1)
                                                            .attr("width", 1)
                                    catpattern.append("image")
                                            .attr("x", - (img_w / 2 - radius))
                                            .attr("y", - (img_h / 2 - radius))
                                            .attr("width", img_w)
                                            .attr("height", img_h)
                                            .attr("xlink:href", d.image)
                                    return "url(#catpattern" + i + ")";

                                })
                                .call(force.drag);
            var text_dx = -20;
            var text_dy = 20;
            var nodes_text = svg.selectAll(".nodetext")
                                .data(root.nodes)
                                .enter()
                                .append("text")
                                .attr("class","nodetext")
                                .attr("dx",text_dx)
                                .attr("dy",text_dy)
                                .text(function(d){
                                    return d.name;
                                });
            force.on("tick", function(){
                 //更新连接线的位置
                 edges_line.attr("x1",function(d){ return d.source.x; });
                 edges_line.attr("y1",function(d){ return d.source.y; });
                 edges_line.attr("x2",function(d){ return d.target.x; });
                 edges_line.attr("y2",function(d){ return d.target.y; });
                 //更新连接线上文字的位置
                 edges_text.attr("x",function(d){ return (d.source.x + d.target.x) / 2 ; });
                 edges_text.attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; });
                 //更新结点图片和文字
                 nodes_img.attr("cx",function(d){ return d.x });
                 nodes_img.attr("cy",function(d){ return d.y });
                 //联系
                 nodes_text.attr("x",function(d){ return d.x });
                 nodes_text.attr("y",function(d){ return d.y + img_w/2; });
            });
            document.getElementById("button3").onclick = function(){
	            d3.selectAll(".linetext").each(function(d,i){
					console.log("关系:"+d.relation);
					if(d.relation.indexOf("亲戚")>-1){
						console.log("包含:亲戚");
						var result = d.relation.replace("亲戚", "");
						console.log("替换后的结果:"+result);
						d3.select(this).attr("class","linetext baohan")
					}
				})
            }
            document.getElementById("button4").onclick = function(){
	            d3.selectAll(".linetext").each(function(d,i){
					console.log("关系:"+d.relation);
					if(d.relation.indexOf("亲戚")>-1){
						console.log("包含:亲戚");
						var result = d.relation.replace("亲戚", "");
						console.log("替换后的结果:"+result);
						d3.select(this).attr("class","linetext")
					}
				})
            }
        });
        }
        updatesvg(data1);
        </script>  
</body>
</html>

附:json文件

data1.json:

{
	"nodes":[
	{ "name": "测试1"   , "image" : "renwu.jpg" },
	{ "name": "测试2"   , "image" : "renwu.jpg" },
	{ "name": "测试3"   , "image" : "renwu.jpg" }
	],
	"edges":[
	{ "source": 0 , "target": 1 , "relation":"同学 同事 亲戚" },
	{ "source": 0 , "target": 2 , "relation":"同学 同事 " }
	]
}

data3.json:

{
	"nodes":[
	{ "name": "测试1"   , "image" : "renwu.jpg" },
	{ "name": "测试2"   , "image" : "renwu.jpg" },
	{ "name": "测试3" , "image" : "renwu.jpg" }
	],
	"edges":[
	{ "source": 0 , "target": 1 , "relation":"同学 同事" },
	{ "source": 0 , "target": 2 , "relation":"同学 同事" }
	]
}

猜你喜欢

转载自blog.csdn.net/songxiaolingbaobao/article/details/81197093