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