Skip to content
Snippets Groups Projects
Select Git revision
  • 337b293bd33fdebb32a685b575f712502f3bba95
  • master default protected
  • csv_export
  • ndex
  • v1.1.18-rc2
  • v1.1.17
  • v1.1.16
  • v1.1.16-rc12
  • v1.1.16-rc11
  • v1.1.16-rc10
  • v1.1.16-rc9
  • v1.1.16-rc8
  • v1.1.16-rc7
  • v1.1.16-rc4
  • v1.1.16-rc3
  • v1.1.16-rc1
  • v1.1.6-rc1
  • v1.1.15
  • v1.1.15-rc7
  • v1.1.15-rc6
  • v1.1.15-rc3
  • v1.1.15-rc1
  • v1.1.14
  • v1.1.13
24 results

about-page.component.html

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    cn2.js 16.39 KiB
    /**
    * creates a new zoom behavior
    */
    var zoom = d3.zoom().on("zoom", handle_zoom);
    
    /**
    * creates svg object and associated attributes
    * applies the zoom behavior to svg
    */
    var svg = d3.select("svg.graph")
        .call(zoom),
    width = svg.attr("width"),
    height = svg.attr("height"),
    perc;
    
    /**
    * scale functions that return y coordinate/color of node depending on group
    */
    var color = d3.scaleOrdinal()
        .domain(["Citedby", "Input", "Reference"])
        .range(['#01d7c0', '#8b90fe', '#a15eb2']),
    y_scale = d3.scaleOrdinal()
        .domain(["Citedby", "Input", "Reference"])
        .range([0, 200, 400]),
    to_remove;
    
    /**
    * creates node object and (default) radius
    */
    var node,
    r = 10;
    
    /**
    * creates link object
    */
    var link;
    
    /**
    * creates a background with a click functionality
    */
    var rect = svg.append("rect")
        .attr("x", 0)
        .attr("y", 0)
        .attr("height", height)
        .attr("width", width)
        .style("fill", 'white')
        .on('click', click_rect);
    
    /**
    * creates svg object (legend) and associated attributes
    * transform
    */
    var svg_legend = d3.select("svg.legendsvg"),
    legend_position = [65,95,125],
    arrow_legend_position = [0,25],
    arrow_group_names = ["Citation","Self-Citation"],
    group_names = ["Cited By","Input","Reference"],
    line_type = d3.scaleOrdinal()
        .domain(["line","dotted"])
        .range([("8,0"),("8,8")]),
    text_info = '',
    text_abstract = '';
        
    var legend = svg_legend.selectAll(".legend")
        .data(legend_position)
        .enter()
        .append("g")
        .attr("class","legend")
        .attr("transform", function(d,i) {return "translate(0," + d  + ")"; });
        
    legend.append("text")
        .attr("x", 80)
        .attr("y", 0)
        .attr("dy", ".35em")
        .style("text-anchor", "start")
        .text(function(d,i) {return group_names[i]});
        
    legend.append("circle")
        .attr("r", r)
        .attr("cx",30-r)
        .style("fill", color);
            
    var legend_arrow = svg_legend.selectAll(".legendarr")
        .data(arrow_legend_position)
        .enter()
        .append("g")
        .attr("class","legendarr")
        .attr("transform", function(d) { return "translate(0," + d  + ")"; });
        
    legend_arrow.append("line")
        .attr("x1", 10)
        .attr("x2", 50)
        .attr("y1", 10)
        .attr("y2", 10)
        .style("stroke-dasharray",line_type)
        .style("stroke", '#999')
        .style("stroke-width", "1px")
        .style('pointer-events', 'none')
        .attr('marker-end',update_marker('#999',this));
    
    legend_arrow.append("text")
        .attr("x", 80)
        .attr("y", 10)
        .attr("dy", ".35em")
        .style("text-anchor", "start")
        .text(function(d,i){return arrow_group_names[i]});
    
    /**
    * creates a new simulation
    * updates the positions of the links and nodes when the 
      state of the layout has changed (simulation has advanced by a tick)
    */
    
    var simulation = d3.forceSimulation()
        .force("link", d3.forceLink().id(function(d) {return d.doi;}).distance(50).strength(function(d) {
                if (d.group == "Input") {return 0;}
                else {return 5;}
            }))
            .force("collide", d3.forceCollide(function(d) {
                if (d.group == "Input") {return 70;}
                else {return 75;}
            }).strength(1))
        .force("charge", d3.forceManyBody().strength(0.001))
        .force("center", d3.forceCenter(width/2, height/2+20))
        .alpha(0.004)
        .on("end",  zoom_to);
    
    /**
    * creates group element
    */
    var g = svg.append("g")
        .attr("class", "everything")
    
    /**
    * creates xAxis element
    */
    var xAxis = d3.axisBottom()
        .tickFormat(function(d) {if (d%1==0) return d;})
        .ticks(10);
    
    /**
    * draw xAxis
    */
    var gX = svg.append("g")
            .attr("class", "axis axis--x")
            .attr("transform", "translate(0,25)")
        gX.append("text")
            .attr("y", -5)
            .attr("x", 85)
            .attr("text-anchor", "end")
            .style('fill', 'black')
            .text("Year")
            .style("font-size", "15px");
    
    /**
    * loads JSON data and calls the update function
    */
    d3.json("json_text.json").then(success,failure)
    function success(graph){
        update(graph.links, graph.nodes);
    }
    function failure(graph){
        localStorage.setItem("oldjson","irgendwaswasimmergespeichertwirdwennkeinejsondaist")
    }
    
    var intervalId=window.setInterval(function(){
        d3.json("json_text.json").then(function(graph) {
            newjson_string=JSON.stringify(graph) 
            var newjson = CryptoJS.MD5(newjson_string).toString();
            oldjson=localStorage.getItem("oldjson")
            if(newjson !== oldjson){
                localStorage.setItem("oldjson", newjson);
                window.location.reload()
            }
        })
    },5000);
    
    /**
    * calls update functions for links and nodes
    * adds the nodes, links and tick functionality to the simulation
    * @param {object} nodes - nodes
    * @param {object} links - links
    */
    function update(links, nodes) {
        updateXAxis(nodes);
        update_links(links);
        update_nodes(nodes);
        
        simulation
            .nodes(nodes)
            .on("tick", handle_tick);
        simulation.force("link")
            .links(links);
        
        link.attr('marker-end', function(d) {return update_marker("#999", d.target);})
            .style("stroke-dasharray",function(d){return self_citation(d.source,d.target)? ("8,8"): ("1,0")});
    }
    
    /**
    * initializes and shows xAxis
    * @param {object} nodes - nodes
    */
    function updateXAxis(nodes) {
        years = [];
        for (i = 0; i < nodes.length; i++) {
            years.push(parseInt((nodes[i]["year"]).split(" ")[2]));
        }
    
        xscale = d3.scaleLinear()
            .domain([d3.min(years)-1, d3.max(years)+1])
            .range([1, width-1])
    
        xAxis.scale(xscale);
        gX.call(xAxis);
    }
    
    /**
    * initializes and shows links (edges)
    * @param {object} links - links
    */
    function update_links(links) {
        link = g.append("g")
            .selectAll(".link")
            .data(links)
            .enter()
            .append("line")
            .style("stroke-width", "1px")
            .style("stroke", "#999")
            .attr("class", "link");
    }
    
    /**
    * initializes and shows nodes with circles, texts and a click functionality
    * creates a new drag behavior and applies it to the circles
    * @param {object} nodes - nodes
    */
    function update_nodes(nodes) {
        node = g.selectAll(".node")
            .data(nodes)
            .enter()
            .append("g")
            .attr("class", "node")
            .call(d3.drag()
                .on("start", start_drag)
                .on("drag", dragged)
            );
    
        node.append("circle")
            .attr("class", "circle")
            .attr("r", function(d) {return 1.5*r+d.citations*0.05})
            .style("fill", function(d){ return color(d.group)})
            .on('click', click_node);
    
        node.append("text")
            .attr("class", "text") 
            .style("font-size", "15px")
            .style('pointer-events', 'auto')
            .text(function (d) {const first_author=d.author[0].split(" ")
            return first_author[first_author.length-1];})
            .on('click', click_node);
    }
    
    /**
    * creates arrowhead and returns its url
    * @param {string} color - color of arrowhead
    * @param {string} target - target node
    */
    function update_marker(color, target) {
        var radius = 1.5*r+target.citations*0.05;
        svg.append('defs').append('marker')
            .attr('id',color.replace("#", "")+radius)
            .attr('viewBox','-0 -5 10 10')
            .attr('refX',radius+9.5)
            .attr('refY',0)
            .attr('orient','auto')
            .attr('markerWidth',10)
            .attr('markerHeight',15)
            .attr('xoverflow','visible')
            .append('svg:path')
            .attr('d', 'M 0,-5 L 10 ,0 L 0,5')
            .attr('fill', color)
            .style('stroke','none');
        return "url(" + color + radius + ")";
    };
    
    /**
    * sets color of circle and its links to black and removes the previous highlights
    * displays overview info of node in textbox
    * @param {object} node - node
    */
    function click_node(node) {
    
        d3.select(this.parentNode).raise();
        fix_nodes(node);
        if(to_remove){
            d3.select(to_remove).selectAll(".circle").style("stroke","none")
        }
        to_remove = this.parentNode;
        d3.select(this.parentNode).selectAll(".circle").style("stroke","black")
        mark_link(node)
        textbox_content(node)
        reset_button_highlight()
        highlight_button("overview")
    }
    
    /**
    * removes the highlights of the circles and their links
    */
    function click_rect() {
        fix_nodes(node);
        d3.selectAll(".circle").style("stroke", "none")
        d3.selectAll(".link")
            .style("stroke", "#999")
            .attr('marker-end', function(d) {return update_marker('#999', d.target);})
        text_abstract='';
        text_info='';
        reset_button_highlight()
        document.getElementById('textbox').innerHTML = "Click node";
    }
    
    /**
    * returns true if journals have a common author (self-citation)
    * @param {object} source - node
    * @param {object} target - node
    */
    function self_citation(source,target) {
        return source.author.some(item=>target.author.includes(item))
    }
    
    /**
    * sets color of link (line and arrowhead) to black if it is directly connected to node
    * and to grey otherwise
    * @param {object} node - node
    */
    function mark_link(node) {
        d3.selectAll(".link")
            .style("stroke", function(o) {
                return is_link_for_node(node, o) ? "black" : "#DEDEDE";})
            .attr('marker-end', function(o) {
                return is_link_for_node(node, o) ? update_marker('#000000', o.target) : update_marker("#DEDEDE", o.target);})
    }
    
    /**
    * returns true if link is directly connected to node and false if it is not
    * @param {object} node - node
    * @param {object} link - link
    */
    function is_link_for_node(node, link) {
        return link.source.index == node.index || link.target.index == node.index;
    }
    
    
    
    /**
    * saves text for overview and abstract of node
    * outputs node info to textbox
    * @param {object} node - node
    */
    
    
    function textbox_content(node) {
        authors = node.author[0]
        for (i = 1; i < node.author.length; i++) {
            authors += (", "+node.author[i])
        }
        text_info = "Title:" + '</br>' + node.name +
        '</br>' +'</br>'+"Author:"+ '</br>' +authors+'</br>'+'</br>'+"Date:"+'</br>'
        +node.year+'</br>'+'</br>'+"Journal:"+'</br>'+node.journal+'</br>'+'</br>'+"DOI:"
        +'</br>'+'<a href="'+node.doi+ '">'+node.doi+'</a>'+'</br>'+'</br>'+"Citations:"
        +'</br>'+node.citations;
        text_abstract = node.abstract;
        document.getElementById('textbox').innerHTML = text_info;
    }
    
    /**
    * sets color of btn to dark gray
    * @param {object} btn - button
    */
    function highlight_button(btn) {
        reset_button_highlight();
        document.getElementById(btn).style.background = "#CACACA";
    }
    
    /**
    * sets color of all buttons to default light gray
    */
    function reset_button_highlight() {
        document.getElementById("overview").style.background = '';
        document.getElementById("abstract").style.background = '';
    }
    
    /**
    * displays abstract in textbox if a is true, overview text otherwise
    * @param {bool} a- bool
    */
    function display_abstract(a) {
        if (text_abstract == '' && text_info == '') {
            document.getElementById('textbox').innerHTML="Click node";
        }
        else {
            if (a == true) {
                document.getElementById('textbox').innerHTML = text_abstract;
            }
            else {
                document.getElementById('textbox').innerHTML = text_info;
            }
        }   
    }
    
    /**
    * updates the positions of the links and nodes
    */
    function handle_tick() {
        link.attr("x1", function (d) {return xscale(parseInt((d.source.year).split(" ")[2]));})
            .attr("y1", function (d) {return d.source.y;})
            .attr("x2", function (d) {return xscale(parseInt((d.target.year).split(" ")[2]));})
            .attr("y2", function (d) {return d.target.y;});
        node.attr("transform", function (d) {return "translate(" + xscale(parseInt((d.year).split(" ")[2])) + ", " + d.y + ")";});
    }
    
    /**
    * initializes the dragging of the node
    * @param {object} node - node
    */
    function start_drag(node) {
        d3.select(this).raise();
        if (!d3.event.active) 
            simulation.alphaTarget(0.3).restart()
        //node.fx = node.x;
        node.fy = node.y;
        fix_nodes(node);
    }
    
    /**
    * applies the dragging to the node
    * @param {object} node - node
    */
    function dragged(node) {
        //node.fx = d3.event.x;
        node.fy = d3.event.y;
        fix_nodes(node);
    }
    
    /**
    * fix positions of all nodes except for the current node
    * @param {object} this_node - node
    */
    function fix_nodes(this_node) {
        node.each(function(d) {
          if (this_node != d) {
            d.fx = d.x;
            d.fy = d.y;
          }
        });
    }
    
    /**
    * applies the transformation (zooming or dragging) to the g element
    */
    function handle_zoom() {
        d3.select('g').attr("transform", d3.event.transform);
        var new_xScale = d3.event.transform.rescaleX(xscale)
        gX.call(xAxis.scale(new_xScale));
    }
    
    /**
    * transforms svg so that the zoom is adapted to the size of the graph
    */
    function zoom_to() {
        node_bounds = d3.selectAll("svg.graph").node().getBBox();
        svg_bounds = d3.select("rect").node().getBBox();
    
        perc_x = width/(node_bounds.width+100);
        perc_y = height/(node_bounds.height+100);
        perc = d3.min([perc_x, perc_y])
        
        d3.select('svg')
    		.call(zoom.scaleBy, perc);
    }
    
    /**
    * transforms svg so that the zoom and drag is reset
    */
    function reset_view() {
        d3.select('svg')
            .call(zoom.scaleTo, 1)
        d3.select('svg')
            .call(zoom.translateTo, 0.5 * width, 0.5 * height);
        d3.select('svg')
    		.call(zoom.scaleBy, perc);
    }
    
    /**
    * save svg as png
    */
    function save_svg(){
    	var svgString = get_svg_string(svg.node());
    	svg_string_to_image(svgString, 2*width, 2*height, 'png', save); // passes Blob and filesize String to the callback
    
    	function save( dataBlob, filesize ){
    		saveAs(dataBlob, 'D3 vis exported to PNG.png'); // FileSaver.js function
    	}
    };
    
    /**
    * generate svgString
    * @param {object} svgNode - node
    */
    function get_svg_string(svgNode) {
    	svgNode.setAttribute('xlink', 'http://www.w3.org/1999/xlink');
    	var cssStyleText = get_css_styles(svgNode);
    	append_css(cssStyleText, svgNode);
    
    	var serializer = new XMLSerializer();
    	var svgString = serializer.serializeToString(svgNode);
    	svgString = svgString.replace(/(\w+)?:?xlink=/g, 'xmlns:xlink='); // Fix root xlink without namespace
    	svgString = svgString.replace(/NS\d+:href/g, 'xlink:href'); // Safari NS namespace fix
    
    	return svgString;
    
    	function get_css_styles(parentElement) {
    		var selectorTextArr = [];
    
    		// Add Parent element Id and Classes to the list
    		selectorTextArr.push('#' + parentElement.id);
    		for (var c = 0; c < parentElement.classList.length; c++)
    				if (!contains('.'+parentElement.classList[c], selectorTextArr))
    					selectorTextArr.push('.'+parentElement.classList[c]);
    
    		// Add Children element Ids and Classes to the list
    		var nodes = parentElement.getElementsByTagName("*");
    		for (var i = 0; i < nodes.length; i++) {
    			var id = nodes[i].id;
    			if (!contains('#'+id, selectorTextArr))
    				selectorTextArr.push('#' + id);
    
    			var classes = nodes[i].classList;
    			for (var c = 0; c < classes.length; c++)
    				if (!contains('.'+classes[c], selectorTextArr))
    					selectorTextArr.push('.'+classes[c]);
    		}
    
    		// Extract CSS Rules
    		var extractedCSSText = "";
    		for (var i = 0; i < document.styleSheets.length; i++) {
    			var s = document.styleSheets[i];
    			
    			try {
    			    if(!s.cssRules) continue;
    			} catch(e) {
    		    		if(e.name !== 'SecurityError') throw e; // for Firefox
    		    		continue;
    		    	}
    
    			var cssRules = s.cssRules;
    			for (var r = 0; r < cssRules.length; r++) {
    				if (contains(cssRules[r].selectorText, selectorTextArr))
    					extractedCSSText += cssRules[r].cssText;
    			}
    		}
    		
    
    		return extractedCSSText;
    
    		function contains(str,arr) {
    			return arr.indexOf(str) === -1 ? false : true;
    		}
    
    	}
    
    	function append_css(cssText, element) {
    		var styleElement = document.createElement("style");
    		styleElement.setAttribute("type","text/css"); 
    		styleElement.innerHTML = cssText;
    		var refNode = element.hasChildNodes() ? element.children[0] : null;
    		element.insertBefore(styleElement, refNode);
    	}
    }
    
    /**
    * convert svgString to image and export it
    * @param {object} svgString - svgString
    * @param {object} width - width of image
    * @param {object} height - height of image
    * @param {object} format - format to save image in 
    * @param {object} callback - callback function 
    */
    function svg_string_to_image( svgString, width, height, format, callback ) {
    	var format = format ? format : 'png';
    
    	var imgsrc = 'data:image/svg+xml;base64,'+ btoa(unescape(encodeURIComponent(svgString))); // Convert SVG string to data URL
    
    	var canvas = document.createElement("canvas");
    	var context = canvas.getContext("2d");
    
    	canvas.width = width;
    	canvas.height = height;
    
    	var image = new Image();
    	image.onload = function() {
    		context.clearRect(0, 0, width, height);
    		context.drawImage(image, 0, 0, width, height);
    
    		canvas.toBlob(function(blob) {
    			var filesize = Math.round(blob.length/1024) + ' KB';
    			if (callback) callback(blob, filesize);
    		});
    		
    	};
    
    	image.src = imgsrc;
    }