Created
February 29, 2016 17:48
-
-
Save JenHLab/fabb713c310663d7e60f to your computer and use it in GitHub Desktop.
Dots on Lines
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<!-- Modification of an example by Scott Murray from Knight D3 course --> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="x-ua-compatible" content="ie=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>Theme Park Attendance</title> | |
<link href='https://fonts.googleapis.com/css?family=Droid+Serif:400,700italic|Arapey|PT+Serif' rel='stylesheet' type='text/css'> | |
<style type="text/css"> | |
body { | |
background-color: white; | |
font-family: 'PT Serif', serif; | |
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 1); | |
padding: 1.5rem; | |
margin-top: 3.5rem; | |
margin-bottom: 3.5rem; | |
} | |
h1 { | |
font-family: 'Droid Serif', serif; | |
font-size: 30px; | |
margin: 20px; | |
} | |
h3{ | |
margin: 10px; | |
font-size: 18px; | |
margin: 20px; | |
width: inherit; | |
} | |
p { | |
font-size: 16px; | |
margin: 10px; | |
text-align: left; | |
margin: 20px; | |
} | |
a{ | |
color: #0365d4; | |
} | |
svg { | |
background-color: white; | |
margin: 20px; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #0365d4; | |
stroke-width: 2px; | |
} | |
.line { | |
fill: none; | |
stroke: #b3d0f2; | |
stroke-width: 1px; | |
stroke-opacity: 80%; | |
} | |
.line.unfocused{ | |
stroke-opacity: 40%; | |
} | |
.line.focused { | |
stroke-width: 2px; | |
stroke-opacity: 100%; | |
stroke: #0365d4; | |
} | |
.axis text { | |
font-family: sans-serif; | |
font-size: 11px; | |
} | |
.tooltip { | |
position: absolute; | |
z-index: 10; | |
} | |
.tooltip p { | |
background-color: white; | |
opacity: 40%; | |
color: #c60bdd; | |
border: none; | |
padding: 2px; | |
} | |
.voronoi path { | |
stroke: none; | |
fill: none; | |
pointer-events: all; | |
} | |
text.linelabel { | |
font-size: 9pt; | |
color: gray; | |
} | |
circle { | |
fill: #c60bdd; | |
} | |
.callout-card { | |
background: white; | |
border: 1px solid #b3d0f2; | |
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); | |
margin: 1rem 0; | |
float: right; | |
width: 40%; | |
overflow: hidden; | |
} | |
.callout-card.warning .card-label { | |
border-color: transparent #b3d0f2 transparent transparent; | |
border-color: rgba(255, 255, 255, 0) #b3d0f2 rgba(255, 255, 255, 0) rgba(255, 255, 255, 0); | |
} | |
.callout-card .card-label { | |
border-style: solid; | |
border-width: 0 70px 40px 0; | |
float: right; | |
height: 0px; | |
width: 0px; | |
transform: rotate(360deg); | |
} | |
.callout-card .callout-card-content { | |
padding: 0.5rem 1.5rem 0.875rem; | |
} | |
.callout-card.radius { | |
border-radius: 0.6rem; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Walt Disney Co. Parks Continues to Welcome Over 100 Million Visitors Yearly</h1> | |
<h3>by <span><i>Jennifer Hernandez</i></span></h3> | |
<br> | |
<p>Walt Disney Co. continues leading the amusement and theme park industry with the most number of visitors to their parks annually. In 2014, the Themed Entertainment Association (TEA) reported that Walt Disney Co. received 134,300,000 million visitors while its major competitor in the U.S., Universal Studios Recretion Group, had 40,152,000 visitors that same year. | |
<br><br> | |
The Walt Disney Co. Parks and Resorts business unit operates 9 of the top 10 most visited parks in the world. Its most popular park is Magic Kingdom at Walt Disney World, Orlando, Florida with 19,332,000 million visitors in 2014, followed by Tokyo Disneyland, Disneyland at Disneyland Resort and Tokyo DisneySea at Tokyo Disney Resort. | |
<br><br> | |
Universal Studios Recretion Group has been experiencing a steady increase in the number of visitors to Universal Studios Florida at Universal Studios Orlando Resort since the opening of the Wizarding World of Harry Potter. In 2014, over 8.2 million people visited the park, 1 million more people from the previous year. | |
</p> | |
<div class="small-12 medium-6 columns"> | |
<div class="callout-card warning radius"> | |
<div class="callout-card-content"> | |
<h3 class="lead" style="color:#0365d4;">Top 10 Most Visited Parks in 2014</h3> | |
<table> | |
<thead> | |
<tr style="font-size: 15px;"> | |
<th width="350">Theme Park</th> | |
<th width="150">Visitors (Million)</th> | |
</tr> | |
</thead> | |
<tbody style="font-size: 13px;"> | |
<tr> | |
<td>Magic Kingdom at Walt Disney World Resort</td> | |
<td>19,332,000</td> | |
</tr> | |
<tr> | |
<td>Tokyo Disneyland at Tokyo Disney Resort</td> | |
<td>17,300,000</td> | |
</tr> | |
<tr> | |
<td>Disneyland at Disneyland Resort</td> | |
<td>16,769,000</td> | |
</tr> | |
<tr> | |
<td>Tokyo DisneySea at Tokyo Disney Resort</td> | |
<td>14,100,000</td> | |
</tr> | |
<tr> | |
<td>Universal Studios Japan</td> | |
<td>11,800,000</td> | |
</tr> | |
<tr> | |
<td>Epcot at Walt Disney World Resort</td> | |
<td>11,454,000</td> | |
</tr> | |
<tr> | |
<td>Disney's Animal Kingdom at Walt Disney World Resort</td> | |
<td>10,402,000</td> | |
</tr> | |
<tr> | |
<td>Disney's Hollywood Studios at Walt Disney World Resort</td> | |
<td>10,312,000</td> | |
</tr> | |
<tr> | |
<td>Disneyland Park at Disneyland Paris</td> | |
<td>9,940,000</td> | |
</tr> | |
<tr> | |
<td>Disney California Adventure at Disneyland Resort</td> | |
<td>8,769,000</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script> | |
<script type="text/javascript"> | |
//Dimensions and padding | |
var fullwidth = 700; | |
var fullheight = 600; | |
var margin = {top: 20, right: 220, bottom: 40, left:100}; | |
var width = fullwidth - margin.left - margin.right; | |
var height = fullheight - margin.top - margin.bottom; | |
//Set up date formatting and years | |
var dateFormat = d3.time.format("%Y"); | |
//Set up scales | |
var xScale = d3.time.scale() | |
.range([ 0, width ]); | |
var yScale = d3.scale.linear() | |
.range([10, height ]); | |
//Configure axis generators | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.orient("bottom") | |
.ticks(8) | |
.tickFormat(function(d) { | |
return dateFormat(d); | |
}) | |
.outerTickSize([0]) | |
.innerTickSize([5]); | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.orient("left") | |
.outerTickSize([0]); | |
//Configure line generator | |
// each line dataset must have a d.year and a d.amount for this to work. | |
var line = d3.svg.line() | |
.x(function(d) { | |
return xScale(dateFormat.parse(d.year)); | |
}) | |
.y(function(d) { | |
return yScale(+d.amount); | |
}); | |
//Create the empty SVG image | |
var svg = d3.select("body") | |
.append("svg") | |
.attr("width", fullwidth) | |
.attr("height", fullheight) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var tooltip = d3.select("body") | |
.append("div") | |
.attr("class", "tooltip"); | |
//Load data | |
d3.csv("pAttendance.csv", function(data) { | |
//New array with all the years, for referencing later | |
var years = ["2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014"]; | |
//Create a new, empty array to hold our restructured dataset | |
var dataset = []; | |
//Loop once for each row in data | |
data.forEach(function (d, i) { | |
var myAttendance = []; | |
//Loop through all the years - and get the emissions for this data element | |
years.forEach(function (y) { | |
// If value is not empty | |
if (d[y]) { | |
myAttendance.push({ | |
park: d.amusementPark, | |
year: y, | |
amount: d[y] // this is the value for, for example, d["2004"] | |
}); | |
} | |
}); | |
dataset.push( { | |
park: d.amusementPark, | |
attendance: myAttendance | |
} ); | |
}); | |
//Uncomment to log the original data to the console | |
// console.log(data); | |
//Uncomment to log the newly restructured dataset to the console | |
console.log(dataset); | |
//Set scale domains - max and mine of the years | |
xScale.domain( | |
d3.extent(years, function(d) { | |
return dateFormat.parse(d); | |
})); | |
// max of emissions to 0 (reversed, remember) | |
yScale.domain([ | |
d3.max(dataset, function(d) { | |
return d3.max(d.attendance, function(d) { | |
return +d.amount; | |
}); | |
}), | |
2000000 | |
]); | |
//Make a group for each country | |
var groups = svg.selectAll("g") | |
.data(dataset) | |
.enter() | |
.append("g") | |
.attr("class", "park"); | |
//Within each group, create a new line/path, | |
groups | |
.append("path") | |
.attr("class", "line") | |
.attr("d", function(d) { | |
console.log(d, this); | |
d.line = this; | |
return line(d.attendance); | |
}); | |
groups.each(function(d) { | |
console.log(d); | |
}) | |
// Adding a subtle animation to increase the dot size when over it! | |
var voronoi = d3.geom.voronoi() | |
.x(function(d){ | |
return xScale(dateFormat.parse(d.year)); | |
}) | |
.y(function(d) { | |
return yScale(+d.amount); | |
}) | |
.clipExtent([[margin.left - 120, margin.top - 50], [width + 20, height + 20]]); | |
var voronoiGroup = svg.append("g") | |
.attr("class", "voronoi"); | |
// we have to do this nesting trick because a lot of dots are in the same place. | |
// the goal here is to map to single points -- no dupes at the same point -- and after | |
// the nesting, return just the actual values (not the keys). | |
// The values in a nest are the original items that went into each key. | |
var nested = d3.nest() | |
.key(function(d) { // this key is the pair of x/y coords - to keep them single | |
return xScale(dateFormat.parse(d.year)) + "," + yScale(+d.amount); | |
}) | |
.rollup(function(v) { | |
return v[0]; // first of the objects, prevents use of 2 in same place | |
}) | |
.entries(d3.merge(dataset.map(function(d) { return d.attendance; }))) | |
.map(function (d) { return d.values;}); // the result is just a flat list of values | |
console.log(nested); | |
voronoiGroup.selectAll("path") | |
.data(voronoi(nested)) | |
.enter() | |
.append("path") | |
.attr("d", function(d, i) { | |
return "M" + d.join("L") + "Z"; }) //copy for a voronoi | |
.datum(function(d, i) { return d.point; }) | |
.on("mouseover", mouseoverFunc) // mouseover goes on the voronoi cell! | |
.on("mousemove", mousemoveFunc) | |
.on("mouseout", mouseoutFunc); | |
// We're putting the text label at the group level | |
groups.append("text") | |
.attr("x", function(d) { | |
if (d.attendance.length != 0) { | |
var lastYear = d.attendance[d.attendance.length-1].year; | |
return xScale(dateFormat.parse(lastYear)); | |
} | |
}) | |
.attr("y", function(d) { | |
if (d.attendance.length != 0) { | |
var lastAmount = d.attendance[d.attendance.length-1].amount; | |
return yScale(+lastAmount); | |
} | |
}) | |
.attr("dx", "3px") | |
.attr("dy", "3px") | |
.text(function(d) { | |
if (d.attendance.length != 0) { | |
var lastAmount = d.attendance[d.attendance.length-1].amount; | |
if (+lastAmount > 11000000) { | |
return d.park; | |
} | |
} | |
}) | |
.attr("class", "linelabel"); | |
// the line's dot is the "focus" element | |
var focus = svg.append("g") | |
.attr("transform", "translate(-100,-100)") // it's off screen | |
.attr("class", "focus"); | |
focus.append("circle") | |
.attr("r", 3.5); | |
focus.append("text") | |
.attr("y", -10); | |
//Title | |
svg.append("text") | |
.attr("x", (width - 400)) | |
.attr("y", 7 - (margin.top / 2)) | |
.style("font-weight", "bold") | |
.style("font-size", "19px") | |
.style("fill", "#0365d4") | |
.text("Theme Park Visitors 2007-2014"); | |
//Axes | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(yAxis); | |
function mouseoverFunc(d) { | |
// position the dot | |
focus.attr("transform", "translate(" + xScale(dateFormat.parse(d.year)) + "," + yScale(+d.amount) + ")"); | |
// show the tooltip | |
tooltip | |
.style("display", null) // this removes the display none setting from it | |
.html("<p>Park: " + d.park + | |
"<br>Year: " + d.year + | |
"<br>Attendance: " + d.amount + " visitors</p>"); | |
} | |
function mousemoveFunc(d) { | |
tooltip | |
.style("top", (d3.event.pageY - 10) + "px" ) | |
.style("left", (d3.event.pageX + 10) + "px"); | |
} | |
function mouseoutFunc(d) { | |
// remove the dot offscreen and the tooltip | |
focus.attr("transform", "translate(-100,-100)"); | |
d3.selectAll("path.line").classed("focused", false); | |
tooltip.style("display", "none"); // this sets it to invisible! | |
} | |
}); // end of data csv | |
</script> | |
<p style="font-size: 13px;"><b>Sources:</b> | |
<br> | |
<i><a href="https://cdn.thewaltdisneycompany.com/sites/default/files/reports/q4-fy15-earnings.pdf">The Walt Disney Company Reports: Fourth Quater and Full Year Earnings for Fiscal 2015</a></i>. The Walt Disney Company. 2015. | |
<br> | |
<br> | |
<i><a href="http://www.teaconnect.org/images/files/TEA_103_49736_150603.pdf">TEA/AECOM 2014 Theme Index and Museum Index: The Global Attendance Report</a></i>. Themed Entertainment Association (TEA). 2015. | |
</p> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
amusementPark | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | |
---|---|---|---|---|---|---|---|---|---|
Magic Kingdom at Walt Disney World Resort | 16640000 | 17063000 | 17233000 | 16972000 | 17142000 | 17536000 | 18588000 | 19332000 | |
Tokyo Disneyland at Tokyo Disney Resort | 12900000 | 14293000 | 13646000 | 14452000 | 13996000 | 14847000 | 17214000 | 17300000 | |
Disneyland at Disneyland Resort | 14730000 | 14721000 | 15900000 | 15980000 | 16140000 | 15963000 | 16202000 | 16769000 | |
Tokyo DisneySea at Tokyo Disney Resort | 12100000 | 12498000 | 12004000 | 12663000 | 11930000 | 12656000 | 14084000 | 14100000 | |
Universal Studios Japan | 8500000 | 8300000 | 8000000 | 8160000 | 8500000 | 9700000 | 10100000 | 11800000 | |
Epcot at Walt Disney World Resort | 10460000 | 10935000 | 10990000 | 10825000 | 10825000 | 11063000 | 11229000 | 11454000 | |
Disney's Animal Kingdom at Walt Disney World Resort | 9100000 | 9540000 | 9590000 | 9686000 | 9783000 | 9998000 | 10198000 | 10402000 | |
Disney's Hollywood Studios at Walt Disney World Resort | 8910000 | 9608000 | 9700000 | 9603000 | 9699000 | 9912000 | 10110000 | 10312000 | |
Disneyland Park at Disneyland Paris | 10600000 | 12688000 | 12740000 | 10500000 | 10990000 | 11200000 | 10430000 | 9940000 | |
Disney California Adventure at Disneyland Resort | 5950000 | 5566000 | 6095000 | 6287000 | 6341000 | 7775000 | 8514000 | 8769000 | |
Universal Studios Florida at Universal Orlando Resort | 6000000 | 6231000 | 5530000 | 5925000 | 6044000 | 6195000 | 7062000 | 8263000 | |
Islands of Adventure at Universal Orlando Resort | 5300000 | 5297000 | 4627000 | 5949000 | 7674000 | 7981000 | 8141000 | 8141000 | |
Ocean Park | 4380000 | 5030000 | 4800000 | 5404000 | 6955000 | 7436000 | 7475000 | 7792000 | |
Lotte World | 5500000 | 4236000 | 4261000 | 5551000 | 5780000 | 6383000 | 7400000 | 7606000 | |
Hong Kong Disneyland at Hong Kong Disneyland Resort | 5200000 | 4500000 | 4600000 | 5200000 | 5900000 | 6700000 | 7400000 | 7500000 | |
Everland | 7500000 | 6600000 | 6169000 | 6884000 | 6570000 | 6853000 | 7303000 | 7381000 | |
Universal Studios Hollywood | 4700000 | 4583000 | 4308000 | 5040000 | 5141000 | 5912000 | 6148000 | 6824000 | |
Songcheng Park | 3797000 | 3327000 | 3800000 | 4100000 | 5810000 | ||||
Nagashima Spa Land | 3910000 | 3734000 | 4700000 | 4465000 | 5820000 | 5850000 | 5840000 | 5630000 | |
Chimelong Ocean Kingdom | 5504000 | ||||||||
Europa Park | 3950000 | 4000000 | 4250000 | 4250000 | 4500000 | 4600000 | 4900000 | 5000000 | |
SeaWorld Orlando | 5740000 | 5926000 | 5800000 | 5100000 | 5202000 | 5358000 | 5090000 | 4683000 | |
Tivoli Gardens | 4396000 | 3972000 | 3870000 | 3696000 | 3963000 | 4033000 | 4200000 | 4478000 | |
Efteling | 3200000 | 3200000 | 4000000 | 4000000 | 4125000 | 4200000 | 4150000 | 4400000 | |
Walt Disney Studios Park at Disneyland Paris | 2200000 | 2612000 | 2655000 | 4500000 | 4710000 | 4800000 | 4470000 | 4260000 | |
Busch Gardens Tampa Bay | 4360000 | 4410000 | 4100000 | 4200000 | 4284000 | 4348000 | 4087000 | 4128000 | |
Universal Studios Singapore | 2000000 | 3411000 | 3480000 | 3650000 | 3840000 | ||||
SeaWorld San Diego | 4260000 | 4174000 | 4200000 | 3800000 | 4294000 | 4444000 | 4311000 | 3794000 | |
OCT East | 3530000 | 3890000 | 4196000 | 3950000 | 3780000 | ||||
Changzhou Dinosaur Park | 2300000 | 3500000 | 3400000 | 3600000 | 3700000 | ||||
Knott's Berry Farm | 3670000 | 3565000 | 3333000 | 3600000 | 3654000 | 3508000 | 3683000 | 3683000 | |
Window of the World | 2500000 | 2651000 | 3123000 | 3170000 | 3250000 | 3600000 | |||
Canada's Wonderland | 3230000 | 3380000 | 3160000 | 3380000 | 3481000 | 3655000 | 3582000 | 3546000 | |
PortAventura | 3500000 | 3300000 | 3000000 | 3050000 | 3522000 | 3540000 | 3400000 | 3500000 | |
Chimelong Paradise | 2400000 | 2400000 | 2700000 | 2970000 | 3200000 | 3351000 | |||
Happy Valley | 2350000 | 2734000 | 3438000 | 3055000 | 3100000 | 3340000 | |||
Happy Valley | 2930000 | 3180000 | 2800000 | 3050000 | 3890000 | 3212000 | 3282000 | 3300000 | |
Cedar Point | 3070000 | 3198000 | 2942000 | 3051000 | 3143000 | 3221000 | 3382000 | 3247000 | |
Kings Island | 3050000 | 3126000 | 3000000 | 3112000 | 3143000 | 3206000 | 3206000 | 3238000 | |
Hersheypark | 2690000 | 2842000 | 2807000 | 2891000 | 2949000 | 3140000 | 3180000 | 3212000 | |
Liseberg | 2950000 | 3050000 | 3150000 | 2900000 | 2900000 | 2800000 | 2860000 | 3100000 | |
Six Flags Magic Mountain | 2550000 | 2500000 | 2600000 | 2700000 | 2808000 | 2906000 | 2848000 | ||
Six Flags Great Adventure | 2730000 | 2761000 | 2634000 | 2700000 | 2650000 | 2800000 | 2800000 | ||
Gardaland | 3100000 | 3100000 | 2900000 | 2800000 | 2850000 | 2700000 | 2700000 | 2750000 | |
Busch Gardens Williamsburg | 3094000 | 2900000 | 2800000 | 2744000 | 2854000 | 2726000 | 2699000 | ||
Alton Towers | 2400000 | 2520000 | 2650000 | 3000000 | 2750000 | 2400000 | 2500000 | 2575000 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment