[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能

[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能前面作者讲解了很多知识图谱原理知识,包括知识图谱相关技术、Neo4j绘制关系图谱等,但仍缺少一个系统全面的实例。为了加深自己对知识图谱构建的认识,为后续创建贵州旅游知识图谱打下基础,作者深入学习了张宏伦老师的网易云课程,并结合自己的理解和技术分享了该系列专栏,从数据采集、数据展示、数据分析到知识图谱构建,文章后续还会讲解中文数据的实体识别、关系抽取、知识计算等。前面通过六篇文章基本构建了电影知识图谱,并且能显示选中节点相关联的边及属性。

大家好,又见面了,我是你们的朋友全栈君。

前面作者讲解了很多知识图谱原理知识,包括知识图谱相关技术、Neo4j绘制关系图谱等,但仍缺少一个系统全面的实例。为了加深自己对知识图谱构建的认识,为后续创建贵州旅游知识图谱打下基础,作者深入学习了张宏伦老师的网易云课程(星球系列电影),并结合自己的理解和技术分享了该系列专栏,从数据采集、数据展示、数据分析到知识图谱构建,文章后续还会讲解中文数据的实体识别、关系抽取、知识计算等。

前面通过六篇文章基本构建了电影知识图谱,并且能显示选中节点相关联的边及属性,如下图所示:


[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能

本文主要增加了一个搜索功能,通过该搜索框能展示搜索节点的相关内容,同时在张老师的基础上增加搜索节点相关联的边及节点。如下图所示:


[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能


[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能

代码下载地址:https://download.csdn.net/download/eastmount/10958879
Github下载地址:https://github.com/eastmountyxz/Knowledge-Graph-Movie

这是一系列基础性文章,希望对您有所帮助 ,尤其是对知识图谱感兴趣和编程刚入门的同学。同时也因为最近准备博士考试,做题做吐了,写点新专栏调节下心情,与君共勉,一起加油。

前文:
[知识图谱实战篇] 一.数据抓取之Python3抓取JSON格式的电影实体
[知识图谱实战篇] 二.Json+Seaborn可视化展示电影实体
[知识图谱实战篇] 三.Python提取JSON数据、HTML+D3构建基本可视化布局
[知识图谱实战篇] 四.HTML+D3+CSS绘制关系图谱
[知识图谱实战篇] 五.HTML+D3添加鼠标响应事件显示相关节点及边
[知识图谱实战篇] 六.HTML+D3实现点击节点显示相关属性及属性值

推荐作者的知识图谱前文:
知识图谱相关会议之观后感分享与学习总结
中文知识图谱研讨会的学习总结 (上) 图谱引入、百度知心、搜狗知立方
搜索引擎和知识图谱那些事 (上).基础篇
基于VSM的命名实体识别、歧义消解和指代消解

CSDN下载-第一届全国中文知识图谱研讨会演讲PPT 清华大学
CSDN下载-知识图谱PDF资料 清华大学知识图谱研讨会汇报PPT

[知识图谱构建] 一.Neo4j图数据库安装初识及药材供应图谱实例
[知识图谱构建] 二.《Neo4j基础入门》基础学习之创建图数据库节点及关系
[关系图谱] 一.Gephi通过共线矩阵构建知网作者关系图谱
[关系图谱] 二.Gephi导入共线矩阵构建作者关系图谱

再次强烈推荐大家阅读张宏伦老师的网易云课程及Github源码,受益匪浅。
https://github.com/Honlan/starwar-visualization/tree/master/star_war
https://study.163.com/course/courseLearn.htm?courseId=1003528010


一.HTML增加搜索框

首先,利用HTML绘制一个搜索框。

<!-- 绘制搜索框 -->
<div id="search">
	<input type="text" class="form-control">
</div>

注意,class为form-control,它是bootstrap的基本样式,所以需要在前面导入基本样式代码,如下:

<link href="http://cdn.bootcss.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<script src="http://cdn.bootcss.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>

此时,你会发现新增的搜索框已经被置于底部,接着需要通过CSS设置其样式。


[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能

CSS增加样式代码如下:绝对定位、位置、颜色、边框去掉、outline去掉、阴影 去掉、跨度设置、背景颜色设置。

#search input {
    position: absolute;
    top: 220px;
    left: 60px;
    color: #fff;
    border: none;
    outline: none;
    box-shadow: none;
    width: 200px;
    background-color: #666;
}

此时就增加好了搜索框:


[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能


二.JS增加搜索响应事件

当搜索框设置完成之后,再设置其响应事件。添加事件 $(’#search1 input’).keyup(function(event) {})
其基本功能表示:

  • 当输入内容则响应该事件keyup
  • 如果input值为空,即没有输入搜索内容则显示所有圆和边
  • 如果有搜索内容,显示搜索相关联的节点
  • 同时设置Texts、所有边隐藏
<script type="text/javascript"> //搜索框中输入内容则响应该事件 //keyup按键敲击响应event $('#search input').keyup(function(event) { 
     //如果Input值是空的显示所有的圆和线(没有进行筛选) if ($(this).val() == '') { 
     d3.select('#svg1 .texts').selectAll('text').attr('class', ''); d3.select('#svg1 .nodes').selectAll('circle').attr('class', ''); d3.select('#svg1 .links').selectAll('line').attr('class', ''); } //否则判断判断三个元素是否等于name值,等于则显示该值 else { 
     var name = $(this).val(); //搜索所有的节点 d3.select('#svg1 .nodes').selectAll('circle').attr('class', function(d) { 
     //输入节点id的小写等于name则显示,否则隐藏 if (d.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) { 
     return ''; } else { 
     return 'inactive'; //隐藏 } }); //搜索texts d3.select('#svg1 .texts').selectAll('text').attr('class', function(d) { 
     if (d.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) { 
     return ''; } else { 
     return 'inactive'; } }); //搜索links d3.select("#svg1 .links").selectAll('line').attr('class', function(d) { 
     //return 'inactive'; }); } }); </script>

此时的运行效果如下图所示,比如搜索 luke 则反馈该节点,它是一个人物。
点击“文字”的搜索也是如此,仅显示单一节点。


[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能


三.优化代码-显示相关联节点及边

但我们更期待的结果是反馈搜索节点及其相关联的边及节点,下面作者结合之前的文章进行优化。此时原理很简单,增加一个循环,判断所有边的起点(Source)或终点(Target)与该搜索节点相邻,则显示,否则设置其class属性为’inactive’,即隐藏节点。

核心代码如下:

<script> //搜索框中输入内容则响应该事件 //keyup按键敲击响应event $('#search input').keyup(function(event) { 
     //如果Input值是空的显示所有的圆和线(没有进行筛选) if ($(this).val() == '') { 
     d3.select('#svg1 .texts').selectAll('text').attr('class', ''); d3.select('#svg1 .nodes').selectAll('circle').attr('class', ''); d3.select('#svg1 .links').selectAll('line').attr('class', ''); } //否则判断判断三个元素是否等于name值,等于则显示该值 else { 
     var name = $(this).val(); //搜索所有的节点 d3.select('#svg1 .nodes').selectAll('circle').attr('class', function(d) { 
     //输入节点id的小写等于name则显示,否则隐藏 if (d.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) { 
     return ''; } else { 
     //优化:与该搜索节点相关联的节点均显示 //links链接的起始节点进行判断,如果其id等于name则显示这类节点 //注意: graph=data for (var i = 0; i < graph.links.length; i++) { 
     //如果links的起点等于name,并且终点等于正在处理的则显示 if ((graph.links[i]['source'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['target'].id == d.id)) { 
     return ''; } //如果links的终点等于name,并且起点等于正在处理的则显示 if ((graph.links[i]['target'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['source'].id == d.id)) { 
     return ''; } } return 'inactive'; //隐藏其他节点  } }); //搜索texts d3.select('#svg1 .texts').selectAll('text').attr('class', function(d) { 
     if (d.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) { 
     return ''; } else { 
     //优化:与该搜索节点相关联的节点均显示 //links链接的起始节点进行判断,如果其id等于name则显示这类节点 //注意: graph=data for (var i = 0; i < graph.links.length; i++) { 
     //如果links的起点等于name,并且终点等于正在处理的则显示 if ((graph.links[i]['source'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['target'].id == d.id)) { 
     return ''; } //如果links的终点等于name,并且起点等于正在处理的则显示 if ((graph.links[i]['target'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['source'].id == d.id)) { 
     return ''; } } return 'inactive'; //隐藏其他节点 } }); //搜索links 所有与搜索name相关联的边均显示 //显示相的邻边 注意 ||  //name=$(this).val():名字为键盘输入的内容 d3.select("#svg1 .links").selectAll('line').attr('class', function(d) { 
     if ((d.source.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) || (d.target.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) ) { 
     return ''; } else { 
     return 'inactive'; //隐藏 } }); } }); //end input </script>

运行结果如下图所示,同时如果有多个名字相关的节点,它们与其关联的节点和边均会显示。


[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能


[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能

PS:但是也存在一个问题,即右边显示的属性为鼠标选中显示,而搜索通常不能显示属性,但这不会影响整体效果。


[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能


四.完整代码

完整代码如下所示:

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>知识图谱</title>
    <meta name="description" content="" />
    <meta name="keywords" content="" />
    <meta name="author" content="" />
    <link rel="shortcut icon" href="">
    <script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
    <link href="http://cdn.bootcss.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
    <script src="http://cdn.bootcss.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
</head>
<style type="text/css"> body { 
     background-color: #272b30; padding: 30px 40px; text-align: center; font-family: OpenSans-Light, PingFang SC, Hiragino Sans GB, Microsoft Yahei, Microsoft Jhenghei, sans-serif; } #indicator { 
     position: absolute; left: 60px; bottom: 120px; text-align: left; color: #f2f2f2; font-size: 12px; } #indicator>div { 
     margin-bottom: 4px; } #indicator span { 
     display: inline-block; width: 30px; height: 14px; position: relative; top: 2px; margin-right: 8px; } .links line { 
     stroke: rgb(240, 240, 240); stroke-opactity: 0.2; } .links line.inactive { 
     /*display: none !important;*/ stroke-opacity: 0; } .nodes circle { 
     stroke: #fff; stroke-width: 1.5px; } .nodes circle:hover { 
     cursor: pointer; } .nodes circle.inactive { 
     display: none !important; } .texts text { 
     display: none; } .texts text:hover { 
     cursor: pointer; } .texts text.inactive { 
     display: none !important; } #mode { 
     position: absolute; top: 160px; left: 60px; } #mode span { 
     display: inline-block; border: 1px solid #fff; color: #fff; padding: 6px 10px; border-radius: 4px; font-size: 14px; transition: color, background-color .3s; -o-transition: color, background-color .3s; -ms-transition: color, background-color .3s; -moz-transition: color, background-color .3s; -webkit-transition: color, background-color .3s; } #mode span.active, #mode span:hover { 
     background-color: #fff; color: #333; cursor: pointer; } #info { 
     position: absolute; bottom: 40px; right: 30px; text-align: right; width: 270px; } #info p { 
     color: #fff; font-size: 12px; margin-top: 0; margin-bottom: 5px; } #info p span { 
     color: #888; margin-right: 10px; } #info h4 { 
     color: #fff; } #search input { 
     position: absolute; top: 220px; left: 60px; color: #fff; border: none; outline: none; box-shadow: none; width: 200px; background-color: #666; } </style>
<body>

	<!-- 绘制标题样式 -->
	<h1 style="color:#fff;font-size:32px;margin-bottom:0px;text-align:center;margin-left:40px;">Star Wars</h1>

	<!-- 第一个布局 绘制知识图谱主图 -->
	<div style="text-align: center; position:relative;">
		<svg width="800" height="560" style="margin-right:80px;margin-bottom:-40px;" id="svg1">
    	</svg>

    	<!-- 绘制图例 -->
		<div id="indicator">
	    </div>

	    <!-- 绘制模式选择 -->
	    <div id="mode">
	    	<span class="active" style="border-top-right-radius:0;border-bottom-right-radius:0;">节点</span>
            <span style="border-top-left-radius:0;border-bottom-left-radius:0;position:relative;left:-5px;">文字</span>
	    </div>

	    <!-- 绘制搜索框 -->
	    <div id="search">
	    	<input type="text" class="form-control">
	    </div>

	    <!-- 绘制右边显示结果 -->
	    <div id="info">
	    	<h4></h4>
	    </div>
	</div>

	<!-- 第二个布局 下部分时间点 文本居中 相对定位-->
	<div style="text-align: center; position:relative;">
		<svg width="960" height="240" style="margin-right:60px;margin-bottom:-40px;" id="svg1">
			<g></g>
    	</svg>
	</div>

</body>

<!-- 增加D3元素库 -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<!-- 补充JS代码 -->
<script type="text/javascript"> $(document).ready(function() { 
     //定义svg变量将布局svg1选出来  var svg = d3.select("#svg1"), width = svg.attr("width"), height = svg.attr("height"); //定义name变量制作图标 var names = ['Films', 'Characters', 'Planets', 'Starships', 'Vehicles', 'Species']; var colors = ['#6ca46c', '#4e88af', '#ca635f', '#d2907c', '#d6744d', '#ded295']; //背景颜色设置 补充CSS样式设置字体布局 for (var i=0; i < names.length; i++) { 
     $('#indicator').append("<div><span style='background-color:" + colors[i] + "'></span>" + names[i] + "</div>"); } //利用d3.forceSimulation()定义关系图 包括设置边link、排斥电荷charge、关系图中心点 var simulation = d3.forceSimulation() .force("link", d3.forceLink().id(function(d) { 
     return d.id; })) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width / 2, height / 2)); //存储关系图的数据 var graph; //定义d3.json请求python处理好的节点及边 请求成功返回数据,否则报错 d3.json("starwar_alldata.json", function(error, data) { 
     if(error) throw error; graph = data; console.log(graph); //D3映射数据至HTML中 //g用于绘制所有边,selectALL选中所有的line,并绑定数据data(graph.links),enter().append("line")添加元素 //数据驱动文档,设置边的粗细 //前面定义var svg = d3.select("#svg1") var link = svg.append("g").attr("class","links").selectAll("line").data(graph.links) .enter().append("line").attr("stroke-width", function(d) { 
     //return Math.sqrt(d.value); return 1; //所有线宽度均为1 }); //添加所有的点 //selectAll("circle")选中所有的圆并绑定数据,圆的直径为d.size //再定义圆的填充色,同样数据驱动样式,圆没有描边,圆的名字为d.id //call()函数:拖动函数,当拖动开始绑定dragstarted函数,拖动进行和拖动结束也绑定函数 var node = svg.append("g").attr("class", "nodes").selectAll("circle").data(graph.nodes) .enter().append("circle").attr("r", function(d) { 
     return d.size; }).attr("fill", function(d) { 
     return colors[d.group]; }).attr("stroke", "none").attr("name", function(d) { 
     return d.id; }).call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended) ); //显示所有的文本  //设置大小、填充颜色、名字、text()设置文本 //attr("text-anchor", "middle")文本居中 var text = svg.append("g").attr("class", "texts").selectAll("text").data(graph.nodes) .enter().append("text").attr("font-size", function(d) { 
     return d.size; }).attr("fill", function(d) { 
     return colors[d.group]; }).attr('name', function(d) { 
     return d.id; }).text(function(d) { 
     return d.id; }).attr('text-anchor', 'middle').call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended) ); //圆增加title node.append("title").text(function(d) { 
     return d.id; }) //simulation中ticked数据初始化,并生成图形 simulation .nodes(graph.nodes) .on("tick", ticked); simulation.force("link") .links(graph.links); //ticked()函数确定link线的起始点x、y坐标 node确定中心点 文本通过translate平移变化 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("cx", function(d) { 
     return d.x; }) .attr("cy", function(d) { 
     return d.y; }); text. attr('transform', function(d) { 
     return 'translate(' + d.x + ',' + (d.y + d.size / 2) + ')'; }); } }); // Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension // 本地json数据需要放置服务器中请求 XAMPP //该变量保证拖动鼠标时,不会影响图形变换,默认为false未选中鼠标 var dragging = false; //开始拖动并更新相应的点 function dragstarted(d) { 
     if (!d3.event.active) simulation.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; dragging = true; } //拖动进行中 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; dragging = false; } //span点击事件 $('#mode span').click(function(event) { 
     //span都设置为不激活状态 $('#mode span').removeClass('active'); //点击的span被激活 $(this).addClass('active'); //text隐藏 nodes显示 if ($(this).text() == '节点') { 
     $('.texts text').hide(); $('.nodes circle').show(); } else { 
     $('.texts text').show(); $('.nodes circle').hide(); } }); //为svg1父元素下的.nodes circle元素绑定鼠标进入事件 $('#svg1').on('mouseenter', '.nodes circle', function(event) { 
     //通过变量dragging保证拖动鼠标时,其状态不受影响,从而改变图形 //鼠标没有拖动才能处理事件 if(!dragging) { 
     //获取被选中元素的名字 var name = $(this).attr("name"); //设置#info h4样式的颜色为该节点的颜色,文本为该节点name //$(this).attr('fill')表示当前悬浮圆的填充色 $('#info h4').css('color', $(this).attr('fill')).text(name); //每次点击添加属性前把上次显示的信息去除,否则会不断叠加 $('#info p').remove(); //打印悬浮的节点信息 //console.log(info[name]); //遍历所有的 for (var key in info[name]) { 
     //类型复杂的不进行显示 if (typeof(info[name][key]) == 'object') { 
     continue; } //比较复杂的超链接字段不显示 if (key == 'url' || key == 'title' || key == 'name' || key == 'edited' || key == 'created' || key == 'homeworld') { 
     continue; } //显示值及其字段名字 $('#info').append('<p><span>' + key + '</span>' + info[name][key] + '</p>'); } //选择#svg1 .nodes中所有的circle,再增加个class d3.select('#svg1 .nodes').selectAll('circle').attr('class', function(d) { 
     //数据的id是否等于name,返回空 if(d.id==name) { 
     return ''; } //当前节点返回空,否则其他节点循环判断是否被隐藏起来(CSS设置隐藏) else { 
     //links链接的起始节点进行判断,如果其id等于name则显示这类节点 //注意: graph=data for (var i = 0; i < graph.links.length; i++) { 
     //如果links的起点等于name,并且终点等于正在处理的则显示 if (graph.links[i]['source'].id == name && graph.links[i]['target'].id == d.id) { 
     return ''; } if (graph.links[i]['target'].id == name && graph.links[i]['source'].id == d.id) { 
     return ''; } } return "inactive"; //前面CSS定义 .nodes circle.inactive } }); //处理相邻的边line是否隐藏 注意 ||  d3.select("#svg1 .links").selectAll('line').attr('class', function(d) { 
     if (d.source.id == name || d.target.id == name) { 
     return ''; } else { 
     return 'inactive'; } }); } }); //鼠标移开还原原图,显示所有隐藏的点及边 $('#svg1').on('mouseleave', '.nodes circle', function(event) { 
     //如果dragging为false才处理事件 if(!dragging) { 
     d3.select('#svg1 .nodes').selectAll('circle').attr('class', ''); d3.select('#svg1 .links').selectAll('line').attr('class', ''); } }); //鼠标进入文本显示相邻节点及边 $('#svg1').on('mouseenter', '.texts text', function(event) { 
     if (!dragging) { 
     var name = $(this).attr('name'); //同样的代码从选中圆中赋值过来 $('#info h4').css('color', $(this).attr('fill')).text(name); $('#info p').remove(); for (var key in info[name]) { 
     if (typeof(info[name][key]) == 'object') { 
     continue; } if (key == 'url' || key == 'title' || key == 'name' || key == 'edited' || key == 'created' || key == 'homeworld') { 
     continue; } $('#info').append('<p><span>' + key + '</span>' + info[name][key] + '</p>'); } d3.select('#svg1 .texts').selectAll('text').attr('class', function(d) { 
     if (d.id == name) { 
     return ''; } for (var i = 0; i < graph.links.length; i++) { 
     if (graph.links[i]['source'].id == name && graph.links[i]['target'].id == d.id) { 
     return ''; } if (graph.links[i]['target'].id == name && graph.links[i]['source'].id == d.id) { 
     return ''; } } return 'inactive'; }); d3.select("#svg1 .links").selectAll('line').attr('class', function(d) { 
     if (d.source.id == name || d.target.id == name) { 
     return ''; } else { 
     return 'inactive'; } }); } }); //鼠标移除文本还原相应节点及边 $('#svg1').on('mouseleave', '.texts text', function(event) { 
     if (!dragging) { 
     d3.select('#svg1 .texts').selectAll('text').attr('class', ''); d3.select('#svg1 .links').selectAll('line').attr('class', ''); } }); //搜索框中输入内容则响应该事件 //keyup按键敲击响应event $('#search input').keyup(function(event) { 
     //如果Input值是空的显示所有的圆和线(没有进行筛选) if ($(this).val() == '') { 
     d3.select('#svg1 .texts').selectAll('text').attr('class', ''); d3.select('#svg1 .nodes').selectAll('circle').attr('class', ''); d3.select('#svg1 .links').selectAll('line').attr('class', ''); } //否则判断判断三个元素是否等于name值,等于则显示该值 else { 
     var name = $(this).val(); //搜索所有的节点 d3.select('#svg1 .nodes').selectAll('circle').attr('class', function(d) { 
     //输入节点id的小写等于name则显示,否则隐藏 if (d.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) { 
     return ''; } else { 
     //优化:与该搜索节点相关联的节点均显示 //links链接的起始节点进行判断,如果其id等于name则显示这类节点 //注意: graph=data for (var i = 0; i < graph.links.length; i++) { 
     //如果links的起点等于name,并且终点等于正在处理的则显示 if ((graph.links[i]['source'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['target'].id == d.id)) { 
     return ''; } //如果links的终点等于name,并且起点等于正在处理的则显示 if ((graph.links[i]['target'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['source'].id == d.id)) { 
     return ''; } } return 'inactive'; //隐藏其他节点  } }); //搜索texts d3.select('#svg1 .texts').selectAll('text').attr('class', function(d) { 
     if (d.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) { 
     return ''; } else { 
     //优化:与该搜索节点相关联的节点均显示 //links链接的起始节点进行判断,如果其id等于name则显示这类节点 //注意: graph=data for (var i = 0; i < graph.links.length; i++) { 
     //如果links的起点等于name,并且终点等于正在处理的则显示 if ((graph.links[i]['source'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['target'].id == d.id)) { 
     return ''; } //如果links的终点等于name,并且起点等于正在处理的则显示 if ((graph.links[i]['target'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['source'].id == d.id)) { 
     return ''; } } return 'inactive'; //隐藏其他节点 } }); //搜索links 所有与搜索name相关联的边均显示 //显示相的邻边 注意 ||  //name=$(this).val():名字为键盘输入的内容 d3.select("#svg1 .links").selectAll('line').attr('class', function(d) { 
     if ((d.source.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) || (d.target.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) ) { 
     return ''; } else { 
     return 'inactive'; //隐藏 } }); } }); //end input //加载Python获取的Json信息:六类实体详细属性信息 var info; //d3.json获取数据 d3.json("all_data.json", function(error, data) { 
     if(error) throw error; info = data; }); }); </script>
