Created
September 14, 2020 00:18
-
-
Save lvngd/a6aa2405f9cc13f085ed3916fbe02fc2 to your computer and use it in GitHub Desktop.
D3.js code for https://www.instagram.com/p/CE_4mWmgnpJ/
This file contains hidden or 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> | |
<meta charset="utf-8"> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v4.js"></script> | |
<link href="https://fonts.googleapis.com/css?family=Kanit:400,700&display=swap" rel="stylesheet"> | |
</head> | |
<body> | |
<div id='tgif-container'> | |
<div id="tgif-chart"></div> | |
</div> | |
</body> | |
<script> | |
var drawGraph = function(data){ | |
var fontFamily = "Kanit"; | |
var svgBackgroundColor = "#391e49"; | |
var barColor = "#449756"; | |
var axisTitleColor = '#e8ab35'; | |
var titleFontColor = '#93f2b0'; | |
var additionalShowFontSize = "2em"; | |
//sidebar text colors to alternate for shows list | |
var color1 = "#FEFFA5"; | |
var color2 = "#efefef"; | |
//get list of shows - used to create y-axis | |
var nodes = d3.map(data, function(d,i){return d.show;}).keys(); | |
var parsedData = data.map(function(d){ | |
var startDate = new Date(d.start_date,0,1); | |
var endDate = new Date(d.end_date,0,1); | |
var dataObject = | |
{ | |
show: d.show, | |
start: startDate, | |
image: d.image, | |
end: endDate | |
}; | |
return dataObject; | |
}); | |
//size of the container div | |
d3.select("#tgif-chart") | |
.style("width", "400px") | |
.style("height", "400px"); | |
const margin = {top: 20, left: 0, bottom: 170, right: 400}, | |
width = 2100-margin.left-margin.right, | |
height = 2100-margin.top-margin.bottom; | |
/* draw the SVG */ | |
var svg = d3.select("#tgif-chart") | |
.append('div') | |
.classed('svg-container', true) | |
.append('svg') | |
.attr("preserveAspectRatio", "xMinYMin meet") | |
.attr("viewBox", "0 0 2100 2100") | |
.classed('svg-content-responsive', true) | |
.style('background-color', svgBackgroundColor) | |
.append('g'); | |
svg | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
/* setup x and y axis scales */ | |
var x = d3.scaleTime().range([470,width]); | |
var y = d3.scaleBand().range([height,0]) | |
.padding(.13); | |
var minDate = d3.min(parsedData.map((d) => {return d.start;})); | |
var maxDate = d3.max(parsedData.map((d) => {return d.end;})); | |
x.domain([minDate,maxDate]); | |
y.domain(nodes); | |
var xAxis = d3.axisBottom(x).tickFormat(function(d){return d3.timeFormat('%Y')(d);}).tickSize(-height); | |
var yAxis = d3.axisLeft(y); | |
var xxAxis = svg.append('g') | |
.classed('axis--x', true) | |
.call(xAxis) | |
.style("font-size", "3.3em") | |
.style("font-weight", "bold") | |
.style("font-family", fontFamily) | |
.attr("transform", "translate(0," + (height+30) + ")"); | |
/* | |
draw the bars | |
basically the way this works is that we have the x-axis of date-years, and | |
when you create a D3.js axis scale, you can use it to calculate where in the SVG | |
something should go. | |
y-axis = the show names | |
x-axis = the years | |
so for each show, the rectangle is drawn next to its image, and the width of the rectangle is calculated by subtracting the start date from the end date | |
*/ | |
var rangeBars = svg.selectAll("g bars") | |
.data(parsedData); | |
var barEnter = rangeBars | |
.enter() | |
.append("g"); | |
var bars = barEnter | |
.append("rect") | |
//get starting x coordinate from the x-axis scale | |
.attr("x", function(d){return x(d.start);}) | |
//get starting y coordinate from y-axis scale | |
.attr("y", function(d){return y(d.show);}) | |
//calculating the rectangle width | |
.attr("width", function(d){var w = x(d.end) - x(d.start); return w;}) | |
.attr("height", y.bandwidth()) | |
.attr("fill", barColor); | |
/* add the y-axis images for the shows */ | |
var node = svg.selectAll("g nodes") | |
.data(parsedData); | |
var nodeEnter = node | |
.enter() | |
.append("g"); | |
var image = nodeEnter.append("image") | |
.attr("xlink:href", function(d){return d.image;}) | |
.attr("x", function(d,i){return 35;} | |
) | |
.attr("y", function(d){return y(d.show);}) | |
.attr("width", 390) | |
.attr("height", 170); | |
/* styling the axis */ | |
d3.selectAll('.tick').selectAll('text') | |
.style('fill', axisTitleColor) | |
.style('font-family', fontFamily); | |
d3.selectAll('.axis--x').selectAll('line') | |
.style('stroke',axisTitleColor) | |
.style('stroke-width', 5) | |
.attr('opacity', 0.1); | |
d3.selectAll('.axis--x').selectAll('.domain').remove(); | |
d3.selectAll('.axis--x').selectAll('text') | |
.attr("transform", "rotate(-40)"); | |
/* | |
everything below this comment is for the sidebar with the list of additional shows and their year ranges | |
*/ | |
var additionalShowYears = {"Going Places": "1990-1991", | |
"Billy": "1991-1992", | |
"Where I live": "1992-1993", | |
"Camp Wilder": "1992-1993", | |
"Getting By": "1992-1993", | |
"On Our Own": "1994-1995", | |
"Aliens In The Family": "1995-1996", | |
"Muppets Tonight": "1995-1996", | |
"Clueless": "1996-1997", | |
"Teen Angel": "1997-1998", | |
"You Wish": "1997-1998", | |
"Brother's Keeper": "1998-1999", | |
"TGAGAAPP*": "1998-1999", | |
"Two of a Kind": "1998-1999", | |
"The Hughley's": "1999-2000", | |
"Making the Band": "1999-2000", | |
"Odd Man Out": "1999-2000"}; | |
var sidebarText = svg.append("g").attr("transform", "rotate(-90) translate(-1730,2090)"); | |
sidebarText | |
.append("text") | |
.attr("y", 0) | |
.attr("x", 0) | |
.text("Two Guys, a Girl and a Pizza Place*") | |
.style("font-size", "1.6em") | |
.style("font-family", fontFamily) | |
.attr("opacity", 0.8) | |
.attr("fill", color1); | |
/* add title */ | |
var title = svg.append("g").attr("transform", "translate(1750,140)"); | |
title | |
.append("text") | |
.attr("y", 0) | |
.attr("x", 0) | |
.text("TGIF") | |
.style("font-size", "10em") | |
.style("font-weight", 700) | |
.style("font-family", fontFamily) | |
.attr("fill", titleFontColor) | |
.attr('opacity', 0.9); | |
title | |
.append("text") | |
.attr("y", 80) | |
.attr("x", 20) | |
.text("Original") | |
.style("font-size", "3em") | |
.style("font-weight", "bold") | |
.style("font-family", fontFamily) | |
.attr("fill", titleFontColor) | |
.attr('opacity', 0.9); | |
title | |
.append("text") | |
.attr("y", 130) | |
.attr("x", 20) | |
.text("Lineup") | |
.style("font-size", "3em") | |
.style("font-weight", "bold") | |
.style("font-family", fontFamily) | |
.attr("fill", titleFontColor); | |
//rectangle background for sidebar with list of shows | |
var sideBlock = svg.append("g") | |
.append("rect") | |
.attr("x", 1735) | |
.attr("y",-50) | |
.attr("width", 400) | |
.attr("height", 1930) | |
.attr("fill", "#ccc") | |
.attr("opacity", 0.2); | |
/* sidebar list of shows */ | |
var shows = svg.append("g").attr("transform", "translate(1775,370)"); | |
var translateY = 0; | |
var count = 0; | |
/* write each show name and date range in side bar */ | |
for(showName in additionalShowYears){ | |
var t = shows | |
.append("g") | |
.attr("transform", `translate(0,${translateY})`); | |
t | |
.append("text") | |
.attr("y",0) | |
.attr("x",0) | |
.text(showName) | |
.style("font-size", additionalShowFontSize) | |
.style("font-family", fontFamily) | |
.style("fill", count%2 == 0 ? color1 : color2) | |
.attr('opacity', 0.8); | |
t | |
.append("text") | |
.attr("y",35) | |
.attr("x",0) | |
.text(additionalShowYears[showName]) | |
.style("font-size", additionalShowFontSize) | |
.style("font-family", fontFamily) | |
.style("fill", (count%2) == 0 ? color1 : color2) | |
.attr('opacity', 0.6); | |
count = count + 1; | |
translateY = translateY + 85; | |
} | |
} | |
d3.json("tgif.json",function(error,data){ | |
drawGraph(data); | |
}); | |
</script> | |
</html> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment