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 }