Public
Edited
Jul 24, 2022
1 star
Insert cell
Insert cell
coloursGraph = {
// get data
//const width = 1200;
//const height = width;

const c = DOM.context2d(width, height);
c.translate(0, 0);

function animate() {
c.fillStyle = "white"
c.fillRect(0, 0, width, height); // make sure to clear or fill the rect
for (const { xPos, yPos, col } of dataToPlot) {
c.beginPath();
c.rect(xPos, yPos, xScale.bandwidth(), 2)
c.fillStyle = col
c.fill()
}
}

animate()

yield c.canvas;
}
Insert cell
studiosGraph = {
// get data
// const width = 700;
// const height = 1000;

const c = DOM.context2d(width, height);
c.translate(0, 0);

function animate() {
c.fillStyle = "white"
c.fillRect(0, 0, width, height); // make sure to clear or fill the rect
for (const { xPos, yPos, col } of dataToPlotStudios) {
c.beginPath();
c.rect(xPos, yPos, xScale.bandwidth()*5, 10)
c.fillStyle = col
c.fill()
}
}

animate()

yield c.canvas;
}
Insert cell
Insert cell
// 5. Create the final data to be polotted
// Including the coordinates and fill of each 'point' where each point is one anime
dataToPlot = {
const dataToPlot = []
groupedData.forEach(yearEntry => {
const year = yearEntry.year // year or decade
const animes = yearEntry.animes
const numAnimes = yearEntry.animes.length
animes.forEach((anime, i) => {
const xPos = xScale(year)
const yPos = yScale(i)
dataToPlot.push({
year: year,
col: anime.col,
xPos: xPos,
yPos: yPos
})
})
})
return dataToPlot
}
Insert cell
// 5. Create the final data to be polotted
// Including the coordinates and fill of each 'point' where each point is one anime
dataToPlotStudios = {
const dataToPlot = []
groupedDataStudios.forEach(yearEntry => {
const studio = yearEntry.studio
const animes = yearEntry.animes
const numAnimes = yearEntry.animes.length
animes.forEach((anime, i) => {
const xPos = xScaleStudios(studio)
const yPos = yScaleStudios(i)
dataToPlot.push({
studio: studio,
col: anime.col,
xPos: xPos,
yPos: yPos
})
})
})
return dataToPlot
}
Insert cell
xScale = d3.scaleBand()
.domain(groupedData.map(d => d.year)) // year or decade
.range([0, width])
Insert cell
xScaleStudios = d3.scaleBand()
.domain(groupedDataStudios.map(d => d.studio))
.range([0, width])
Insert cell
yScale = d3.scaleLinear()
.domain([0, d3.max(groupedData, d => d.animes.length)])
.range([height, 0])
Insert cell
yScaleStudios = d3.scaleLinear()
.domain([0, d3.max(groupedDataStudios, d => d.animes.length)])
.range([height, 0])
Insert cell
// 4. sort the colour values inside of each year-group (don't think that works)
// groupedData.forEach(d => {
// _.sortBy(d.animes, e => e.colRGB[0])
// })
Insert cell
// 3. Group the data by year
groupedData = _.chain(data)
.groupBy("air_year") // decade or year
.map((value, key) => ({ year: +key, animes: value }))
.value()
Insert cell
groupedDataStudios = _.chain(dataCol3StudiosSorted)
.groupBy("studio")
.map((value, key) => ({ studio: key, animes: value }))
.value()
Insert cell
dataCol3Studios
Insert cell
dataCol3StudiosSorted = _.sortBy(dataCol3Studios, d => [d.colHSL[0], d.colRGB[1]])
Insert cell
// 2. Sort all the data by appropriate col value and filter years
data = _.sortBy(dataCol3, d => [d.colHSL[2], d.colRGB[1]]).filter(d => +d.air_year >= 1980 & +d.air_year <= 2020)
Insert cell
dataCol1 = dataCol1Raw
Insert cell
// 1. Create RGB and HSL values entries for each anime
dataCol3.forEach(anime => {
anime.col = anime.colours[0]
const rgb = anime.colours[0].split('rgb(')[1].split(')')[0].split(', ')
anime.colRGB = [+rgb[0], +rgb[1], +rgb[2]]
anime.colHSL = rgbToHsl(+rgb[0], +rgb[1], +rgb[2])
})
Insert cell
dataCol3Studios
Insert cell
dataCol3Studios.forEach(anime => {
anime.col = anime.colours[0]
const rgb = anime.colours[0].split('rgb(')[1].split(')')[0].split(', ')
anime.colRGB = [+rgb[0], +rgb[1], +rgb[2]]
anime.colHSL = rgbToHsl(+rgb[0], +rgb[1], +rgb[2])
})
Insert cell
dataCol1Raw
Insert cell
// 1. Create RGB and HSL values entries for each anime
dataCol1Raw.forEach(anime => {
anime.decade = getDecade(new Date(String(anime.air_year)))
anime.col = anime.colours[0]
const rgb = anime.colours[0].split('rgb(')[1].split(')')[0].split(', ')
anime.colRGB = [+rgb[0], +rgb[1], +rgb[2]]
anime.colHSL = rgbToHsl(+rgb[0], +rgb[1], +rgb[2])
})
Insert cell
getDecade(new Date('2001'))
Insert cell
function getDecade(date) {
return (Math.floor(date.getFullYear() / 10) * 10);
}
Insert cell
// 0. Just for the 3-colour version - Unroll the data where there are 3 colours per anime
dataCol3 = {
const dataCol3 = []
dataCol3Raw.forEach(d => {
const colours = d.colours
colours.forEach(c => {
dataCol3.push({
img: d.img,
air_year: d.air_year,
colours: [c]
})
})
})
return dataCol3
}
Insert cell
// 0. Just for the 3-colour version - Unroll the data where there are 3 colours per anime - for the studios data
dataCol3Studios = {
const dataCol3Studios = []
studios.forEach(d => {
const colours = d.colours
colours.forEach(c => {
dataCol3Studios.push({
img: d.img,
studio: d.studio,
colours: [c]
})
})
})
return dataCol3Studios
}
Insert cell
dataCol1Raw = FileAttachment("posters_all_1col.json").json({typed: true})
Insert cell
dataCol3Raw = FileAttachment("posters_all_3col.json").json({typed: true})
Insert cell
studios = [...pixar, ...disney, ...ghibli]
Insert cell
pixar.forEach(d => d.studio = 'pixar')
Insert cell
pixar = FileAttachment("posters_pixar_3col.json").json({typed: true})
Insert cell
disney.forEach(d => d.studio = 'disney')
Insert cell
disney = FileAttachment("posters_disney_3col.json").json({typed: true})
Insert cell
ghibli.forEach(d => d.studio = 'ghibli')
Insert cell
ghibli = FileAttachment("posters_ghibli_3col@1.json").json({typed: true})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more