如何突出显示所选节点在d3js? [英] how to highlight the selected node in d3js?

查看:195
本文介绍了如何突出显示所选节点在d3js?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想突出显示所选节点及其连接的节点,点击d3js中的任何节点,
,其他节点将消失或变得模糊。

 <%@ Page Language =C#AutoEventWireup =trueCodeBehind =WebForm1.aspx.csInherits =D3js_edges_connected_by_nodes_id.WebForm1%& 

<!DOCTYPE html>

< html xmlns =http://www.w3.org/1999/xhtml>
< head runat =server>
< script type =text / javascriptsrc =http://d3js.org/d3.v2.min.js>< / script>
< script type =text / javascriptsrc =https://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js>< / script>
< title>加权引用图< / title>
< style>
path.link {
fill:none;
stroke:#666;
stroke-width:1.5px;
}

circle {
fill:#ccc;
stroke:#333;
stroke-width:1.5px;
}

text {
font:10px sans-serif;
pointer-events:none;
}

text.shadow {
stroke:#fff;
stroke-width:3px;
stroke-opacity:.8;
}

body {
background-color:white;
margin:0px;
}

.graphContainer {
text-shadow:-1px -1px 0 white,1px -1px 0 white,-1px 1px 0 white,1px 1px 0 white;
}
< / style>
< script>
function load_graph(text){

var color = d3.scale.category20();
// try {
// var data = JSON.parse(text);
//} catch(e){
// window.alert(sometext:+ e);
//}

var data = {nodes:[{id:127230,name:优化查询评估算法,引用:26, group:10},{id:127254,name:Flow algorithms for parallel query optimization,citation:22,group:10},{id:127380,name 用于在两个处理器上查询优化问题的随机近似算法,引用:14,group:10},{id:127438,name:Optimization algorithms for simultaneous multidimensional queries in OLAP environments引用:12,group:10},{id:127063,name:数据库系统中的查询优化,citation:230,group:10},{id:127158 ,name:Query memory in a memory-resident domain relational calculus database system,citation:41,group:10},{id:129760,name: ,引用:10,组:10},{id:129872,引用:22,group:10},{id:129867,name:ADVISORS名称:Tellabs和THRIP通过Telkom罗得斯大学卓越中心,引用:10,组:10},{id:127412,名称:分散查询中的最优服务排序group:10},{id:130856,name:Web services上的查询,citation:10,group:10} id:130959,name:利用并行度加速关键字搜索在深度网络资源上,citation:10,group:10},{id:131199,name:列表可在ScienceDirect Future Generation Computer Systems,citation:10,group:10},{id:131211,name:Flow Algorithms for Parallel Query Optimization,citation:10, group:10},{id:127373,name:Multi-query Optimization for On-Line Analytical Processing,citation:14,group:10},{id:133379, name:结构化集合的子集的简明描述,引用:21,group:10}],links:[{source:127230,target:127063,name c1,value:10,value:10,grouo:1},{source:127230,target:127158, ,{source:127230,target:129760,name:c1,value:10,grouo:1},{source:127230,target:129867, :c1,value:10,grouo:1},{source:127230,target:129872,name:c1,value:10,grouo 1,source:127230,target:127063,name:c1,value:10,grouo:9} name:c1,value:10,grouo:9},{source:127230,target:129760,name:c1,value:10,grouo :9,{source:127230,target:129867,name:c1,value:10,grouo:9} 1297,name:c1,value:10,grouo:9},{source:127254,target:127412,name:c1 grouo:1},{source:127254,target:130856,name:c1,value:10,grouo:1},{source:127254,target :130959,name:c1,value:10,grouo:1},{source:127254,target:131199,name:c1,value 10,grouo:1},{source:127254,target:131211,name:c1,value:10,grouo:1},{source:127254, target:127412,name:c1,value:10,grouo:9},{source:127254,target:130856,name:c1 :10,grouo:9},{source:127254,target:130959,name:c1,value:10,grouo:9} 127254,target:131199,name:c1,value:10,grouo:9},{source:127254,target:131211,name:c1 value:10,grouo:9},{source:127438,target:127373,name:c1,value:10,grouo:1} :127438,target:133379,name:c1,value:10,grouo:1},{source:127438,target:127373,name:c1 ,value:10,grouo:9},{source:127438,target:133379,name:c1,value:10,grouo:9} ;

//用于存储两个节点之间的链接数。
// mLinkNum [data.links [i] .source +,+ data.links [i] .target] = data.links [i] .linkindex;
var mLinkNum = {};

