|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> |
|
<style> |
|
body { |
|
margin:0px; |
|
} |
|
|
|
//Movie title---------- |
|
.label { |
|
font-size: 12pt; |
|
font-family: 'sans-serif'; |
|
alignment-baseline: middle; |
|
fill: #635F5D; |
|
} |
|
|
|
//Movie Gross---------- |
|
.costnumber { |
|
font-size: 12pt; |
|
font-family: 'sans-serif'; |
|
alignment-baseline: middle; |
|
fill: #000000; |
|
} |
|
.costbar { |
|
fill: #635F5D; |
|
} |
|
|
|
.subtitle { |
|
font-size: 25pt; |
|
fill: #635F5D; |
|
} |
|
.heading { |
|
font-size: 18pt; |
|
fill: #635F5D; |
|
} |
|
</style> |
|
</head> |
|
|
|
<body> |
|
<script> |
|
const width = 960; |
|
const height = 500; |
|
const margin = { |
|
left: 50, |
|
right: 100, |
|
top: 100, |
|
bottom: 30 |
|
} |
|
|
|
const innerWidth = width - margin.left - margin.right; |
|
const innerHeight = height - margin.top - margin.bottom; |
|
const labelWidth = 400; |
|
const DomWidth = 100; |
|
const DomPad = 69; |
|
const costWidth = innerWidth - (labelWidth + DomWidth + DomPad); |
|
|
|
const svg = d3.select("body").append("svg") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
|
|
//Headings----------------------------------------------------- |
|
svg.append('text') |
|
.attr('class', 'subtitle') |
|
.attr('x', margin.left) |
|
.attr('y', 50) |
|
.text('2017 Worldwide Box Office Gross'); |
|
|
|
svg.append('text') |
|
.attr('class', 'heading') |
|
.attr('x', margin.left ) |
|
.attr('y', 90) |
|
.text('Movie Title (Studio)'); |
|
|
|
svg.append('text') |
|
.attr('class', 'heading') |
|
.attr('x', margin.left + labelWidth) |
|
.attr('y', 90) |
|
.text('% Domestic'); |
|
|
|
svg.append('text') |
|
.attr('class', 'heading') |
|
.attr('x', margin.left + labelWidth + DomWidth + DomPad) |
|
.attr('y', 90) |
|
.text('Total Gross'); |
|
|
|
const g = svg.append('g') |
|
.attr('transform', `translate(${margin.left}, ${margin.top})`) |
|
|
|
|
|
//Data---------------------------------------------------------- |
|
// source: |
|
// http://www.boxofficemojo.com/yearly/chart/?view2=worldwide&yr=2017&p=.htm |
|
const data = [ |
|
{ |
|
rank: 1, |
|
name: "Beauty and the Beast", |
|
value: 1423, |
|
studio: "BV", |
|
per_dom: 0.399 |
|
}, |
|
{ |
|
rank: 2, |
|
name: "The Fate of the Furious", |
|
value: 1238, |
|
studio: "Uni", |
|
per_dom: 0.182 |
|
}, |
|
{ |
|
rank: 3, |
|
name: "Despicable Me 3", |
|
value: 1007, |
|
studio: "Uni", |
|
per_dom: 0.258 |
|
}, |
|
{ |
|
rank: 4, |
|
name: "Guardians of the Galaxy Vol 2", |
|
value: 863, |
|
studio: "BV", |
|
per_dom: 0.451 |
|
}, |
|
{ |
|
rank: 5, |
|
name: "Wolf Warrior 2", |
|
value: 852, |
|
studio:"HC", |
|
per_dom: 0.003 |
|
|
|
}, |
|
{ |
|
rank: 6, |
|
name: "Spider-Man: Homecoming", |
|
value: 823, |
|
studio: "Sony", |
|
per_dom: 0.398 |
|
}, |
|
{ |
|
rank: 7, |
|
name: "Wonder Woman", |
|
value: 816, |
|
studio: "WB", |
|
per_dom: 0.503 |
|
}, |
|
{ |
|
rank: 8, |
|
name: "Pirates of the Caribbean: Dead Men Tell No Tales", |
|
value: 793, |
|
studio: "WB", |
|
per_dom: 0.503 |
|
}, |
|
{ |
|
rank: 9, |
|
name: "Logan", |
|
value: 616, |
|
studio: "Fox", |
|
per_dom: 0.367 |
|
}, |
|
{ |
|
rank: 10, |
|
name: "Transformers: The Last Knight", |
|
value: 605, |
|
studio: "Fox", |
|
per_dom: 0.215 |
|
} |
|
]; |
|
|
|
|
|
const cost = d => d.value; |
|
const per_dom = d => d.per_dom; |
|
//const country = d => d.studio; |
|
//const continent = d => d.continent; |
|
const studio = d => d.studio; |
|
const rank = d => d.rank; |
|
const yValue = d => d.name; |
|
|
|
const costXScale = d3.scaleLinear() |
|
.domain([0, d3.max(data, cost)]) |
|
.range([0, costWidth]); |
|
|
|
const magXScale = d3.scaleLinear() |
|
.domain([0, d3.max(data, per_dom)]) |
|
.range([0, DomWidth]); |
|
|
|
const yScale = d3.scaleBand() |
|
.domain(data.map(yValue).reverse()) |
|
.range([innerHeight, 0]) |
|
.padding(0.272); |
|
|
|
const continentColor = d3.scaleOrdinal(d3.schemeDark2); |
|
|
|
const groups = g.selectAll('g').data(data); |
|
|
|
const labelGroup = groups |
|
.enter().append('g') |
|
.attr('transform', d => `translate(0, ${yScale(yValue(d))})`); |
|
|
|
// rank ------------------------------------ |
|
labelGroup |
|
.append('text') |
|
.attr('class', 'label') |
|
.attr('x', 0) |
|
.attr('y', yScale.bandwidth() / 2) |
|
.text(d => `${rank(d)} -`); |
|
|
|
// name ------------------------------------- |
|
labelGroup |
|
.append('text') |
|
.attr('class', 'label') |
|
.attr('x', 25) |
|
.attr('y', yScale.bandwidth() / 2) |
|
// .attr('fill', d => continentColor(continent(d))) |
|
.text(d => `${yValue(d)} (${studio(d)})`); |
|
|
|
const magGroup = groups |
|
.enter().append('g') |
|
.attr('transform', d => `translate(${labelWidth} ${yScale(yValue(d))})`); |
|
|
|
//Domestic Gross----------------------------------- |
|
magGroup |
|
.append('rect') |
|
.attr('class', 'magbar') |
|
.attr('width', d => magXScale(per_dom(d))) |
|
.attr('height', yScale.bandwidth()) |
|
// .attr('fill', d => continentColor(continent(d))); |
|
|
|
magGroup |
|
.append('text') |
|
.attr('class', 'magnumber') |
|
.attr('x', d => magXScale(per_dom(d)) + 8) |
|
.attr('y', yScale.bandwidth() / 2) |
|
// .attr('fill', d => continentColor(continent(d))) |
|
.text(d => per_dom(d).toFixed(2)*100); |
|
|
|
|
|
// Total Gross Graph----------------------------- |
|
const costGroup = groups |
|
.enter().append('g') |
|
.attr('transform', d => `translate(${labelWidth + DomWidth + DomPad}, ${yScale(yValue(d))})`); |
|
|
|
costGroup |
|
.append('rect') |
|
.attr('class', 'costbar') |
|
.attr('width', d => costXScale(cost(d))) |
|
.attr('height', yScale.bandwidth()) |
|
// .attr('fill', d => continentColor(continent(d))); |
|
|
|
costGroup |
|
.append('text') |
|
.attr('class', 'costnumber') |
|
.attr('x', d => costXScale(cost(d)) + 8) |
|
.attr('y', yScale.bandwidth() / 2) |
|
// .attr('fill', d => continentColor(continent(d))) |
|
.text(d => `\$${cost(d)} M`); |
|
|
|
</script> |
|
</body> |