This is the braodway projection interactive, currently developed at the Economist Data Team.
We love blockbuilder!
xxxxxxxxxx
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css" type="text/css" media="screen"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script type="text/javascript" src="https://infographics.economist.com/js_libraries/infographic_mobile.js"></script>
<!-- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> -->
<link rel="stylesheet" href="https://cdn.static-economist.com/sites/all/themes/econfinal/styles/reset.css">
<link type="text/css" rel="stylesheet" media="all" href="https://cdn.static-economist.com/sites/all/themes/econfinal/styles/ec-custom-fonts.css">
<script src="d3.slider.js"></script>
<!-- <link rel="stylesheet" href="https://cdn.static-economist.com/sites/all/themes/econfinal/styles/reset.css">
<link type="text/css" rel="stylesheet" media="all" href="https://cdn.static-economist.com/sites/all/themes/econfinal/styles/ec-custom-fonts.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> -->
<link rel="stylesheet" href="style2.css">
<style>
body, h1, h2, h3, p, table, td {
margin: 0px;
padding: 0px;
font-family: Officina, Calibri, Arial;
font-size: 13px;
line-height: 1.5em;
color: #000;
}
#content {
margin: 0px;
padding: 0px;
width: 595px;
text-align: center;
}
#container {
margin: 0px 0px 15px 0px;
padding: 0px;
}
#header h1 {
margin: 7px 0px 0px 20px;
padding: 0px;
font-family: Officina_bold, Calibri, Arial;
font-size: 17px;
font-weight: normal;
color: #000;
}
#header h2 {
margin: -3px 0px 0px 20px;
font-family: Officina, Calibri, Arial;
font-size: 14px;
font-weight: normal;
}
#footer h1 {
margin: 50px 50px 0px 100px;
margin-top: 140px;
padding: 50px;
padding-bottom: 20px;
padding-top: 30px;
font-family: Officina_bold, Calibri, Arial;
font-size: 17px;
font-weight: normal;
color: #000;
}
#footer h2 {
margin: -3px 0px 0px 60px;
font-family: Officina, Calibri, Arial;
font-size: 18px;
font-weight: normal;
}
p {
margin: 0px 0px 15px 0px;
color: #4a4a4a;
font-weight: normal;
font-family: Arial,sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
#buttons {
margin: 10px 5px 0px 0px;
padding: 0px;
float: right;
}
.button {
display: inline-block;
margin: 0px;
padding: 2px 5px;
line-height: 20px;
text-align: center;
font-family: Officina, Calibri, Arial;
font-size: 14px;
display: inline-block;
cursor: pointer;
border: 1px solid #E30010;
margin-right: -5px;
}
#buttons .selected {
background: #ff0000;
color: #fff;
}
.button:hover {
background:#ff0000;
color: #fff;
cursor: pointer;
}
#header {
margin: 0px;
padding: 0px;
border: 1px solid #E11B17;
border-width: 2px 0px 0px 0px;
}
#block {
float: left;
margin: 0px;
padding: 0px;
height: 25px;
width: 10px;
background: #E11B17;
}
g.group text {
opacity: 0;
}
.scatter {
/*fill: #79d3f6;*/
/*stroke: #00a2d9;*/
stroke-width: 2;
opacity: 1;
}
.trendline {
fill: none;
stroke: #7b2713;
stroke-width: 2px;
opacity: 1;
}
div.tooltip {
position: absolute;
pointer-events: none;
margin: 0px;
padding: 7px;
background: #fff;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
border: 1px solid #ccc;
opacity: 0;
display: none;
}
.label {
/*display: none;*/
}
div.tooltip p, div.tooltip h2 {
margin: 0px;
padding: 0px;
font-size: 13px;
line-height: 1.2rem;
color: #000;
text-align: left;
font-family: Officina, Calibri, Arial;
font-size: 13px;
}
div.tooltip h2 {
margin: 0px;
padding: 0px 0px 5px 0px;
font-size: 14px;
}
#chart {
margin: 0px;
padding: 0px 0px 0px 20px;
}
#source {
margin: 0px 0px 0px 20px;
padding: 0px;
font-family: Officina, Calibri, Arial;
font-size: 14px;
color: #000;
}
.footnote{
font-family: Officina, Calibri, Arial;
font-size: 12px;
}
#select {
margin: 5px 0px 0px 20px;
}
@-moz-document url-prefix() {
.t-column {
margin: 0px -4px 0px 0px;
}
}
div#main-wrapper {
width: 200;
height: 200;
}
.baseline line {
stroke: #000000;
stroke-width: 2px
}
line.annotation{stroke:#999;}
#line-chart text.annotation,#line-chart .agehighlight text{font-family:'Inconsolata',Monaco,"Lucida Console",Consolas,"Courier New";font-size:14px;fill:#444;text-anchor:left;
}#line-chart .agehighlight text{fill:#000;font-weight:bold;text-transform:uppercase;}
#line-chart .agehighlight line{stroke:#000;stroke-width:2px;}
</style>
</head>
<body>
<div id="header">
<div id="block"></div>
<h1>Broadway</h1>
<h2>The success of Hamilton compared to your own show</h2>
<!-- <svg id="headerSVG" width="595" height="40"> -->
</div>
</div>
<div id="content">
<div id="main-wrapper">
<div id="controls">
<div class="sentence">Musical? </div>
<div id="kind" class="dropdown-wrapper", tabindex="0" style="float:left;z-index:20">
<span>kind</span>
<ul class="dropdown"></ul>
</div>
<div class="sentence">Starring </div>
<div id="actor" class="dropdown-wrapper", tabindex="1" style="float:left;z-index:20">
<span>Actor type</span>
<ul class="dropdown"></ul>
</div>
<div class="sentence">Genre </div>
<div id="genre" class="dropdown-wrapper", tabindex="2" style="float:left;z-index:20">
<span>Genre</span>
<ul class="dropdown"></ul>
</div>
<!-- 2nd line -->
<div class="sentence">Sold-out? </div>
<div id="kind" class="dropdown-wrapper", tabindex="0" style="float:left;z-index:10">
<span>Yes</span>
<ul class="dropdown"></ul>
</div>
<div class="sentence">Days-open? </div>
<div id="actor" class="dropdown-wrapper", tabindex="1" style="float:left;z-index:10">
<span>7 days</span>
<ul class="dropdown"></ul>
</div>
<div class="sentence">Original? </div>
<div id="genre" class="dropdown-wrapper", tabindex="2" style="float:left;z-index:10">
<span>Yes</span>
<ul class="dropdown"></ul>
</div>
<!-- 3rd line -->
<div class="sentence">Disney? </div>
<div id="kind" class="dropdown-wrapper", tabindex="0" style="float:left;z-index:10">
<span>No</span>
<ul class="dropdown"></ul>
</div>
<div class="sentence">Variable? </div>
<div id="actor" class="dropdown-wrapper", tabindex="1" style="float:left;z-index:10">
<span>Fill</span>
<ul class="dropdown"></ul>
</div>
<div class="sentence">Variable? </div>
<div id="genre" class="dropdown-wrapper", tabindex="2" style="float:left;z-index:10">
<span>Fill</span>
<ul class="dropdown"></ul>
</div>
<!-- Cast -->
<div class="sentence"> Cast-size</div>
<div id="cast">
<div id="ageslider" class="sliderholder"></div>
<div id="agevalue"></div>
</div>
</div>
<!-- end Controls -->
</div><!-- @end #main-wrapper -->
</div>
<div id="content">
<div id="main-wrapper">
<div id="footer">
<!-- results -->
<h1 width="500px" id="resultheading">Revenue prediction (in US$):</h1>
<h2 width="500px" id="resultVal"></h2>
</div>
<div id="container">
<div id="chart"></div>
<!-- <p id="source">Sources: OECD; Economist Intelligence Unit</p> -->
</div>
</div><!-- @end #main-wrapper -->
</div>
<script>
var margin = {top: 20, right: 80, bottom: 50, left: 90},
width = 595 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// var barChartHeight = 130;
var areaChartHeight = 500;
var tagColour = "#e11b17";
var colHighlighted = "#FD9D28";
var colUnhighlighted = "#dddddd";
var colourButtonOff = "#ffffff"; // white
var colourButtonOn = "#00699f"; // blue
var highlightColour = "#9a404f";
var colourTint = "#7fc9c7";
var p99Colour = "#3dbbd1";
var kind = {
"play": "Play",
"musical": "Musical",
}
var actor = { // 1
"AActor": "A-Actor",
"bActor": "B-Actor",
"cActor": "C-Actor",
};
var genre = { // 2
"comedy": "Comedy",
"drama": "Drama",
"other": "Other",
};
// currentCastSize // 3
var currentKind = "play";
var currentActor = "AActor";
var currentGenre = "comedy";
var currentCastSize = 50;
var currentKindID = 0,
currentActorID = 0,
currentGenreID = 0;
var result;
// kind dropdown menu
var dropdown_kind = d3.select("#controls #kind");
dropdown_kind.select("span").text(kind[currentKind]);
dropdown_kind.on("click", function() {
d3.select(this).classed("active", !d3.select(this).classed("active"));
});
var dropdown_kind_li = dropdown_kind.select(".dropdown").selectAll("li")
.data(d3.keys(kind))
.enter().append("li")
.attr("id", function(d) { return d; })
.classed("current", function(d) { return d == currentKind ? true : false; }).text(function(d) { return kind[d]; });
dropdown_kind_li.on("click", function(d, i) {
d3.select("#kind span").text(kind[d]);
d3.select(this).classed("current", true);
d3.select("#kind #" + currentKind).classed("current", false);
currentKind = d;
currentKindID = i;
// console.log(currentKindID)
// resetCounts();
update();
return currentKindID;
});
// Actor dropdown menu
var dropdown_actor = d3.select("#controls #actor");
dropdown_actor.select("span").text(actor[currentActor]);
dropdown_actor.on("click", function() {
d3.select(this).classed("active", !d3.select(this).classed("active"));
});
var dropdown_actor_li = dropdown_actor.select(".dropdown").selectAll("li")
.data(d3.keys(actor))
.enter().append("li")
.attr("id", function(d) { return d; })
.classed("current", function(d) { return d == currentActor ? true : false; }).text(function(d) { return actor[d]; });
dropdown_actor_li.on("click", function(d, i) {
d3.select("#actor span").text(actor[d]);
d3.select(this).classed("current", true);
d3.select("#actor #" + currentActor).classed("current", false);
currentActor = d;
currentActorID = i;
// console.log(currentActorID)
// resetCounts();
update();
return currentActorID;
});
// Genre dropdown menu
var dropdown_genre = d3.select("#controls #genre");
dropdown_genre.select("span").text(genre[currentGenre]);
dropdown_genre.on("click", function() {
d3.select(this).classed("active", !d3.select(this).classed("active"));
});
var dropdown_genre_li = dropdown_genre.select(".dropdown").selectAll("li")
.data(d3.keys(genre))
.enter().append("li")
.attr("id", function(d) { return d; })
.classed("current", function(d) { return d == currentGenre ? true : false; }).text(function(d) { return genre[d]; });
dropdown_genre_li.on("click", function(d, i) {
d3.select("#genre span").text(genre[d]);
d3.select(this).classed("current", true);
d3.select("#genre #" + currentGenre).classed("current", false);
currentGenre = d;
currentGenreID = i;
// console.log(currentGenreID)
// resetCounts();
update();
return currentGenreID;
});
var age_slider = d3.slider().min(0).max(100).ticks(0).stepValues(d3.range(0,100)).value(currentCastSize)
.callback(brushed);
d3.select("#ageslider").call(age_slider);
d3.select("#agevalue").text(currentCastSize);
var parseDate = d3.time.format("%m/%d/%Y").parse;
var x = d3.time.scale()
.range([0, width]);
var xA = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var yA = d3.scale.linear()
.domain([0, 1])
.range([height, 0]);
var color = d3.scale.ordinal().range(["#70C7DB", "#A15F7F"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(6)
.tickFormat(d3.time.format("%W"))
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickSize(-width)
.ticks(7);
var line = d3.svg.line()
.interpolate("step")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.temperature); });
var svg = d3.select("#chart").append("svg").classed("wrapper2", true)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
ageAnnotate(1.1,100, "Hamilton's success sticks out");
ageAnnotate(1.3,371, "Average income across 1040 shows is 652,079.9");
d3.csv("dataBW2.csv", function(error, data) {
if (error) throw error;
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; }));
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var cities = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {date: d.date, temperature: +d[name]};
})
};
});
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([
d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }),
d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); })
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Cumulative revenue, in $");
var city = svg.selectAll(".city")
.data(cities)
.enter().append("g")
.attr("class", "city");
city.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); })
.style("stroke-opacity", 0.7);
city.append("text")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")"; })
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) { return d.name; })
.style("fill", function(d) { return color(d.name); })
svg.append("g")
.attr("class", "baseline")
.attr("transform", "translate(0, "+ height +")")
.append("line")
.attr("x1", -20)
.attr("x2", width)
.attr("y2", 0)
});
var parseDate2 = d3.time.format("%m/%d/%Y").parse;
var dataNew = [];
var datafinal;
d3.csv("dateModel.csv", function (error, dataWeeks, results) {
// dataWeeks.forEach(function (d) {
// d = parseDate2(d)
// })
var results = 0;
dataWeeks.forEach(function(d, i) {
d.x2 = parseDate2(d.dateModel);
d.y2 = (results*i);
// dataNew.push({x2: parseDate2(d.dateModel),
// y2: (results*i)})
}); // end for map function
console.log(dataWeeks)
// x.domain(d3.extent(dataWeeks, function(d) { return d.x2; }));
// y.domain(d3.extent(dataWeeks, function(d) { return d.y2; }));
var line3 = d3.svg.line()
.interpolate("step")
.x(function(d) { return x(d.x2); })
.y(function(d) { return y(d.y2); });
var linegraph3 = svg.append("path")
.attr("class", "line3")
.attr('d', function(d){return line3(dataWeeks)})
.style("stroke", "#0C6290")
.style("fill", "none")
.style("stroke-width", 4)
.style("stroke-opacity", 0.7)
.attr("transform", "translate(0, -5)");
update(dataWeeks, line3)
})
function brushed () {
update();
currentCastSize = age_slider.value();
d3.select("#agevalue").text(currentCastSize)
return currentCastSize;
}
function ageAnnotate(year, Ypos, text) {
svg.append("line")
.attr("class", "annotation")
.attr("x1", 259)
.attr("x2", 259)
.attr("stroke-dasharray", "3,3")
.attr("y1", yA(0))
.attr("y2", yA(1));
svg.append("text")
.attr("class", "annotation")
.attr("transform", "translate("+xA((year-0.8))+","+Ypos+")rotate(-0)")
.text(text);
}
function update () {
var results = ((currentCastSize/5) + (currentGenreID*20) + (currentActorID*20) + (currentKindID*20)) * 100000;
d3.csv("dateModel.csv", function(error, dataUpdate) {
dataUpdate.forEach(function(d, i) {
d.x2 = parseDate2(d.dateModel);
d.y2 = (results*i);
});
var line3 = d3.svg.line()
.interpolate("step")
.x(function(d) { return x(d.x2); })
.y(function(d) { return y(d.y2); });
svg.select(".line3")
.transition()
.duration(750)
.attr('d', function(d){return line3(dataUpdate)});
d3.select('#resultVal')
.text(results);
return results;
// // Scale the range of the data again
// x.domain(d3.extent(data, function(d) { return d.date; }));
// y.domain([0, d3.max(data, function(d) { return d.close; })]);
// // Select the section we want to apply our changes to
// var svg = d3.select("body").transition();
// // Make the changes
// svg.select(".line") // change the line
// .duration(750)
// .attr("d", valueline(data));
// svg.select(".x.axis") // change the x axis
// .duration(750)
// .call(xAxis);
// svg.select(".y.axis") // change the y axis
// .duration(750)
// .call(yAxis);
});
}
</script>
</body>
Modified http://infographics.economist.com/js_libraries/infographic_mobile.js to a secure url
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js
https://infographics.economist.com/js_libraries/infographic_mobile.js
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js