//排序链接第一个
// sortLinks();

data.links.sort(function(a,b){
if(a.source> b.source){return 1;}
else if source< b.source){return -1;}
else {
if(a.target> b.target){return 1;}
if(a.target< b.target){return -1;}
else {return 0;}
}
})

//设置linkIndex和linkNumer可能的多个链接共享相同的源和目标节点
setLinkIndexAndNum();


var w = 1345,
h = 1000;

var force = d3.layout.force()
.size([w,h])
.linkDistance(100)

.on(tick,tick);

var svg = d3.select(。graphContainer)append(svg:svg)
.attr(width,w)
.attr高度,h);

var color = d3.scale.category10()
var edges = [];
data.links.forEach(function(e){
var sourceNode = data.nodes.filter(function(n){
return n.id === e.source;
})[0],
targetNode = data.nodes.filter(function(n){
return n.id === e.target;
})[0]

edges.push({
source:sourceNode,
target:targetNode,
name:e.name,
value:e.value,
linkindex:e.linkindex,
grouo:i.erouo
});
});

console.log(edges)
force
.nodes(data.nodes)
.links(edges)
.start();

var path = svg.append(svg:g)
.selectAll(line)
.data(edges)
。 append(svg:path)
.attr(class,link)
.style(stroke-width,function(d,i){
console.log (d.value)
return Math.sqrt(d.value);
})style('stroke',function(d){
return color(d.grouo);
});


