1 var svg = d3.select("svg"), 2 width = +svg.attr("width"), 3 height = +svg.attr("height"); 4 5 var node, 6 r=12, 7 color = d3.scaleOrdinal() 8 .domain(["citing", "input", "cited"]) 9 .range([' #01d7c0', ' #8b90fe ', ' #a15eb2 ']), 10 yscale = d3.scaleOrdinal() 11 .domain(["citing", "input", "cited"]) 12 .range([0, 200, 400]), 13 toRemove; 14 15 var link; 16 17 var rect = svg.append("rect") 18 .attr("x", 0) 19 .attr("y", 0) 20 .attr("height", height) 21 .attr("width", width) 22 .style("fill", 'white') 23 .on('click', function(d) { 24 d3.selectAll(".circle").style("stroke", "none") 25 d3.selectAll(".link") 26 .style("stroke", "#999") 27 .attr('marker-end',marker('#999')) 28 document.getElementById('textbox').innerHTML = "Click node"; 29 }); 30 31 var simulation = d3.forceSimulation() 32 .force("link", d3.forceLink().id(function(d) {return d.doi;}).distance(100).strength(1)) 33 .force("collide", d3.forceCollide(50)) 34 .force("charge", d3.forceManyBody().strength(-30)) 35 .force("center", d3.forceCenter(width/2, height/2)) 36 .force("yscale", d3.forceY().strength(1).y(function(d) {return yscale(d.group)})); 37 38 /** 39 * create a new zoom behavior and apply it to svg 40 */ 41 var zoom = d3.zoom() 42 .on("zoom", zoom); 43 zoom(svg); 44 45 /** 46 * create group element 47 */ 48 var g = svg.append("g") 49 .attr("class", "everything") 50 51 //d3.json("data.json", function (error, graph) { 52 d3.json("json_text.json").then(function(graph){ 53 update(graph.links, graph.nodes); 54 }) 55 56 function update(links, nodes) { 57 link = g.append("g") 58 .selectAll(".link") 59 .data(links) 60 .enter() 61 .append("line") 62 .style("stroke-width", "1px") 63 .style("stroke", "#999") 64 .attr("class", "link") 65 .attr('marker-end',marker("#999")) 66 67 node = g.append("g") 68 .selectAll(".node") 69 .data(nodes) 70 .enter() 71 .append("g") 72 .attr("class", "node") 73 .call(d3.drag() 74 .on("start", dragstarted) 75 .on("drag", dragged) 76 ) 77 .attr("initial_x", function(d) {return d.dx;}) 78 .attr("initial_y", function(d) {return d.dy;}); 79 80 node.append("circle") 81 .attr("r", r) 82 .attr("class", "circle") 83 .style("fill", function(d){ return color(d.group)}) 84 .on('click', function (d) { 85 if(toRemove){ 86 d3.select(toRemove).selectAll(".circle").style("stroke","none") 87 } 88 toRemove = this.parentNode; 89 d3.select(this).style("stroke","black") 90 marklink(d) 91 textfunc(d) 92 }); 93 94 node.append("text") 95 .attr("class", "text") //über selectAll(".text") können objs mit der klasse ausgewählt werden 96 .style("font-size", "15px") 97 .text(function (d) {return firstauthor(d.author);}) 98 .style('pointer-events', 'auto') 99 .on('click', function(d) { 100 if(toRemove){ 101 d3.select(toRemove).selectAll(".circle").style("stroke","none"); 102 } 103 toRemove = this.parentNode; 104 d3.select(this.parentNode).selectAll(".circle").style("stroke","black") 105 106 marklink(d) 107 textfunc(d); 108 }); 109 110 simulation 111 .nodes(nodes) 112 .on("tick", ticked); 113 114 simulation.force("link") 115 .links(links); 116 } 117 118 function isLinkForNode(node, link){ 119 return link.source.index == node.index || link.target.index == node.index; 120 } 121 122 function marklink(node){ 123 d3.selectAll(".link") 124 .style("stroke", function(o) { 125 return isLinkForNode(node, o) ? "black" : "#999";}) 126 .attr('marker-end', function(o) { 127 return isLinkForNode(node, o) ? marker('#000000') : marker('#999');}) 128 } 129 130 function marker(color) { 131 svg.append('defs').append('marker')//arrowhead 132 .attr('id',color.replace("#", "")) 133 .attr('viewBox','-0 -5 10 10') 134 .attr('refX',r+10) 135 .attr('refY',0) 136 .attr('orient','auto') 137 .attr('markerWidth',10) 138 .attr('markerHeight',15) 139 .attr('xoverflow','visible') 140 .append('svg:path') 141 .attr('d', 'M 0,-5 L 10 ,0 L 0,5') 142 .attr('fill', color)//arrowhead color 143 .style('stroke','none'); 144 return "url(" + color + ")"; 145 }; 146 147 /** 148 * returns last name of first author 149 * @param {string} authors - The comma-separated string of authors 150 */ 151 function firstauthor(authors){ 152 if (/,/.test(authors)==false){ 153 var firstauthor=/^.*\s+([\w\-]+)[\.\s]*$/.exec(authors) 154 } 155 else{ 156 var firstauthor=/^[\s\w\.\-]*\s([\w\-]+)[\.\s]*,.*$/.exec(authors) 157 } 158 return firstauthor[1] 159 } 160 161 function textfunc(d){ 162 document.getElementById('textbox').innerHTML = "Title:" + '</br>' + d.name + 163 '</br>' +'</br>'+"Author:"+ '</br>' +d.author+'</br>'+'</br>'+"Year:"+'</br>'+d.year+'</br>'+'</br>' 164 +"doi:"+'</br>'+d.doi; 165 } 166 167 function ticked() { 168 link.attr("x1", function (d) {return d.source.x;}) 169 .attr("y1", function (d) {return d.source.y;}) 170 .attr("x2", function (d) {return d.target.x;}) 171 .attr("y2", function (d) {return d.target.y;}); 172 node.attr("transform", function (d) {return "translate(" + d.x + ", " + d.y + ")";}); 173 } 174 175 function dragstarted(d) { 176 if (!d3.event.active) 177 simulation.alphaTarget(0.3).restart() 178 d.fx = d.x; 179 d.fy = d.y; 180 } 181 182 function dragged(d) { 183 d.fx = d3.event.x; 184 d.fy = d3.event.y; 185 } 186 187 function resetGraph(){ 188 d3.selectAll(".node").each(function(d) { 189 d.fx = d.initial_x; 190 d.fy = d.initial_y; 191 }) 192 } 193 194 function zoom(){ 195 d3.select('g').attr("transform", d3.event.transform) 196 } 197 198 /** 199 * sets the 200 */ 201 function resetZoom() { 202 d3.select('svg') 203 .call(zoom.scaleTo, 1); 204 } 205 206 /** 207 * sets the transform such that svg is centered 208 */ 209 function center() { 210 d3.select('svg') 211 .call(zoom.translateTo, 0.5 * width, 0.5 * height); 212 }