##Summary This Map of New Mexico present information about the relative population across the state, it's evolution since 1900 and other facts related to population. It should be interesting to those who know about New Mexico or are generally interested in population trends.
It presents the counties of New Mexico as a Chloropleth using a Quartize scale which encodes populations of the counties as colors: white means the county did not yet exist and the data is actually missing. dark red represents population's above 500K which is really only Bernallillo where the major city in NM called Albuquerque is. Yellow to Red represents populations in between those
##Design: The initial design was intended to show a chloropleth which would explain how New mexico could be such a less populated State except for Albuquerque/county of Bernallilo which is a faily large city. It was intended to show the change in population from 1990 to 2010 which is available on the us goverment census website. It was envisioned that the chloropleth transiton of population over time whould make for a good visual. The initial prototype/map without filling is provided as the HTML file called NMPopMapOnly.html. see below.
The visualization ended up at 3 stages implementing the visualization experience theory referred to in Udacity Data Visualization class as the Martini Glass. The Martini Glass experience as applied to this visualization is:
Martini Base: User s allowed to explore the population of each county in New Mexico as of the most recent Census in 2010.
Martini Stem: User is shown the transtion visualization of how population changed from 1900 to 2010.
Martini Drink: The user is presented all the information and can consume it as they see fit.
##Feedback from reviewers:
##Resources
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v3.js"></script>
<script src="https://d3js.org/queue.v1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.10.0/d3-legend.js"></script>
<style>
h2 {
text-align: center;
color: black;
font-size: 120%;
}
div.play_buttons {
position: fixed;
top: 70px;
left: 20px;
}
div.play_buttons div {
display:inline;
background-color: rgb(241,191,0); /*NM Yellow*/
padding: 7px;
margin: 7px;
}
div.years_buttons {
position: fixed;
top: 65px;
left: 80px;
}
div.years_buttons div {
display:inline;
background-color: rgb(241,191,0); /*NM Yellow*/
padding: 4px;
margin: 4px;
border-radius: 4px;
font-size: 80%;
}
button#clearBtn {
position: fixed;
top: 50px;
left: 850px;
display:inline;
background-color: rgb(241,191,0); /*NM Yellow*/
padding: 7px;
margin: 7px;
}
button#filterBtn {
position: fixed;
top: 50px;
left: 750px;
display:inline;
background-color: rgb(241,191,0); /*NM Yellow*/
padding: 7px;
margin: 7px;
}
.q0-9{fill:rgb(255,255,229)}
.q1-9{fill:rgb(255,247,188)}
.q2-9{fill:rgb(254,227,145)}
.q3-9{fill:rgb(254,196,79)}
.q4-9{fill:rgb(254,153,41)}
.q5-9{fill:rgb(236,112,20)}
.q6-9{fill:rgb(204,76,2)}
.q7-9{fill:rgb(153,52,4)}
.q8-9{fill:rgb(102,37,6)}
.legendQuant {
font-size: 66%;
}
div.tooltip {
position: fixed;
text-align: center;
width: 120px;
padding: 3px;
font: 14px sans-serif;
background: rgb(170,21,27); /*NM Red*/
border: 0px;
border-radius: 8px;
pointer-events: none;
box-shadow:rgba(0, 0, 0, 0.3) 0 4px 10px; /* tootip floats */
}
/* next items control the tooltip that appears periodically) */
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
/* Position the tooltip */
position: absolute;
z-index: 1;
}
.tooltip:hover .tooltiptext {
visibility: visible;
}
#myBtn {
position: fixed;
top: 110px;
left: 10px;
font-size: 80%
}
#myBtn2 {
position: fixed;
top: 140px;
left: 10px;
font-size: 80%
}
#myBtn3 {
position: fixed;
top: 170px;
left: 10px;
font-size: 80%
}
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 140px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(241,191,0); /*NM Yellow*/
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Header */
.modal-header {
padding: 2px 16px;
background-color: rgb(170,21,27); /*NM Red*/
color: white;
}
/* Modal Body */
.modal-body {
padding: 2px 16px;
background-color: rgb(241,191,0); /*NM Yellow*/
}
/* Modal Footer */
.modal-footer {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
/* Modal Content */
.modal-content {
position: fixed;
top: 120px;
left: 600px;
background-color: #fefefe;
margin: auto;
padding: 0;
border: 1px solid #888;
width: 25%;
/*
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
-webkit-animation-name: animatetop;
-webkit-animation-duration: 0.4s;
animation-name: animatetop;
animation-duration: 0.4s
*/
}
/* Add Animation */
@-webkit-keyframes animatetop {
from {top: -300px; opacity: 0}
to {top: 0; opacity: 1}
}
@keyframes animatetop {
from {top: -300px; opacity: 0}
to {top: 0; opacity: 1}
}
table {
position: fixed;
top: 100px;
left: 400px;
border-collapse: collapse;
padding: 0;
margin: 0 0 2px 0;
font-size: 66%;
}
table th {
text-align: left;
border-bottom: 2px solid rgb(254,153,41);
vertical-align: bottom;
padding: 0 2px 2px 2px;
text-align: right;
}
table td {
border-bottom: 1px solid rgb(254,196,79);
border-right: 1px solid rgb(254,196,79);
vertical-align: top;
padding: 2px;
text-align: right;
}
table th:nth-child(1),
table td:nth-child(1) {
text-align: left;
padding-left: 0;
font-weight: bold;
}
</style>
<div id="myModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<span class="close">×</span>
Replace me first
</div>
<div class="modal-body",role="document"> Replace me <OL><LI> FIRST</LI><LI>sECOND</LI></OL>
</div>
</div>
</div>
<script type="text/javascript">
function draw(geo_data) { //Main function
"use strict";
//setup tool tip text for the 3 phases of "martini" style visualization
var martiniBase = ["New Mexico's Population in 2010",
"Start with the County Populations as of the 2010 Census. If you hover over the counties you'll see the actual population. Spend a while to get used to the various counties and the relative population of each. When you are ready use the white buttons: 1. the top one repeats this introduction. 2. The middle one tells explains more about what you saw. 3. the bottom button is for when you are ready for more."] ;
var martiniBaseSummary = ["New Mexico's Population in 2010 - In review",
"New Mexico has 33 counties as of the 2010 Census. 32% of the population of the whole state, or almost a 3rd, live in Bernallilo County in the center of the state. Bernallilo is the 3rd smallest county after Los Alamos and Valencia but contains the City of Albuquerque and the university of New Mexico. The next most populous city is Las Cruces in Dona Ana County in Southern NM home to New Mexico State University. It is telling that Higher Education seems to drive the larest populations in this State. Note the the Northwest and South East Corners are also realively higher populations. These are both Oil producing area's and owe their population to the Oil and Gas Industry. "] ;
var martiniStem = ["New Mexico's Population from 1900 to 2010",
"Now we will transition back to 1900 and the decade by decade progression to 2010. Click the play button when ready. You can also click on any year to transition to it. When you are done looking at the progression, click the middle button for an explanation."];
var martiniStemSummary = ["New Mexico's Population changes from 1900 to 2010 - In review",
"In 1900 the counties shown on the map were part of the Territory of New Mexico which included Arizona. In 1900 there were only 20 counties in New Mexico. Note the counties which did not exist in white. New Mexico did not become a U.S. state until 1912 by which time all but 7 had seceeded to become independent entities. The final 2 counties to seceed were Los Alamos in 1949 after it's historic role in building the Atom Bombs which ended World War 2 and Cibola County as recently as 1981 which seceeded from Valencia County. In terms of the population change trends, most telling is #1 that Bernallilo and Albuquerque have been the largest since 1900 and has grown the fastest. It must help in such a large but relativley unpopulated State to be in the center. Another telling lack of change is San Miguel county which has scarecely grown since 1900 when it was the second most populous county in the state. We'll look for some statistics on that in the next section. Next to San Miguel is Harding County which has consistenly shrunk and is a 5th of the size since 1900. San Miguel and Harding have no significantly large cities and largely arid grassland for natural resources. When ready: click the'Show me more' button to continue."] ;
var martiniDrink = ["New Mexico's Population in more detail",
"You made it!! Now you can see it all including this new table of county facts as of 2010. Click on individual counties to highlight as many as you want. Click the 'filter' button to show only those counties for easy comparison. Click the 'clear' button to start selecting over again."];
var martiniDrinkSummary = ["New Mexico's Population Statistics",
"So what stands out from all these statistics? If you select the largest counties and filter you'll see that they are growing the fastest. Look at Delta%. If you select the more populated counties in the NorthWest and Southeast you'll see that their major industry is Natural resources. The summary in general is that New Mexico is growing only by educating it's citizens and by Oil and Gas. the generally accepted tenent is that New Mexico needs to diversif into other areas. On exception is Los Alamos County add that an you can see what the possible and promising 3rd Industry is for New Mexico. "];
//setup a function to lookup fill values as a workaround for quantize which doesn't play well
function colorBaseOn(value) {
if (value < 1) {return "rgb(255,255,255)"}
else {if (value < 1000) {return "rgb(255,247,188)"}
else {if (value < 2000) {return "rgb(254,227,145)"}
else {if (value < 5000) {return "rgb(254,196,79)"}
else {if (value < 20000) {return "rgb(254,153,41)"}
else {if (value < 50000) {return "rgb(236,112,20)"}
else {if (value < 100000) {return "rgb(204,76,2)"}
else {if (value < 400000) {return "rgb(153,52,4)"}
else {return "rgb(102,37,6)"}}}}}}}}}
// setup sizes for the svg element
var margin = 20,
width = 620 - margin,
height = 700 - margin;
// Put the title on the screen
d3.select("body")
.append("h2")
.text("Population of the Counties of New Mexico, United States")
;
var commaFormat = d3.format("0,000"); // to format the population and other #s
var firstTip = true; // sets up so we can show the first tip only once
// setup the modal to contain martini tips
d3.select("body") //Modal button #1 - getting started and review
.append("button")
.attr("id","myBtn")
.text("Start Here");
d3.select("body") //Modal button #2 - explanations
.append("button")
.attr("id","myBtn2")
.text("What did I miss?");
d3.select("body") //Modal button #3 - next
.append("button")
.attr("id","myBtn3")
.text("Show me more");
var modal = document.getElementById('myModal');// Name the modal
var btn = document.getElementById("myBtn");// Name the button that opens the modal
btn.onclick = function() { // When the user clicks the button, open the modal
turnOnModal(1);
}
var btn2 = document.getElementById("myBtn2");// Name the button that opens the modal
btn2.onclick = function() { // When the user clicks the button, open the modal
turnOnModal(2);
}
var btn3 = document.getElementById("myBtn3");// Name the button that opens the modal
btn3.onclick = function() { // When the user clicks the button, open the modal
turnOnModal(3);
}
window.onclick = function(event) { // When the user clicks anywhere outside of the modal, close it
if (event.target == modal) { // if in Modal mode get out
modal.style.display = "none";
}
}
function turnOnModal(buttonPressed) { //setup common function to turn on the modal with variable text
if (buttonPressed === 1 && martiniStep === 3) {
d3.select(".modal-header").text(martiniDrink[0]);
d3.select(".modal-body").text(martiniDrink[1]);
}
if (buttonPressed === 2 && martiniStep === 3) {
d3.select(".modal-header").text(martiniDrinkSummary[0]);
d3.select(".modal-body").text(martiniDrinkSummary[1]);
}
if (buttonPressed === 1 && martiniStep === 2) {
d3.select(".modal-header").text(martiniStem[0]);
d3.select(".modal-body").text(martiniStem[1]);
}
if (buttonPressed === 2 && martiniStep === 2) {
d3.select(".modal-header").text(martiniStemSummary[0]);
d3.select(".modal-body").text(martiniStemSummary[1]);
}
if (buttonPressed === 3 && martiniStep === 2) {
d3.select(".modal-header").text(martiniDrink[0]);
d3.select(".modal-body").text(martiniDrink[1]);
fillCounties("2010");//put the year and county display to 2010 to match the statisitcs table
// display the statistics table
var peopleTable = tabulate(NMcenthist, ["id","Delta%",
"Area","PopDensity","Unemployed","Job Openings","AvergeWage","TopIndustry" ,"Industry%"]);
d3.select("btn3").attr("hidden",true);
martiniStep = 3
}
if (buttonPressed === 0) { //when screen first loads
martiniStep = 1
buttonPressed = 1
d3.select("#myBtn").text("Tell me again");
}
if (buttonPressed === 1 && martiniStep === 1) {
d3.select(".modal-header").text(martiniBase[0]);
d3.select(".modal-body").text(martiniBase[1]);
}
if (buttonPressed === 2 && martiniStep === 1) {
d3.select(".modal-header").text(martiniBaseSummary[0]);
d3.select(".modal-body").text(martiniBaseSummary[1]);
}
if (buttonPressed === 3 && martiniStep === 1) {
d3.select(".modal-header").text(martiniStem[0]);
d3.select(".modal-body").text(martiniStem[1]);
d3.select("div.play_buttons").attr("hidden",null);
d3.select("div.years_buttons").attr("hidden",null);
fillCounties("1900");//put the year and county display to 1900
buttonLooksPushed("1900")
martiniStep = 2
}
modal.style.display = "block";
}
//Turn on modal for the first time as page loads
var martiniStep=0;
turnOnModal(0);
// Put the SVG on the screen
var svg = d3.select("body")
.append("svg")
// .attr("fill","rgb(254,153,41)") //workaround for fill transition starting at black
.attr("width", width + margin)
.attr("height", height + margin)
.append('g')
.attr('class', 'map')
;
//setup var called years to drive buttons and looping
var years = [];
for(var i = 1900; i < 2011; i += 10) {
years.push(i);
};
// Define the div for the tooltip to appear for counties
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
/*
Use D3 to load the GeoJSON file */
var projection = d3.geo.albersUsa()
.scale(5000)
.translate([1000, -40]);
var path = d3.geo.path().projection(projection);
/* Draw the county outline */
var map = svg.selectAll('path')
.data(geo_data.features)
.enter()
.append('path')
.attr('d', path)
.style('stroke', 'black')
.style('stroke-width', 0.5)
.attr("id", function(d){
var countyLoc = d.properties.name.search("County");
return d.properties.name.slice(0,countyLoc-1);
})
;
/* Add the County names */
var map1 = svg.selectAll("text")
.data(geo_data.features)
.enter()
.append("svg:text")
.text(function(d){
var countyLoc = d.properties.name.search("County");
return d.properties.name.slice(0,countyLoc-1);
})
.attr("fill","rgb(255,255,255)") /* needs to contrast with Quantize scale */
.attr("x", function(d){
return path.centroid(d)[0];
})
.attr("y", function(d){
return path.centroid(d)[1];
})
.attr("text-anchor","middle")
.attr('font-size','8pt')
.attr('fill', "grey") //make county more readable
.attr('width', '30px')
.attr('word-wrap', 'break-word');
;
/* Fill the County relative to population */
//setup javascript map function to lookup values in the incoming csv
var popById = d3.map();
// setup scale to color the counties based on population
var domain = [0,1000,2000,5000,20000,50000,75000,400000, 1000000];
var quantize = d3.scale.threshold()
.domain(domain)
// .domain([0, 665000])
.range(d3.range(9).map(function(i) { return "q" + i + "-9"; }));
//create a legend from https://d3-legend.susielu.com/#color-quant
var svg = d3.select("svg");
svg.append("g")
.attr("class", "legendQuant")
.attr("transform", "translate(200,570)");
var legend = d3.legend.color()
.title("Population")
.labels(["not yet in existence"])
.shapeWidth(25)
.shapeHeight(8)
.labelFormat(d3.format(",d"))
.useClass(true)
.scale(quantize);
svg.select(".legendQuant")
.call(legend);
//read csv file of data and cleanup (make numerics numeric)
var NMcenthist = [];
queue()
.defer(d3.csv,"NMcenhist_totals.csv", function(data) //defer waits for file to load
{for (var i = 0; i < years.length; i++) {
data[years[i]] = +data[years[i]];} //takes string and makes it numeric
NMcenthist.push(data);
})
//once file is read proceed to the next (ready) function
.await(ready);
//continue from queue.defer
function ready(error, us) {
if (error) throw error;
console.log(NMcenthist);
//all loaded - set initial year and give a first tooltip to the user
fillCounties("2010");
};
// called to change fill for a different year
function fillCounties(year) {
console.log("changing counties pop to year: " + year)
// Setup lookup from the CSV file
NMcenthist.forEach(function(d) {
popById.set(d.id, +d[year]);
});
//color map based on lookup value
var counties = svg.selectAll("path")
.style("fill-opacity", 0)
.transition().duration(1500) //-----------Timing for smooth color transition
.style("fill", function(d) {
return colorBaseOn(popById.get(d.properties.name)); })
.attr("d", path)
.style("fill-opacity", 1);
//added tootip based on https://bl.ocks.org/d3noob/a22c42db65eb00d4e369
function setupCountyHover(d,t) {
div.transition()
.duration(200)
.style("opacity", .9);
if (popById.get(d.properties.name) < 1) {
div .html(d.properties.name + " had not yet seceded" )
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
} else {
div .html("Population of " + d.properties.name
+" was " + commaFormat(popById.get(d.properties.name)))
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
}
}
svg.selectAll("path")
.on("mouseover", function (d){setupCountyHover(d,this)}) //---------Tooltip for county outline
.on("mouseout", function(d) { //turn off tooltip
div.transition()
.duration(500)
.style("opacity", 0);
})
.on("click",function(d) { //-------- On click to highlight rows
var firstWord = d.properties.name.substr(0, d.properties.name.indexOf(" "));
d3.select("tr#" + firstWord) // highlight selected county in the table
.style("background-color","rgb(64,224,208)")
.attr("class","tr-selected");
d3.select("tr#" + firstWord) // highlight selected county in the svg
.style("background-color","rgb(64,224,208)")
.attr("class","tr-selected");
;
});
svg.selectAll("text")
.on("mouseover", function (d){setupCountyHover(d,this)}) //---------Tooltip for county name
.on("mouseout", function(d) { //turn off tooltip
div.transition()
.duration(500)
.style("opacity", 0);
})
.on("click",function(d) { //-------- On click to highlight rows
var firstWord = d.properties.name.substr(0, d.properties.name.indexOf(" "));
d3.select("tr#" + firstWord) // highlight selected county in the table
.style("background-color","rgb(64,224,208)") //NM Turquoise
.attr("class","tr-selected");
;
});
}
//add play button to show each year in turn
var play = d3.select("body")
.append("div")
.attr("class", "play_buttons")
.attr("hidden",true) // hidden until Martini Stage 2
.append("div")
.text("Play")
.attr("id","playpausebtn")
.attr("state","paused")
.attr("playyear",1900)
//add citation at bottom
var cite = d3.select("body")
.append("div")
.attr("class", "citation")
.text("Data Source: U.S. Census Bureau; generated by Jamey McCabe; using American FactFinder; <https://factfinder2.census.gov>; (15 February 2016).")
.style('font-size',"10px")
.attr('fill', "grey")
// The table generation function
function tabulate(data, columns) {
var table = d3.select("body").append("table")
.attr("style", "margin-left: 250px"),
thead = table.append("thead"),
tbody = table.append("tbody");
// append the header row
thead.append("tr")
.selectAll("th")
.data(columns)
.enter()
.append("th")
.text(function(column) { return column; });
// create a row for each object in the data
var rows = tbody.selectAll("tr")
.data(data)
.enter()
.append("tr")
.attr("class","tr-unselected")
.attr("id",function(d) {
var firstWords = [];
// find first word from https://stackoverflow.com/users/603003/comfreek
var firstWord = d.id.substr(0, d.id.indexOf(" "));
return firstWord; //set the ID of row to the first word in county name/data id
})
.on("click",function(d) { //-------- On click to highlight rows
d3.select(this) // highlight selected county in the table
.style("background-color","rgb(64,224,208)") //NM Turquoise
.attr("class","tr-selected");
});
// create a cell in each row for each column
var cells = rows.selectAll("td")
.data(function(row) {
return columns.map(function(column) {
return {column: column, value: row[column]};
});
})
.enter()
.append("td")
.html(function(d) { return d.value; })
;
// setup the filter and clear buttons
d3.select("body")
.append("button")
.attr("id","filterBtn")
.text("filter");
var fBtn = document.getElementById("filterBtn");// Name the filter button
fBtn.onclick = function() { // When the user clicks "Filter" show only the selected tr
d3.select("tr#Median").attr("class","tr-selected");
d3.selectAll(".tr-unselected").attr("hidden",true);
}
d3.select("body")
.append("button")
.attr("id","clearBtn")
.text("clear");
var cBtn = document.getElementById("clearBtn");// Name the clear button
cBtn.onclick = function() { // When the user clicks "Clear"
d3.selectAll(".tr-unselected").attr("hidden",null) //unhide the unslected rows
d3.selectAll(".tr-selected").attr("class","tr-unselected"); //unselect the selected rows
d3.selectAll("tr").style("background-color",null); //change background color off
}
return table;
}
;
// Set play / pause button functionality, Credit: https://www.developphp.com/video/JavaScript/Audio-Play-Pause-Mute-Buttons-Tutorial
//setup variables to control looping display
var playbtn;
var playState = "paused";
// Add Event Handling - provides interupts to start and stop looping
document.getElementById("playpausebtn").addEventListener("click",playPause);
// Function to loop and stop looping
function playPause(){
console.log("play button clicked - state =" + playState)
var playYear = 1900;
var playMs = 2000; //milliseconds pause between years when playing
function nextYear() {buttonLooksPushed(playYear);fillCounties(playYear);playYear+=10;};
d3 //use transition.transition to chain the years
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
.transition().duration(playMs).each(nextYear)
;
}
//add buttons for each year to allow individual selection of a year
var buttons = d3.select("body")
.append("div")
.attr("class", "years_buttons")
.attr("hidden",true) // hidden until Martini Stage 3
.selectAll("div")
.data(years)
.enter()
.append("div")
.attr("class","yrButton")
.attr("id",function(d) {return "b"+d;}) //set id to format "b" + year
.text(function(d) {return d;})
.attr("hidden",true) // hidden until Martini Stage 3
.style("background", "rgb(241,191,0)") /*NM Yellow*/
;
var button2010 = d3.select("#b2010")
.attr("hidden",null) // show 2010 for Stage 1
//setup function to make button looked pushed
function buttonLooksPushed(year) {
d3.select(".years_buttons")
.selectAll("div")
.transition()
.duration(10)
.style("background", "rgb(241,191,0)") /*NM Yellow*/
.style("box-shadow", "");
d3.select("#b" + year)
.transition()
.duration(10)
.style("background", "rgb(170,21,27)") //NM Red
.style("box-shadow", "inset 5px 5px 5px #888888") //button looks pushed in
.style("color", "white");
}
buttons.on("click", function(d) {
buttonLooksPushed(d);
fillCounties(d);
});
};
</script>
</head>
<body>
<script type="text/javascript">
/* Use D3 to load the GeoJSON file */
d3.json("NM_county 1.json", draw);
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.js to a secure url
Modified http://d3js.org/queue.v1.min.js to a secure url
https://d3js.org/d3.v3.js
https://d3js.org/queue.v1.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.10.0/d3-legend.js