var circle = svg.append(svg:g)
.selectAll(circle)
.data(force.nodes b $ b .enter()。append(svg:circle)
.attr(r,function(d){
return(Math.sqrt(d.citation));
})
.style(fill,function(d){
return color(d.group);
})
.call(force.drag);

var text = svg.append(svg:g)
.selectAll(g)
.data(force.nodes())
。 enter()。append(svg:g);
console.log('test');
//具有粗白色笔划的文本的副本,用于易读。
//text.append(\"svg:text)
//.attr(\"x,8)
//.attr(\"y,.31em)
//.attr(\"class,shadow)
//.text (function(d){
// return d.name;
//});

text.append(svg:text)
.attr(x,8)
.attr(y,.31em)
.text(function(d){
// return d.name;
});

//使用椭圆弧路径段来对方向性进行双重编码。
function tick(){
path.attr(d,function(d,i){
var dx = d.target.x - d.source.x,
dy = d.target.y-d.source.y,
dr = 30 * d.linkindex; // linknum如上定义
var output =M+ d.source.x + + d.source.y +A+ dr +,+ dr +0,01+ d.target.x +,+ d.target.y;
/ /console.log(d)
returnM+ d.source.x +,+ d.source.y +A+ dr +,+ dr +0 0,1 + d.target.x +,+ d.target.y;
});

//将工具提示添加到连接路径
path.append(svg:title)
.text(function(d,i){
return d .name;
});

circle.attr(transform,function(d){
returntranslate(+ d.x +,+ d.y +);
}

text.attr(transform,function(d){
returntranslate(+ d.x +,+ d.y +);
}
}

//按源排序链接,然后目标
function sortLinks1(){
data.links.sort(function(a,b){
if(a.source> b.source){
return 1;
} else if(a.source< b.source){
return -1;
} else {
if(a.target> b.target){
return 1;
}
if(a.target< b.target){
return -1;
} else {
return 0;
}
}
});
}



//任何具有重复源和目标的链接获得增量的'linknum'
function setLinkIndexAndNum1(){
(var i = 0; i if(i!= 0& $ amp
data.links [i] .source == data.links [ i-1] .source&&
data.links [i] .target == data.links [i-1] .target){
data.links [i] .linkindex = data .links [i-1] .linkindex + 1;
console.log(data.links [i] .linkindex)
} else {
data.links [i] .linkindex = 1;
console.log(data.links [i] .linkindex)
}
//保存两个节点之间的链接总数
if(mLinkNum [data.links [i ] .target +,+ data.links [i] .source]!== undefined){
mLinkNum [data.links [i] .target +,+ data.links [i] .source ] = data.links [i] .linkindex;
} else {
mLinkNum [data.links [i] .source +,+ data.links [i] .target] = data.links [i] .linkindex;
}
}
}

function setLinkIndexAndNum(){

for(var i = 0; i if(i!= 0&
data.links [i] .source == data.links [i-1] .source&&
data.links [i] .target == data.links [i-1] .target){
data.links [i] .linkindex = data.links [i-1] .linkindex + 1;
}
else {
data.links [i] .linkindex = 1;
};
};
}
}
< / script>
< / head>
< body>
< form id =form1runat =server>
< div>
< script src =// d3js.org/d3.v3.min.js\"> ;</script>
<% - < textarea runat =serverid =textareacols =80rows =20>< / textarea>
< asp:Label ID =Label1runat =serverText =Label>< / asp:Label> - %>
< / div>
< div id =graphContainerclass =graphContainer>< / div>
< / form>
< / body>
< / html>

有什么方法可以在d3js中使用这种功能吗?

解决方案

有几种方法可以做到。这是其中之一:

  circle.on(click,function(d){
var thisNode = d.id
var connected = data.links.filter(function(e){
return e.source === thisNode || e.target === thisNode
});
circle.attr(opacity,function(d){
return(connected.map(d => d.source).indexOf(d.id)> -1 || connected.map (opacity,function(d)),其中(d => d.target).indexOf(d.id)> -1)?1:0.1
} d){
return(d.source.id == thisNode || d.target.id == thisNode)?1:0.1
});

使用您的代码检查演示:



  var color = d3.scale.category20(); // try {// var data = JSON.parse(text); //} catch(e){ // window.alert(sometext:+ e); //} var data = {nodes:[{id:127230,name:Optimization of query evaluation algorithms,citation:26,group:10},{id:127254 ,name:用于并行查询优化的流算法,引用:22,group:10},{id:127380,name:用于两个处理器上的查询优化问题的随机逼近算法 ,citation:14,group:10},{id:127438,name:Optimization algorithms for simultaneous multidimensional queries in OLAP environments {id:127063,name:Query optimization in database systems,citation:230,group:10},{id:127158,name:驻地域关系演算数据库系统,引用:41,group:10},{id:129760,name:TQuel概述,引用:22,group },{id:129867,name:ADVISORS,citation:10,group:10},{id:129872,name:Tellabs and THRIP through the Telkom Center在罗得斯大学卓越,引用:10,组:10},{id:127412,名称:在服务分散查询中的最优服务排序 group:10},{id:130856,name:Queries over Web Services,citation:10,group:10},{id:130959,name:Exploiting并行化以加速关键字搜索对于深度域源,引用:10,group:10},{id:131199,name:Contents lists available at ScienceDirect Future Generation Computer Systems :10,group:10},{id:131211,name:Flow Algorithms for Parallel Query Optimization,citation:10,group:10},{id:127373 ,name:在线分析处理的多查询优化,引用:14,group:10},{id:133379,name: name:c1,value:10,grouo,name:group:21,group:10} :1},{source:127230,target:127158,name:c1,value:10,grouo:1},{source:127230,target 129760,name:c1,value:10,grouo:1},{source:127230,target:129867,name:c1 grouo:1},{source:127230,target:129872,name:c1,value:10,grouo:1},{source:127230,target :127063,name:c1,value:10,grouo:9},{source:127230,target:127158,name:c1,value 10,grouo:9},{source:127230,target:129760,name:c1,value:10,grouo:9} target:129867,name:c1,value:10,grouo:9},{source:127230,target:129872,name:c1 :10,grouo:9},{source:127254,target:127412,name:c1,value:10,grouo:1} 127254,target:130856,name:c1,value:10,grouo:1},{source:127254,target:130959,name:c1 value:10,grouo:1},{source:127254,target:131199,name:c1,value:10,grouo:1} :127254,target:131211,name:c1,value:10,grouo:1},{source:127254,target:127412,name:c1 ,值:10,grouo:9},{source:127254,target:130856,name:c1 source:127254,target:130959,name:c1,value:10,grouo:9},{source:127254,target:131199, name:c1,value:10,grouo:9}c1,value:10,grouo:9},{source:127254,target:131211, ,{source:127438,target:127373,name:c1,value:10,grouo:1},{source:127438,target:133379,name :c1,value:10,grouo:1},{source:127438,target:127373,name:c1,value:10,grouo 9},{source:127438,target:133379,name:c1,value:10,grouo:9} //用于存储两个节点之间的链接数。 // mLinkNum [data.links [i] .source +,+ data.links [i] .target] = data.links [i] .linkindex; var mLinkNum = {}; // sort links first // sortLinks(); data.links.sort(function(a,b){if(a.source> b.source){return 1;} else if(a.source< b.source){return -1;} else {if (a.target> b.target){return 1;} if(a.target< b.target){return -1;} else {return 0;}}})//设置linkIndex和linkNumer它可能有多个链接共享同一个源和目标节点setLinkIndexAndNum(); var w = 1345,h = 1000; var force = d3.layout.force().size([w,h]).linkDistance(100).charge(-800).on(tick,tick); var svg = d3.select(body)。append(svg:svg).attr(width,w).attr(height,h); var color = d3.scale.category10()var edges = []; data.links.forEach(function(e){var sourceNode = data.nodes.filter(function(n){return n.id === e.source;})[0],targetNode = data.nodes.filter函数(n){return n.id === e.target;})[0]; edges.push({source:sourceNode,target:targetNode,name:e.name,value:e.value,linkindex:e .linkindex,grouo:egrouo});}); force .nodes(data.nodes).links(edges).start(); var path = svg.append(svg:g).selectAll(line).data(edges).enter()。append(svg:path).attr(class,link)。 style('stroke',function(d){return color(d.grouo);}); style('stroke-width',function(d,i){return Math.sqrt(d.value);} var circle = svg.append(svg:g).selectAll(circle).data(force.nodes()).enter()。append(svg:circle).attr (d){return(Math.sqrt(d.citation));}).style(fill,function(d){return color(d.group);})。 var text = svg.append(svg:g).selectAll(g).data(force.nodes()).enter()。append(svg:g); //具有可读性的粗白色笔划的文本副本。 //text.append(\"svg:text)//.attr(\"x,8)//.attr(\"y,.31em)//.attr(\"class,shadow) //.text (function(d){// return d.name; //}); text.append(svg:text).attr(x,8).attr(y,.31em).text(function(d){// return d.name;}); circle.on(click,function(d){var thisNode = d.id var connected = data.links.filter(function(e){return e.source === thisNode || e.target === thisNode }; circle.attr(opacity,function(d){return(connected.map(d => d.source).indexOf(d.id)> -1 || connected.map ; d.target).indexOf(d.id)> -1)λ1:0.1}); path.attr(opacity,function(d){return(d.source.id == thisNode || d .target.id == thisNode)?1:0.1});})//使用椭圆弧路径段来对方向性进行双重编码。 function tick(){path.attr(d,function(d,i){var dx = d.target.x  -  d.source.x,dy = d.target.y  -  d.source.y,dr = 30 * d.linkindex; // linknum在上面定义var output =M+ d.source.x +,+ d.source.y +A+ dr +,+ dr + 0,1+ d.target.x +,+ d.target.y; //console.log(d)returnM+ d.source.x +,+ d.source.y + A+ dr +,+ dr +0 0,1+ d.target.x +,+ d.target.y; //将工具提示添加到连接路径path.append(svg:title).text(function(d,i){return d.name;}); circle.attr(transform,function(d){returntranslate(+ d.x +,+ d.y +);}); text.attr(transform,function(d){returntranslate(+ d.x +,+ d.y +);}); } //根据源排序链接,然后目标函数sortLinks1(){data.links.sort(function(a,b){if(a.source> b.source){return 1;} else if源 

  path.link {fill:none;中风:#666; stroke-width:1.5px; } circle {fill:#ccc;中风:#333; stroke-width:1.5px; } text {font:10px sans-serif; pointer-events:none; } text.shadow {stroke:#fff; stroke-width:3px;中风不透明度:.8; } body {background-color:white; margin:0px; }  

 < script src =https:// cdnjs .cloudflare.com / ajax / libs / d3 / 3.4.11 / d3.min.js>< / script>  


I want to highlight the selected node and its connected nodes on clicking any node in d3js, and the other nodes will disappear or gets dull.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="D3js_edges_connected_by_nodes_id.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <script type="text/javascript" src="http://d3js.org/d3.v2.min.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
    <title>Weighted Citation Graph</title>
    <style>
        path.link {
            fill: none;
            stroke: #666;
            stroke-width: 1.5px;
        }

        circle {
            fill: #ccc;
            stroke: #333;
            stroke-width: 1.5px;
        }

        text {
            font: 10px sans-serif;
            pointer-events: none;
        }

            text.shadow {
                stroke: #fff;
                stroke-width: 3px;
                stroke-opacity: .8;
            }

        body {
            background-color: white;
            margin: 0px;
        }

        .graphContainer {
            text-shadow: -1px -1px 0 white, 1px -1px 0 white, -1px 1px 0 white, 1px 1px 0 white;
        }
    </style>
    <script>
        function load_graph(text) {

            var color = d3.scale.category20();
            //try{
            //    var data = JSON.parse(text);
            //} catch (e) {
            //    window.alert("sometext: "+e);
            //}

            var data = { "nodes": [{ "id": 127230, "name": "Optimization of query evaluation algorithms", "citation": 26, "group": 10 }, { "id": 127254, "name": "Flow algorithms for parallel query optimization", "citation": 22, "group": 10 }, { "id": 127380, "name": "Randomized approximation algorithms for query optimization problems on two processors", "citation": 14, "group": 10 }, { "id": 127438, "name": "Optimization algorithms for simultaneous multidimensional queries in OLAP environments", "citation": 12, "group": 10 }, { "id": 127063, "name": "Query optimization in database systems", "citation": 230, "group": 10 }, { "id": 127158, "name": "Query optimization in a memory-resident domain relational calculus database system", "citation": 41, "group": 10 }, { "id": 129760, "name": "An Overview of TQuel", "citation": 22, "group": 10 }, { "id": 129867, "name": "ADVISORS", "citation": 10, "group": 10 }, { "id": 129872, "name": "Tellabs and THRIP through the Telkom Centre of Excellence at Rhodes University.", "citation": 10, "group": 10 }, { "id": 127412, "name": "Optimal service ordering in decentralized queries over web services", "citation": 13, "group": 10 }, { "id": 130856, "name": "Queries over Web Services", "citation": 10, "group": 10 }, { "id": 130959, "name": "Exploiting Parallelism to Accelerate Keyword Search On Deep-web Sources", "citation": 10, "group": 10 }, { "id": 131199, "name": "Contents lists available at ScienceDirect Future Generation Computer Systems", "citation": 10, "group": 10 }, { "id": 131211, "name": "Flow Algorithms for Parallel Query Optimization", "citation": 10, "group": 10 }, { "id": 127373, "name": "Multi-query Optimization for On-Line Analytical Processing", "citation": 14, "group": 10 }, { "id": 133379, "name": "Concise descriptions of subsets of structured sets", "citation": 21, "group": 10 }], "links": [{ "source": 127230, "target": 127063, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127230, "target": 127158, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127230, "target": 129760, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127230, "target": 129867, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127230, "target": 129872, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127230, "target": 127063, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127230, "target": 127158, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127230, "target": 129760, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127230, "target": 129867, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127230, "target": 129872, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127254, "target": 127412, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127254, "target": 130856, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127254, "target": 130959, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127254, "target": 131199, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127254, "target": 131211, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127254, "target": 127412, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127254, "target": 130856, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127254, "target": 130959, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127254, "target": 131199, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127254, "target": 131211, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127438, "target": 127373, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127438, "target": 133379, "name": "c1", "value": 10, "grouo": 1 }, { "source": 127438, "target": 127373, "name": "c1", "value": 10, "grouo": 9 }, { "source": 127438, "target": 133379, "name": "c1", "value": 10, "grouo": 9 }] };

            // used to store the number of links between two nodes. 
            // mLinkNum[data.links[i].source + "," + data.links[i].target] = data.links[i].linkindex;
            var mLinkNum = {};

            // sort links first
            // sortLinks();

            data.links.sort(function (a, b) {
                if (a.source > b.source) { return 1; }
                else if (a.source < b.source) { return -1; }
                else {
                    if (a.target > b.target) { return 1; }
                    if (a.target < b.target) { return -1; }
                    else { return 0; }
                }
            })

            // set up linkIndex and linkNumer, because it may possible multiple links share the same source and target node
            setLinkIndexAndNum();


            var w = 1345,
                h = 1000;

            var force = d3.layout.force()
            .size([w, h])
            .linkDistance(100)
            .charge(-800)
            .on("tick", tick);

            var svg = d3.select(".graphContainer").append("svg:svg")
            .attr("width", w)
            .attr("height", h);

            var color = d3.scale.category10()
            var edges = [];
            data.links.forEach(function (e) {
                var sourceNode = data.nodes.filter(function (n) {
                    return n.id === e.source;
                })[0],
                    targetNode = data.nodes.filter(function (n) {
                        return n.id === e.target;
                    })[0];

                edges.push({
                    source: sourceNode,
                    target: targetNode,
                    name: e.name,
                    value: e.value,
                    linkindex: e.linkindex,
                    grouo: e.grouo
                });
            });

            console.log(edges)
            force
              .nodes(data.nodes)
              .links(edges)
              .start();

            var path = svg.append("svg:g")
            .selectAll("line")
            .data(edges)
            .enter().append("svg:path")
            .attr("class", "link")
            .style("stroke-width", function (d, i) {
                console.log(d.value)
                return Math.sqrt(d.value);
            }).style('stroke', function (d) {
                return color(d.grouo);
            });


            var circle = svg.append("svg:g")
            .selectAll("circle")
            .data(force.nodes())
            .enter().append("svg:circle")
            .attr("r", function (d) {
                return (Math.sqrt(d.citation));
            })
            .style("fill", function (d) {
                return color(d.group);
            })
            .call(force.drag);

            var text = svg.append("svg:g")
            .selectAll("g")
            .data(force.nodes())
            .enter().append("svg:g");
            console.log('test');
            // A copy of the text with a thick white stroke for legibility.
            //text.append("svg:text")
              //.attr("x", 8)
              //.attr("y", ".31em")
              //.attr("class", "shadow")
              //.text(function (d) {
                  //return d.name;
              //});

            text.append("svg:text")
              .attr("x", 8)
              .attr("y", ".31em")
              .text(function (d) {
                 // return d.name;
              });

            // Use elliptical arc path segments to doubly-encode directionality.
            function tick() {
                path.attr("d", function (d, i) {
                    var dx = d.target.x - d.source.x,
                       dy = d.target.y - d.source.y,
                       dr = 30 * d.linkindex;  //linknum is defined above
                    var output = "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
                    //console.log(d)
                    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
                });

                // Add tooltip to the connection path
                path.append("svg:title")
                  .text(function (d, i) {
                      return d.name;
                  });

                circle.attr("transform", function (d) {
                    return "translate(" + d.x + "," + d.y + ")";
                });

                text.attr("transform", function (d) {
                    return "translate(" + d.x + "," + d.y + ")";
                });
            }

            // sort the links by source, then target
            function sortLinks1() {
                data.links.sort(function (a, b) {
                    if (a.source > b.source) {
                        return 1;
                    } else if (a.source < b.source) {
                        return -1;
                    } else {
                        if (a.target > b.target) {
                            return 1;
                        }
                        if (a.target < b.target) {
                            return -1;
                        } else {
                            return 0;
                        }
                    }
                });
            }



            //any links with duplicate source and target get an incremented 'linknum'
            function setLinkIndexAndNum1() {
                for (var i = 0; i < data.links.length; i++) {
                    if (i != 0 &&
                        data.links[i].source == data.links[i - 1].source &&
                        data.links[i].target == data.links[i - 1].target) {
                        data.links[i].linkindex = data.links[i - 1].linkindex + 1;
                        console.log(data.links[i].linkindex)
                    } else {
                        data.links[i].linkindex = 1;
                        console.log(data.links[i].linkindex)
                    }
                    // save the total number of links between two nodes
                    if (mLinkNum[data.links[i].target + "," + data.links[i].source] !== undefined) {
                        mLinkNum[data.links[i].target + "," + data.links[i].source] = data.links[i].linkindex;
                    } else {
                        mLinkNum[data.links[i].source + "," + data.links[i].target] = data.links[i].linkindex;
                    }
                }
            }

            function setLinkIndexAndNum() {

                for (var i = 0; i < data.links.length; i++) {
                    if (i != 0 &&
                        data.links[i].source == data.links[i - 1].source &&
                        data.links[i].target == data.links[i - 1].target) {
                        data.links[i].linkindex = data.links[i - 1].linkindex + 1;
                    }
                    else {
                        data.links[i].linkindex = 1;
                    };
                };
            }
        }
    </script>
</head>
<body>
     <form id="form1" runat="server">
    <div>
    <script src="//d3js.org/d3.v3.min.js"></script>
        <%--<textarea runat="server" id="textarea" cols="80" rows="20"></textarea>
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>--%>
    </div>
        <div id="graphContainer" class="graphContainer"></div>
    </form>
</body>
</html>

is there any way of applying this kind of functionality in d3js?

解决方案

There are several ways to make it. This is one of them:

circle.on("click", function(d) {
    var thisNode = d.id
    var connected = data.links.filter(function(e) {
        return e.source === thisNode || e.target === thisNode
    });
    circle.attr("opacity", function(d) {
        return (connected.map(d => d.source).indexOf(d.id) > -1 || connected.map(d => d.target).indexOf(d.id) > -1) ? 1 : 0.1
    });

    path.attr("opacity", function(d) {
        return (d.source.id == thisNode || d.target.id == thisNode) ? 1 : 0.1
    });

Check the demo with your code:

    var color = d3.scale.category20();
    //try{
    //    var data = JSON.parse(text);
    //} catch (e) {
    //    window.alert("sometext: "+e);
    //}

    var data = {
        "nodes": [{
            "id": 127230,
            "name": "Optimization of query evaluation algorithms",
            "citation": 26,
            "group": 10
        }, {
            "id": 127254,
            "name": "Flow algorithms for parallel query optimization",
            "citation": 22,
            "group": 10
        }, {
            "id": 127380,
            "name": "Randomized approximation algorithms for query optimization problems on two processors",
            "citation": 14,
            "group": 10
        }, {
            "id": 127438,
            "name": "Optimization algorithms for simultaneous multidimensional queries in OLAP environments",
            "citation": 12,
            "group": 10
        }, {
            "id": 127063,
            "name": "Query optimization in database systems",
            "citation": 230,
            "group": 10
        }, {
            "id": 127158,
            "name": "Query optimization in a memory-resident domain relational calculus database system",
            "citation": 41,
            "group": 10
        }, {
            "id": 129760,
            "name": "An Overview of TQuel",
            "citation": 22,
            "group": 10
        }, {
            "id": 129867,
            "name": "ADVISORS",
            "citation": 10,
            "group": 10
        }, {
            "id": 129872,
            "name": "Tellabs and THRIP through the Telkom Centre of Excellence at Rhodes University.",
            "citation": 10,
            "group": 10
        }, {
            "id": 127412,
            "name": "Optimal service ordering in decentralized queries over web services",
            "citation": 13,
            "group": 10
        }, {
            "id": 130856,
            "name": "Queries over Web Services",
            "citation": 10,
            "group": 10
        }, {
            "id": 130959,
            "name": "Exploiting Parallelism to Accelerate Keyword Search On Deep-web Sources",
            "citation": 10,
            "group": 10
        }, {
            "id": 131199,
            "name": "Contents lists available at ScienceDirect Future Generation Computer Systems",
            "citation": 10,
            "group": 10
        }, {
            "id": 131211,
            "name": "Flow Algorithms for Parallel Query Optimization",
            "citation": 10,
            "group": 10
        }, {
            "id": 127373,
            "name": "Multi-query Optimization for On-Line Analytical Processing",
            "citation": 14,
            "group": 10
        }, {
            "id": 133379,
            "name": "Concise descriptions of subsets of structured sets",
            "citation": 21,
            "group": 10
        }],
        "links": [{
            "source": 127230,
            "target": 127063,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127230,
            "target": 127158,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127230,
            "target": 129760,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127230,
            "target": 129867,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127230,
            "target": 129872,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127230,
            "target": 127063,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127230,
            "target": 127158,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127230,
            "target": 129760,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127230,
            "target": 129867,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127230,
            "target": 129872,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127254,
            "target": 127412,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127254,
            "target": 130856,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127254,
            "target": 130959,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127254,
            "target": 131199,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127254,
            "target": 131211,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127254,
            "target": 127412,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127254,
            "target": 130856,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127254,
            "target": 130959,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127254,
            "target": 131199,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127254,
            "target": 131211,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127438,
            "target": 127373,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127438,
            "target": 133379,
            "name": "c1",
            "value": 10,
            "grouo": 1
        }, {
            "source": 127438,
            "target": 127373,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }, {
            "source": 127438,
            "target": 133379,
            "name": "c1",
            "value": 10,
            "grouo": 9
        }]
    };

    // used to store the number of links between two nodes. 
    // mLinkNum[data.links[i].source + "," + data.links[i].target] = data.links[i].linkindex;
    var mLinkNum = {};

    // sort links first
    // sortLinks();

    data.links.sort(function(a, b) {
        if (a.source > b.source) {
            return 1;
        } else if (a.source < b.source) {
            return -1;
        } else {
            if (a.target > b.target) {
                return 1;
            }
            if (a.target < b.target) {
                return -1;
            } else {
                return 0;
            }
        }
    })

    // set up linkIndex and linkNumer, because it may possible multiple links share the same source and target node
    setLinkIndexAndNum();


    var w = 1345,
        h = 1000;

    var force = d3.layout.force()
        .size([w, h])
        .linkDistance(100)
        .charge(-800)
        .on("tick", tick);

    var svg = d3.select("body").append("svg:svg")
        .attr("width", w)
        .attr("height", h);

    var color = d3.scale.category10()
    var edges = [];
    data.links.forEach(function(e) {
        var sourceNode = data.nodes.filter(function(n) {
                return n.id === e.source;
            })[0],
            targetNode = data.nodes.filter(function(n) {
                return n.id === e.target;
            })[0];

        edges.push({
            source: sourceNode,
            target: targetNode,
            name: e.name,
            value: e.value,
            linkindex: e.linkindex,
            grouo: e.grouo
        });
    });

    force
        .nodes(data.nodes)
        .links(edges)
        .start();

    var path = svg.append("svg:g")
        .selectAll("line")
        .data(edges)
        .enter().append("svg:path")
        .attr("class", "link")
        .style("stroke-width", function(d, i) {
            return Math.sqrt(d.value);
        }).style('stroke', function(d) {
            return color(d.grouo);
        });


    var circle = svg.append("svg:g")
        .selectAll("circle")
        .data(force.nodes())
        .enter().append("svg:circle")
        .attr("r", function(d) {
            return (Math.sqrt(d.citation));
        })
        .style("fill", function(d) {
            return color(d.group);
        })
        .call(force.drag);

    var text = svg.append("svg:g")
        .selectAll("g")
        .data(force.nodes())
        .enter().append("svg:g");
    // A copy of the text with a thick white stroke for legibility.
    //text.append("svg:text")
    //.attr("x", 8)
    //.attr("y", ".31em")
    //.attr("class", "shadow")
    //.text(function (d) {
    //return d.name;
    //});

    text.append("svg:text")
        .attr("x", 8)
        .attr("y", ".31em")
        .text(function(d) {
            // return d.name;
        });

    circle.on("click", function(d) {
        var thisNode = d.id
        var connected = data.links.filter(function(e) {
            return e.source === thisNode || e.target === thisNode
        });
        circle.attr("opacity", function(d) {
            return (connected.map(d => d.source).indexOf(d.id) > -1 || connected.map(d => d.target).indexOf(d.id) > -1) ? 1 : 0.1
        });

        path.attr("opacity", function(d) {
            return (d.source.id == thisNode || d.target.id == thisNode) ? 1 : 0.1
        });

    })

    // Use elliptical arc path segments to doubly-encode directionality.
    function tick() {
        path.attr("d", function(d, i) {
            var dx = d.target.x - d.source.x,
                dy = d.target.y - d.source.y,
                dr = 30 * d.linkindex; //linknum is defined above
            var output = "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
            //console.log(d)
            return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
        });

        // Add tooltip to the connection path
        path.append("svg:title")
            .text(function(d, i) {
                return d.name;
            });

        circle.attr("transform", function(d) {
            return "translate(" + d.x + "," + d.y + ")";
        });

        text.attr("transform", function(d) {
            return "translate(" + d.x + "," + d.y + ")";
        });
    }

    // sort the links by source, then target
    function sortLinks1() {
        data.links.sort(function(a, b) {
            if (a.source > b.source) {
                return 1;
            } else if (a.source < b.source) {
                return -1;
            } else {
                if (a.target > b.target) {
                    return 1;
                }
                if (a.target < b.target) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
    }



    //any links with duplicate source and target get an incremented 'linknum'
    function setLinkIndexAndNum1() {
        for (var i = 0; i < data.links.length; i++) {
            if (i != 0 &&
                data.links[i].source == data.links[i - 1].source &&
                data.links[i].target == data.links[i - 1].target) {
                data.links[i].linkindex = data.links[i - 1].linkindex + 1;
                console.log(data.links[i].linkindex)
            } else {
                data.links[i].linkindex = 1;
            }
            // save the total number of links between two nodes
            if (mLinkNum[data.links[i].target + "," + data.links[i].source] !== undefined) {
                mLinkNum[data.links[i].target + "," + data.links[i].source] = data.links[i].linkindex;
            } else {
                mLinkNum[data.links[i].source + "," + data.links[i].target] = data.links[i].linkindex;
            }
        }
    }

    function setLinkIndexAndNum() {

        for (var i = 0; i < data.links.length; i++) {
            if (i != 0 &&
                data.links[i].source == data.links[i - 1].source &&
                data.links[i].target == data.links[i - 1].target) {
                data.links[i].linkindex = data.links[i - 1].linkindex + 1;
            } else {
                data.links[i].linkindex = 1;
            };
        };
    }

  path.link {
            fill: none;
            stroke: #666;
            stroke-width: 1.5px;
        }

        circle {
            fill: #ccc;
            stroke: #333;
            stroke-width: 1.5px;
        }

        text {
            font: 10px sans-serif;
            pointer-events: none;
        }

            text.shadow {
                stroke: #fff;
                stroke-width: 3px;
                stroke-opacity: .8;
            }

        body {
            background-color: white;
            margin: 0px;
        }

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

这篇关于如何突出显示所选节点在d3js?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