[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能
前面作者講解了很多知識(shí)圖譜原理知識(shí),包括知識(shí)圖譜相關(guān)技術(shù)、Neo4j繪制關(guān)系圖譜等,但仍缺少一個(gè)系統(tǒng)全面的實(shí)例。為了加深自己對(duì)知識(shí)圖譜構(gòu)建的認(rèn)識(shí),為后續(xù)創(chuàng)建貴州旅游知識(shí)圖譜打下基礎(chǔ),作者深入學(xué)習(xí)了張宏倫老師的網(wǎng)易云課程(星球系列電影),并結(jié)合自己的理解和技術(shù)分享了該系列專欄,從數(shù)據(jù)采集、數(shù)據(jù)展示、數(shù)據(jù)分析到知識(shí)圖譜構(gòu)建,文章后續(xù)還會(huì)講解中文數(shù)據(jù)的實(shí)體識(shí)別、關(guān)系抽取、知識(shí)計(jì)算等。
前面通過(guò)六篇文章基本構(gòu)建了電影知識(shí)圖譜,并且能顯示選中節(jié)點(diǎn)相關(guān)聯(lián)的邊及屬性,如下圖所示:
本文主要增加了一個(gè)搜索功能,通過(guò)該搜索框能展示搜索節(jié)點(diǎn)的相關(guān)內(nèi)容,同時(shí)在張老師的基礎(chǔ)上增加搜索節(jié)點(diǎn)相關(guān)聯(lián)的邊及節(jié)點(diǎn)。如下圖所示:
代碼下載地址:https://download.csdn.net/download/eastmount/10958879
Github下載地址:https://github.com/eastmountyxz/Knowledge-Graph-Movie
這是一系列基礎(chǔ)性文章,希望對(duì)您有所幫助 ,尤其是對(duì)知識(shí)圖譜感興趣和編程剛?cè)腴T(mén)的同學(xué)。同時(shí)也因?yàn)樽罱鼫?zhǔn)備博士考試,做題做吐了,寫(xiě)點(diǎn)新專欄調(diào)節(jié)下心情,與君共勉,一起加油。
前文:
[知識(shí)圖譜實(shí)戰(zhàn)篇] 一.數(shù)據(jù)抓取之Python3抓取JSON格式的電影實(shí)體
[知識(shí)圖譜實(shí)戰(zhàn)篇] 二.Json+Seaborn可視化展示電影實(shí)體
[知識(shí)圖譜實(shí)戰(zhàn)篇] 三.Python提取JSON數(shù)據(jù)、HTML+D3構(gòu)建基本可視化布局
[知識(shí)圖譜實(shí)戰(zhàn)篇] 四.HTML+D3+CSS繪制關(guān)系圖譜
[知識(shí)圖譜實(shí)戰(zhàn)篇] 五.HTML+D3添加鼠標(biāo)響應(yīng)事件顯示相關(guān)節(jié)點(diǎn)及邊
[知識(shí)圖譜實(shí)戰(zhàn)篇] 六.HTML+D3實(shí)現(xiàn)點(diǎn)擊節(jié)點(diǎn)顯示相關(guān)屬性及屬性值
文章目錄
- 一.HTML增加搜索框
- 二.JS增加搜索響應(yīng)事件
- 三.優(yōu)化代碼-顯示相關(guān)聯(lián)節(jié)點(diǎn)及邊
- 四.完整代碼
推薦作者的知識(shí)圖譜前文:
知識(shí)圖譜相關(guān)會(huì)議之觀后感分享與學(xué)習(xí)總結(jié)
中文知識(shí)圖譜研討會(huì)的學(xué)習(xí)總結(jié) (上) 圖譜引入、百度知心、搜狗知立方
搜索引擎和知識(shí)圖譜那些事 (上).基礎(chǔ)篇
基于VSM的命名實(shí)體識(shí)別、歧義消解和指代消解
CSDN下載-第一屆全國(guó)中文知識(shí)圖譜研討會(huì)演講PPT 清華大學(xué)
CSDN下載-知識(shí)圖譜PDF資料 清華大學(xué)知識(shí)圖譜研討會(huì)匯報(bào)PPT
[知識(shí)圖譜構(gòu)建] 一.Neo4j圖數(shù)據(jù)庫(kù)安裝初識(shí)及藥材供應(yīng)圖譜實(shí)例
[知識(shí)圖譜構(gòu)建] 二.《Neo4j基礎(chǔ)入門(mén)》基礎(chǔ)學(xué)習(xí)之創(chuàng)建圖數(shù)據(jù)庫(kù)節(jié)點(diǎn)及關(guān)系
[關(guān)系圖譜] 一.Gephi通過(guò)共線矩陣構(gòu)建知網(wǎng)作者關(guān)系圖譜
[關(guān)系圖譜] 二.Gephi導(dǎo)入共線矩陣構(gòu)建作者關(guān)系圖譜
再次強(qiáng)烈推薦大家閱讀張宏倫老師的網(wǎng)易云課程及Github源碼,受益匪淺。
https://github.com/Honlan/starwar-visualization/tree/master/star_war
https://study.163.com/course/courseLearn.htm?courseId=1003528010
一.HTML增加搜索框
首先,利用HTML繪制一個(gè)搜索框。
<!-- 繪制搜索框 --> <div id="search"><input type="text" class="form-control"> </div>注意,class為form-control,它是bootstrap的基本樣式,所以需要在前面導(dǎo)入基本樣式代碼,如下:
<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>此時(shí),你會(huì)發(fā)現(xiàn)新增的搜索框已經(jīng)被置于底部,接著需要通過(guò)CSS設(shè)置其樣式。
CSS增加樣式代碼如下:絕對(duì)定位、位置、顏色、邊框去掉、outline去掉、陰影 去掉、跨度設(shè)置、背景顏色設(shè)置。
#search input {position: absolute;top: 220px;left: 60px;color: #fff;border: none;outline: none;box-shadow: none;width: 200px;background-color: #666; }此時(shí)就增加好了搜索框:
二.JS增加搜索響應(yīng)事件
當(dāng)搜索框設(shè)置完成之后,再設(shè)置其響應(yīng)事件。添加事件 $(’#search1 input’).keyup(function(event) {})
其基本功能表示:
- 當(dāng)輸入內(nèi)容則響應(yīng)該事件keyup
- 如果input值為空,即沒(méi)有輸入搜索內(nèi)容則顯示所有圓和邊
- 如果有搜索內(nèi)容,顯示搜索相關(guān)聯(lián)的節(jié)點(diǎn)
- 同時(shí)設(shè)置Texts、所有邊隱藏
此時(shí)的運(yùn)行效果如下圖所示,比如搜索 luke 則反饋該節(jié)點(diǎn),它是一個(gè)人物。
點(diǎn)擊“文字”的搜索也是如此,僅顯示單一節(jié)點(diǎn)。
三.優(yōu)化代碼-顯示相關(guān)聯(lián)節(jié)點(diǎn)及邊
但我們更期待的結(jié)果是反饋搜索節(jié)點(diǎn)及其相關(guān)聯(lián)的邊及節(jié)點(diǎn),下面作者結(jié)合之前的文章進(jìn)行優(yōu)化。此時(shí)原理很簡(jiǎn)單,增加一個(gè)循環(huán),判斷所有邊的起點(diǎn)(Source)或終點(diǎn)(Target)與該搜索節(jié)點(diǎn)相鄰,則顯示,否則設(shè)置其class屬性為’inactive’,即隱藏節(jié)點(diǎn)。
核心代碼如下:
<script> //搜索框中輸入內(nèi)容則響應(yīng)該事件 //keyup按鍵敲擊響應(yīng)event $('#search input').keyup(function(event) {//如果Input值是空的顯示所有的圓和線(沒(méi)有進(jìn)行篩選)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', '');}//否則判斷判斷三個(gè)元素是否等于name值,等于則顯示該值else {var name = $(this).val();//搜索所有的節(jié)點(diǎn)d3.select('#svg1 .nodes').selectAll('circle').attr('class', function(d) {//輸入節(jié)點(diǎn)id的小寫(xiě)等于name則顯示,否則隱藏if (d.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) {return '';} else {//優(yōu)化:與該搜索節(jié)點(diǎn)相關(guān)聯(lián)的節(jié)點(diǎn)均顯示//links鏈接的起始節(jié)點(diǎn)進(jìn)行判斷,如果其id等于name則顯示這類節(jié)點(diǎn)//注意: graph=datafor (var i = 0; i < graph.links.length; i++) {//如果links的起點(diǎn)等于name,并且終點(diǎn)等于正在處理的則顯示if ((graph.links[i]['source'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['target'].id == d.id)) {return '';}//如果links的終點(diǎn)等于name,并且起點(diǎn)等于正在處理的則顯示if ((graph.links[i]['target'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['source'].id == d.id)) {return '';}} return 'inactive'; //隱藏其他節(jié)點(diǎn) }});//搜索textsd3.select('#svg1 .texts').selectAll('text').attr('class', function(d) {if (d.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) {return '';} else {//優(yōu)化:與該搜索節(jié)點(diǎn)相關(guān)聯(lián)的節(jié)點(diǎn)均顯示//links鏈接的起始節(jié)點(diǎn)進(jìn)行判斷,如果其id等于name則顯示這類節(jié)點(diǎn)//注意: graph=datafor (var i = 0; i < graph.links.length; i++) {//如果links的起點(diǎn)等于name,并且終點(diǎn)等于正在處理的則顯示if ((graph.links[i]['source'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['target'].id == d.id)) {return '';}//如果links的終點(diǎn)等于name,并且起點(diǎn)等于正在處理的則顯示if ((graph.links[i]['target'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['source'].id == d.id)) {return '';}} return 'inactive'; //隱藏其他節(jié)點(diǎn)}});//搜索links 所有與搜索name相關(guān)聯(lián)的邊均顯示//顯示相的鄰邊 注意 || //name=$(this).val():名字為鍵盤(pán)輸入的內(nèi)容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>運(yùn)行結(jié)果如下圖所示,同時(shí)如果有多個(gè)名字相關(guān)的節(jié)點(diǎn),它們與其關(guān)聯(lián)的節(jié)點(diǎn)和邊均會(huì)顯示。
PS:但是也存在一個(gè)問(wèn)題,即右邊顯示的屬性為鼠標(biāo)選中顯示,而搜索通常不能顯示屬性,但這不會(huì)影響整體效果。
四.完整代碼
完整代碼如下所示:
<!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>知識(shí)圖譜</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><!-- 繪制標(biāo)題樣式 --><h1 style="color:#fff;font-size:32px;margin-bottom:0px;text-align:center;margin-left:40px;">Star Wars</h1><!-- 第一個(gè)布局 繪制知識(shí)圖譜主圖 --><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;">節(jié)點(diǎn)</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><!-- 繪制右邊顯示結(jié)果 --><div id="info"><h4></h4></div></div><!-- 第二個(gè)布局 下部分時(shí)間點(diǎn) 文本居中 相對(duì)定位--><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元素庫(kù) --> <script src="https://d3js.org/d3.v4.min.js"></script> <!-- 補(bǔ)充JS代碼 --> <script type="text/javascript">$(document).ready(function() {//定義svg變量將布局svg1選出來(lái) var svg = d3.select("#svg1"), width = svg.attr("width"), height = svg.attr("height");//定義name變量制作圖標(biāo)var names = ['Films', 'Characters', 'Planets', 'Starships', 'Vehicles', 'Species'];var colors = ['#6ca46c', '#4e88af', '#ca635f', '#d2907c', '#d6744d', '#ded295'];//背景顏色設(shè)置 補(bǔ)充CSS樣式設(shè)置字體布局for (var i=0; i < names.length; i++) {$('#indicator').append("<div><span style='background-color:" + colors[i] + "'></span>" + names[i] + "</div>");}//利用d3.forceSimulation()定義關(guān)系圖 包括設(shè)置邊link、排斥電荷charge、關(guān)系圖中心點(diǎn)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));//存儲(chǔ)關(guān)系圖的數(shù)據(jù)var graph;//定義d3.json請(qǐng)求python處理好的節(jié)點(diǎn)及邊 請(qǐng)求成功返回?cái)?shù)據(jù),否則報(bào)錯(cuò)d3.json("starwar_alldata.json", function(error, data) {if(error) throw error;graph = data;console.log(graph);//D3映射數(shù)據(jù)至HTML中//g用于繪制所有邊,selectALL選中所有的line,并綁定數(shù)據(jù)data(graph.links),enter().append("line")添加元素//數(shù)據(jù)驅(qū)動(dòng)文檔,設(shè)置邊的粗細(xì)//前面定義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});//添加所有的點(diǎn)//selectAll("circle")選中所有的圓并綁定數(shù)據(jù),圓的直徑為d.size//再定義圓的填充色,同樣數(shù)據(jù)驅(qū)動(dòng)樣式,圓沒(méi)有描邊,圓的名字為d.id//call()函數(shù):拖動(dòng)函數(shù),當(dāng)拖動(dòng)開(kāi)始綁定dragstarted函數(shù),拖動(dòng)進(jìn)行和拖動(dòng)結(jié)束也綁定函數(shù)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));//顯示所有的文本 //設(shè)置大小、填充顏色、名字、text()設(shè)置文本//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));//圓增加titlenode.append("title").text(function(d) {return d.id;})//simulation中ticked數(shù)據(jù)初始化,并生成圖形simulation.nodes(graph.nodes).on("tick", ticked);simulation.force("link").links(graph.links);//ticked()函數(shù)確定link線的起始點(diǎn)x、y坐標(biāo) node確定中心點(diǎn) 文本通過(guò)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數(shù)據(jù)需要放置服務(wù)器中請(qǐng)求 XAMPP//該變量保證拖動(dòng)鼠標(biāo)時(shí),不會(huì)影響圖形變換,默認(rèn)為false未選中鼠標(biāo)var dragging = false;//開(kāi)始拖動(dòng)并更新相應(yīng)的點(diǎn)function dragstarted(d) {if (!d3.event.active) simulation.alphaTarget(0.3).restart();d.fx = d.x;d.fy = d.y;dragging = true;}//拖動(dòng)進(jìn)行中function dragged(d) {d.fx = d3.event.x;d.fy = d3.event.y;}//拖動(dòng)結(jié)束function dragended(d) {if (!d3.event.active) simulation.alphaTarget(0);d.fx = null;d.fy = null;dragging = false;}//span點(diǎn)擊事件$('#mode span').click(function(event) {//span都設(shè)置為不激活狀態(tài)$('#mode span').removeClass('active');//點(diǎn)擊的span被激活$(this).addClass('active');//text隱藏 nodes顯示if ($(this).text() == '節(jié)點(diǎn)') {$('.texts text').hide();$('.nodes circle').show();} else {$('.texts text').show();$('.nodes circle').hide();}});//為svg1父元素下的.nodes circle元素綁定鼠標(biāo)進(jìn)入事件$('#svg1').on('mouseenter', '.nodes circle', function(event) {//通過(guò)變量dragging保證拖動(dòng)鼠標(biāo)時(shí),其狀態(tài)不受影響,從而改變圖形//鼠標(biāo)沒(méi)有拖動(dòng)才能處理事件if(!dragging) {//獲取被選中元素的名字var name = $(this).attr("name");//設(shè)置#info h4樣式的顏色為該節(jié)點(diǎn)的顏色,文本為該節(jié)點(diǎn)name//$(this).attr('fill')表示當(dāng)前懸浮圓的填充色$('#info h4').css('color', $(this).attr('fill')).text(name);//每次點(diǎn)擊添加屬性前把上次顯示的信息去除,否則會(huì)不斷疊加$('#info p').remove();//打印懸浮的節(jié)點(diǎn)信息//console.log(info[name]);//遍歷所有的for (var key in info[name]) {//類型復(fù)雜的不進(jìn)行顯示if (typeof(info[name][key]) == 'object') {continue;}//比較復(fù)雜的超鏈接字段不顯示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,再增加個(gè)classd3.select('#svg1 .nodes').selectAll('circle').attr('class', function(d) {//數(shù)據(jù)的id是否等于name,返回空if(d.id==name) {return '';} //當(dāng)前節(jié)點(diǎn)返回空,否則其他節(jié)點(diǎn)循環(huán)判斷是否被隱藏起來(lái)(CSS設(shè)置隱藏)else {//links鏈接的起始節(jié)點(diǎn)進(jìn)行判斷,如果其id等于name則顯示這類節(jié)點(diǎn)//注意: graph=datafor (var i = 0; i < graph.links.length; i++) {//如果links的起點(diǎn)等于name,并且終點(diǎn)等于正在處理的則顯示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';}});}});//鼠標(biāo)移開(kāi)還原原圖,顯示所有隱藏的點(diǎn)及邊$('#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', '');} });//鼠標(biāo)進(jìn)入文本顯示相鄰節(jié)點(diǎn)及邊$('#svg1').on('mouseenter', '.texts text', function(event) {if (!dragging) {var name = $(this).attr('name');//同樣的代碼從選中圓中賦值過(guò)來(lái)$('#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';}});}});//鼠標(biāo)移除文本還原相應(yīng)節(jié)點(diǎn)及邊$('#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', '');}});//搜索框中輸入內(nèi)容則響應(yīng)該事件//keyup按鍵敲擊響應(yīng)event$('#search input').keyup(function(event) {//如果Input值是空的顯示所有的圓和線(沒(méi)有進(jìn)行篩選)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', '');}//否則判斷判斷三個(gè)元素是否等于name值,等于則顯示該值else {var name = $(this).val();//搜索所有的節(jié)點(diǎn)d3.select('#svg1 .nodes').selectAll('circle').attr('class', function(d) {//輸入節(jié)點(diǎn)id的小寫(xiě)等于name則顯示,否則隱藏if (d.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) {return '';} else {//優(yōu)化:與該搜索節(jié)點(diǎn)相關(guān)聯(lián)的節(jié)點(diǎn)均顯示//links鏈接的起始節(jié)點(diǎn)進(jìn)行判斷,如果其id等于name則顯示這類節(jié)點(diǎn)//注意: graph=datafor (var i = 0; i < graph.links.length; i++) {//如果links的起點(diǎn)等于name,并且終點(diǎn)等于正在處理的則顯示if ((graph.links[i]['source'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['target'].id == d.id)) {return '';}//如果links的終點(diǎn)等于name,并且起點(diǎn)等于正在處理的則顯示if ((graph.links[i]['target'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['source'].id == d.id)) {return '';}} return 'inactive'; //隱藏其他節(jié)點(diǎn) }});//搜索textsd3.select('#svg1 .texts').selectAll('text').attr('class', function(d) {if (d.id.toLowerCase().indexOf(name.toLowerCase()) >= 0) {return '';} else {//優(yōu)化:與該搜索節(jié)點(diǎn)相關(guān)聯(lián)的節(jié)點(diǎn)均顯示//links鏈接的起始節(jié)點(diǎn)進(jìn)行判斷,如果其id等于name則顯示這類節(jié)點(diǎn)//注意: graph=datafor (var i = 0; i < graph.links.length; i++) {//如果links的起點(diǎn)等于name,并且終點(diǎn)等于正在處理的則顯示if ((graph.links[i]['source'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['target'].id == d.id)) {return '';}//如果links的終點(diǎn)等于name,并且起點(diǎn)等于正在處理的則顯示if ((graph.links[i]['target'].id.toLowerCase().indexOf(name.toLowerCase()) >= 0) && (graph.links[i]['source'].id == d.id)) {return '';}} return 'inactive'; //隱藏其他節(jié)點(diǎn)}});//搜索links 所有與搜索name相關(guān)聯(lián)的邊均顯示//顯示相的鄰邊 注意 || //name=$(this).val():名字為鍵盤(pán)輸入的內(nèi)容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信息:六類實(shí)體詳細(xì)屬性信息var info;//d3.json獲取數(shù)據(jù)d3.json("all_data.json", function(error, data) {if(error) throw error;info = data;});}); </script> </html>源碼下載地址:https://download.csdn.net/download/eastmount/10958879
希望這篇基礎(chǔ)性文章對(duì)你有所幫助,尤其是新手。
哎,英語(yǔ)真心太差了,博士也不一定能考上,但我至少奮斗過(guò),這個(gè)寒假每日每夜都忙碌著。同時(shí)也希望未來(lái)能有更多時(shí)間學(xué)習(xí)新知識(shí),分享新知識(shí)。未來(lái)的路誰(shuí)又知道,作為一名大學(xué)老師,希望自己能始終保持初心,教好自己的每一個(gè)學(xué)生;作為一名程序員,希望自己知道學(xué)無(wú)止境,寫(xiě)好自己的每一篇博文;作為一名主人公,希望自己能照顧好另一伴,愛(ài)她就像愛(ài)生命。我毫無(wú)閱歷,毫無(wú)準(zhǔn)備,我一頭栽進(jìn)我的命里,就像跌進(jìn)一個(gè)深坑,從那一秒鐘起,我的心里只有一個(gè),就是你。
(By:Eastmount 2019-02-14 下午4點(diǎn) http://blog.csdn.net/eastmount/)
總結(jié)
以上是生活随笔為你收集整理的[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [知识图谱实战篇] 六.HTML+D3实
- 下一篇: [知识图谱实战篇] 八.HTML+D3绘