</html>

源码下载地址:https://download.csdn.net/download/eastmount/10958879

希望这篇基础性文章对你有所帮助,尤其是新手。

哎,英语真心太差了,博士也不一定能考上,但我至少奋斗过,这个寒假每日每夜都忙碌着。同时也希望未来能有更多时间学习新知识,分享新知识。未来的路谁又知道,作为一名大学老师,希望自己能始终保持初心,教好自己的每一个学生;作为一名程序员,希望自己知道学无止境,写好自己的每一篇博文;作为一名主人公,希望自己能照顾好另一伴,爱她就像爱生命。我毫无阅历,毫无准备,我一头栽进我的命里,就像跌进一个深坑,从那一秒钟起,我的心里只有一个,就是你。

(By:Eastmount 2019-02-14 下午4点 http://blog.csdn.net/eastmount/)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/153318.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 多维数组转化为一维数组_数组的大小长度可以改变吗

    多维数组转化为一维数组_数组的大小长度可以改变吗allocaalloca是GNUlibc中的内存分配函数。voidfunc(){void*p=alloca(size);//dosomethingusingp//…}一般来说,alloca的内存是在调用alloca的函数func的栈上分配的,当func返回或者异常退出的时候,分配的内存或自动释放。以上说的是一般的情…

    2022年10月29日
  • stringutils.isnotblank()_String java

    stringutils.isnotblank()_String java今天在做SSM系统时候,为了进行查询特意使用StringUtils.isNotBlank(name)一定注意导入的包是:importorg.apache.commons.lang3.StringUtils;开始使用的是com.mysql.jdbc中的StringUtils.isNullOrEmpty,,,结果导致在我进行查询的时候各种错误,特地来此总结一番。StringUtils方法的

  • java通过jdbc连接sql server数据库_mysqljdbc连接数据库代码

    java通过jdbc连接sql server数据库_mysqljdbc连接数据库代码文章目录一、需求二、项目结构三、步骤1、创建数据库、数据表,插入数据2、创建javaweb项目3、下载驱动包4、导入驱动包5、创建包,创建类6、程序7、运行结果一、需求创建一个javaweb项目,读取bookinfo表中的数据,并输出到控制台二、项目结构JDBC.java用来写主程序mysql-connector-java-5.1.47.jar是java连接mysql需要导入的jar包…

  • 流式布局 简单_CSS3流式布局

    流式布局 简单_CSS3流式布局第三方库://依赖:compile’com.hyman:flowlayout-lib:1.1.2’布局文件&amp;amp;lt;com.zhy.view.flowlayout.TagFlowLayoutandroid:id=&amp;quot;@+id/id_flowlayout&amp;quot;zhy:max_select=&amp;quot;-1&amp;quot;android:layout

    2022年10月28日
  • IDEA导入jar包[通俗易懂]

    IDEA导入jar包[通俗易懂]一、导入1、java项目在没有导入该jar包之前,如图:2、点击File->ProjectStructure(快捷键Ctrl+Alt+Shift+s),点击ProjectStructure界面左侧的“Modules”如图:3、在“Dependencies”标签界面下,点击右边绿色的“+”号,选择第一个选项“JARsord…

  • matlab画时域和频谱图_信号的频域分析及matlab实现

    matlab画时域和频谱图_信号的频域分析及matlab实现随机振动信号分析方法总结信号处理(信号滤波、时频域分析、神经网络、寿命预测)一、时域分析时域分析特征包括均值、方差、峭度、峰峰值等;振动信号降噪结果分析:对于去噪效果好坏的评价,常用信号的信噪比(SNR)、估计信号同原信号的均方根误差(RMSE)来判断。SNR越高则说明混在信号里的噪声越小,否则相反。RMSE的计算值越小则表示去噪效果越好。信噪比定义:均方根误差定义:二、频域分析三、时频联合域分析(JointTime-FrequencyAnalysis,JTFA)即时频分析,

    2022年10月15日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号