<head>
    <script src="https://d3js.org/d3.v4.min.js"></script>
  <script src="d3.legend.js"></script>
    <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
    <script src="index.js"></script>
    <link href="https://fonts.googleapis.com/css?family=Josefin+Sans" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="index.css">
    </head>
    <body>
    <div id="content">
    <h1>
    Who's panelling at the Animal Rights National Conference?
    </h1>
    <svg id="network"></svg>
    
    </div>
    </body>
body {
  font-family: 'Josefin Sans', cursive;
}

#content {
  position: absolute;
  width: 800px;
  padding: 25px;
  margin-left: auto;
  margin-right: auto;
  left: 0;
  right: 0;
  background-color: rgba(249, 249, 249, 0.863);
  border-left: 5px solid #000000;
  border-right: 5px solid #000000;
}

h1 {
  text-align: center;
  font-size: 42px;
}

#network {
  position: relative;
  width: 800px;
  height: 600px;
  padding: 15px;
  margin: 0 auto;
}

.tooltip {
  position: absolute;
  text-align: left;
  width: 120px;
  padding: 8px;
  margin-top: -20px;
  border:2px solid #000000;
  font: 12px sans-serif;
  background: #FFFFFF;
  pointer-events: none;
}

.edges line {
  stroke: #999;
  stroke-opacity: 0.4;
}

.nodes circle {
  stroke: #FFF;
  stroke-width: 2px;
}

.nodes {
  width: 100%;
  height: 100%;
  margin: 0 auto;
}

.edges {
  width: 100%;
  height: 100%;
  margin: 0 auto;
}
//Set SVG height and width
var width = 960,
    height = 660,
    padding = 5,
    radius=function (d) {
        return +d.degree * 150};

// Draw tooltips, to be used on mouseover and mouseout functions
var div = d3.select("body").append("div")	
    .attr("class", "tooltip")				
    .style("opacity", 0);
//Set force simulation for links and nodes

var force = d3.forceSimulation()
    //Create a force between nodes based on links
    .force("link", d3.forceLink().id(function (d) {
        return d.id;
    }))
    //.force("forceY", d3.forceY().y(height/2).strength(0.2))
    //.force("forceX", d3.forceX().x(width/2).strength(0.1))
    //forceManyBody simulates attraction and repulsion between nodes based on edge weight
    .force("attract", d3.forceManyBody().distanceMax(height - 2).distanceMin(20).strength(50))
    .force("repel", d3.forceManyBody().distanceMax(width/2).distanceMin(20).strength(-80))
    //Sets center force to the middle of the visualization
    .force("center", d3.forceCenter(width / 2, height / 2));

//Parse node list and edge list for use as arrays
//Entire chart creation procedure nested inside .csv functions
d3.csv("https://docs.google.com/spreadsheets/d/e/2PACX-1vRoWY_pOghfkbDQXUW8Fkb1jhE8In6rf4ToU5RNQzWXImU4_wkL0ABwD5J-npFZ1qyGtec8h49V_jR4/pub?output=csv", function (edges) {
    console.log(edges);
    d3.csv("https://docs.google.com/spreadsheets/d/e/2PACX-1vSSle95w7G7gCghDFHoFi5Eb_rXaHcEeBr4dVcbS1hFAedvdmLJDhasWw2edDeMTdI88jZv_exyIEfY/pub?output=csv", function (nodes) {
            console.log(nodes);

            //Color scale variable
            var colorScale =  d3.scaleQuantize()
                .domain([d3.min(nodes, function(d){ 
                  return d.orgbudget}),d3.max(nodes, function(d){
                  return d.orgbudget})])
                .range(d3.schemeSpectral[8]);             
                  console.log("colorScale:",colorScale.domain);  
            
            //console.log(d3.min(nodes.orgbudget));

            //Set variable for drawing new edges
            //Edges referred to as "links" in d3 network graph documentation    
            var link =d3.select("svg")
                .append("g")
                .attr("class", "edges")
                .attr("width", width)
                .attr("height", height)
                .selectAll("line")
                .data(edges)
                .enter().append("line")
                .attr("stroke-width", function (d) {
                    return Math.sqrt(+d.weight) - 1
                });


            //Set variable for drawing new nodes    
            var node =d3.select("svg")
                .append("g")
                .attr("class", "nodes")
                .selectAll("circle")
                .data(nodes)
                .enter()
                .append("circle")
                .attr("r", radius)
                .attr("fill", function(d){ return colorScale(+d.orgbudget)})
                .on("mousemove", function(d) {		
                    div.transition()		
                        .duration(200)		
                        .style("opacity", .9)		
                    div	.html("<b>" + d.label + "</b><br/>" + d.organization + "</br> <b>Organization Budget</b>: $<i>" + d.orgbudget +"</i>")	
                        .style("left", (d3.event.pageX + 20) + "px")		
                        .style("top", (d3.event.pageY - 60) + "px");	
                    })					
                .on("mouseout", function(d) {		
                    div.transition()		
                        .duration(500)		
                        .style("opacity", 0);
                    })
                    .call(d3.drag()
                    .on("start",dragstarted)
                    .on("drag",dragged)
                    .on("end",dragended));
         
         function dragstarted(d)
         { 
            force.restart();
            force.alpha(1.0);
            d.fx = d.x;
            d.fy = d.y;
         }
        
         function dragged(d)
         {
            d.fx = d3.event.x;
            d.fy = d3.event.y;
         }
        
         function dragended(d)
         {
            d.fx = null;
            d.fy = null;
            force.alphaTarget(0.1);
         }
        

            node.append("title")
                .text(function (d) {
                    return d.label;
                })
                ;


            //Initiate force simulation, set nodes to specified array
            force
                //Adds nodes, assigns x/y positions and x/y velocity based on the forces declared in the variable "force"
                .nodes(nodes)
                //.on(tick) increments the "tick" counter by 1,
                //Initiates the "ticked" function to position nodes and edges 
                .on("tick", ticked);

            //Declares the links to be used in the link force       
            force.force("link")
                .links(edges);
            //Set node and link positioning based on "tick" function
            //Basically waits for all elements to be processed, 
            //increments the tick timer by 1, then positions objects 
            
          
            function ticked() {
                link
                    .attr("x1", function (d) {
                        return d.source.x;
                    })
                    .attr("y1", function (d) {
                        return d.source.y;
                    })
                    .attr("x2", function (d) {
                        return d.target.x;
                    })
                    .attr("y2", function (d) {
                        return d.target.y;
                    });

                node
                    .attr("cx", function(d) { return d.x = Math.max(200, Math.min(width-200, d.x))
                                            ;})
                    .attr("cy", function(d) { return d.y = Math.max(100, Math.min(height-100, d.y)) ;});
                    


            }

        }



    )



})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.