D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
maggie-lee
Full window
Github gist
Georgia High Schools Compared
<!DOCTYPE html> <html> <style> body { font: 10px sans-serif; } .title { font-size: 22px; } .choose{ font-size: 12px; fill: #31A354; font-weight: bold; } .source { font-size: 10 fill: black; } .canvas { background-color: #E5F5E0; } .dot {} .sidebarItem{} .ul { list-style: none; list-style-type: none; padding: 0; margin-left: 0; z-index:2; } .axis path, .axis line { fill: none; stroke: black; display: none; shape-rendering: crispEdges; } div.explanation { position: relative; font: 12px sans-serif; top: -1400px; right: -10px; width: 600px; height: 80px; background: #E5F5E0; border: 0px; border-radius: 0px; } div.tooltip { position: absolute; text-align: center; width: 80px; height: 60px; padding: 2px; font: 10px sans-serif; background: #A1D99B; border: 0px; border-radius: 8px; pointer-events: none; z-index: 1; } div.sidebar{ position: relative; top: -650px; right: -475px; width: 150px; height: 625px; padding-left: -150px; font: 12px sans-serif; text-align: left; color: #31A354; background: #E5F5E0; border: 0px; border-radius: 0px; overflow: scroll; } </style> <head> <script type="text/javascript" src="https://d3js.org/d3.v3.min.js"></script> </head> <body> <script> //light green #E5F5E0 //middle green #A1D99B //dark green #31A354 //start with some variables var margin = {top: 200, right: 10, bottom: 20, left: 10}; var width = 625 - margin.left - margin.right, height = 850 - margin.top - margin.bottom; //read in some data d3.csv("ccrpi.csv", function(error, data) { data.forEach(function(d) { // read in everything in case needed later d.systemId = +d.SystemId, //adding a "+" reads it in as a number i/o string d.system = d.SystemName, d.schoolId = +d.SchoolId, d.schoolName = d.SchoolName, d.grades = d.GradeConfiguration, d.gradeCluster = d.GradeCluster, d.aPoints = +d.AchievementPoints, // score out of 70 d.prPoints = +d.ProgressPoints, //score out of 15 d.agPoints = +d.AchievementGapPoints, // score out of 15 d.cPoints = +d.TotalChallengePoints, //max 10 d.score = +d.CCRPIScore //out of 100 }) //filters to go from like 2,000 schools to the 450 or so I want: var filtered = data.filter(function(el) { return el.gradeCluster == "H" && //filter in high schools only isNaN(el.schoolId) == false && // filter out school system averages isNaN(el.score) == false ; //filter out "N/A"s }); // and start drawing var svg = d3.select("body").append("svg") .attr("class", "canvas") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .style("overflow", "scroll") .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var x = d3.scale.linear() .range([20, 425]) .domain([0, 1]); var y = d3.scale.linear() .range([height, 0]) .domain([0, d3.max(filtered, function (d) {return d.score;})]); //get the top score var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var div = d3.select("body").append("div") // put the tooltip in a separate div .attr("class", "tooltip") //see d3noob website for all tooltip explanation .style("opacity", 0); var dots = svg.selectAll(".dot") //ok let's draw a dot ... .data(filtered) /// for each school in the filtered list .enter().append("circle") .attr("class", "dot") .attr("fill", "#31A354") .attr("stroke", "DimGray") .attr("opacity", 0.5) .attr("r", 4.5) .attr("cy", height/2) .attr("cx", function () {return x(Math.random());} ) // x axis doesn't mean anything on this graph. :( .attr("class", "dot") .attr("fill", "#31A354") .attr("stroke", "DimGray") .attr("opacity", 0.5) .attr("class", function (d) {return d.system + " dot";}) // assign each dot to two classes. First, its school system name, then also to " dot". every dot needs to be in the dot class for its all-dot-related instructions. but it also needs to be in its school system class to take instructions that just apply to its school system. See this for mapping: https://bit.ly/10VxAK5 .on("mouseover", function(d) { //beautiful transition animation //d3.select(this).style("fill", "red"); div.transition() .duration(200) .style("opacity", .9); div .html("<b>" + d.system.replace(/_/g, " ") + "</b></br>" + d.schoolName + "</br>" + d.score) .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY - 28) + "px"); }) .on("mouseout", function(d) { //d3.select(this).style("fill", "#31A354"); div.transition() .duration(500) .style("opacity", 0); }); dots.transition() .transition() .duration(1500) .attr("cy", function (d) {return (y(d.score)); }) // now out of "filtered", we need an js object of just system names, no duplicates, to make the sidebar. there might be a way to do this on the fly but idk. we'll wrap it in a function var sidebarArrayMaker = function (some_Array) { var sidebarArray = []; var len = some_Array.length; for (var i = 0; i < len; i++) { var obj = { system: some_Array[i].system, sortable: true, resizeable: true }; sidebarArray.push(obj); }; for( var i=0; i<sidebarArray.length-1; i++ ) { if ( sidebarArray[i].system == sidebarArray[i+1].system) { delete sidebarArray[i]; } } sidebarArray = sidebarArray.filter( function( el ){ return (typeof el !== "undefined"); } ); {return sidebarArray} }; //then we'll call the function sidebarArray = (sidebarArrayMaker(filtered)); //putting the sidebar in a separate div so I can give it overflow:scroll in css var sidebarDiv = d3.select("body").append("div") .attr("class", "sidebar") var ul = d3.select(".sidebar").append("ul") //select the sidebar and put a ul in it .attr("class", "ul") ul.selectAll("li") .data(sidebarArray) .enter() .append("li") .text(function (d) {return d.system.replace(/_/g, " ");}) .attr("class", "sidebarItem") .attr("class", function (d) {return d.system + " sidebarItem";}) //assign each text to two classes, just like for dots above .on("click", function(d) { d3.selectAll(".sidebarItem").style("color", "#31A354"); //sidebar text reset/default to dark green d3.selectAll(".dot").style("fill", "#31A354"); // all dots reset/default to dark green d3.selectAll("." + d.system).style("fill", "red").style("color", "red"); }) // then whatever system you click on, all the dots of that same class turn red. .on("mouseout", function (d) { console.log("mouse upped"); // don't un-red the dots until someone clicks on a different sidebar word }); var explanationDiv = d3.select("body").append("div") .attr("class", "explanation") .text("Georgia started measuring its schools by a new scale with the 2012 school year. The new Georgia College and Career Ready Performance Index replaces the Adequate Yearly Progress measure that Georgia dropped when it exited the federal No Child Left Behind program in early 2012. The new scale scores every school out of 100, with heaviest weight on achievement, like, content mastery and post high school readiness."); svg.append("g") .attr("class", "axis") .attr("transform", "translate( 20 ,0)") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 0) .attr("dx", -600) .style("text-anchor", "start") .attr("font-family", "sans-serif") .attr("font-size", "10px") .attr("fill", "black") .text("Score out of 100"); svg.append("text") .attr("class", "title") .attr("x", 0) .attr("y", -150) .text("Georgia High Schools Plot against Each Other"); svg.append("text") .attr("class", "source") .attr("x", 0) .attr("y", -130) .text("by Maggie Lee"); svg.append("text") .attr("class", "choose") .attr("x", 465) .attr("y", -10) .text("choose a system:"); svg.append("text") .attr("class", "choose") .attr("x", 465) .attr("y", -23) .text("Scroll & click to"); svg.append("text") .attr("class", "source") .attr("x", 50) .attr("y", height+10) .text("Source: Georgia Department of Education"); svg.append("text") .attr("class", "choose") .attr("x", 10) .attr("y", -23) .text("Hover to see a single school"); }); //Some school names have been abbreviated because they are so long. //thanks to d3Vinno on YouTube https://www.youtube.com/user/d3Vienno //thanks to the d3js community and this link expecially for one-to-many mappings hhttps://bit.ly/10VxAK5 //that one school with 101 is correct </script> </body> </html>
Modified
http://d3js.org/d3.v3.min.js
to a secure url
https://d3js.org/d3.v3.min.js