Published
Edited
Dec 20, 2020
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

{
const lostYearsTmp = d3.shuffle(lostYears)

const cellSize = width / 12 - 4 * 11;
const div = d3.create("div").attr('width', width).attr('id', 'myGrid')
.attr('style', 'display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;grid-gap:4px;')

const cellHeight = 70;

const cells = div.selectAll('div').data(lostYearsTmp.slice(0, 100).join('div')
.style('height', `${cellHeight}px`)
.style('border-bottom', '2px solid rgba(0,0,0,0.6)')
.style('position', 'relative')
.style('margin', '0 8px')

const yScale = d3.scaleLinear().domain([0,111]).range([0, cellHeight])
const flameScale = d3.scaleLinear().domain([0,111]).range([25, 10])
const haloScale = d3.scaleLinear().domain([0,111]).range([75, 30])

const wickHeight = 6;

cells.each(function(d, i) {
const elem = d3.select(this).datum(d);
// halo
elem
.append('div')
.style('position', 'absolute')
.style('bottom', d => `${yScale(d.lostYears) - 4}px`)
.style('height', d => `${haloScale(d.age)}px`)
.style('width', d => `${haloScale(d.age)}px`)
.style('background-color', 'rgba(255, 215, 0, 0.1)')
.style('border-radius', '50% 50% 50% 50%')
.style('border', '1px solid rgba(255, 215, 0, 0.5)')
.style('left', '50%')
.style('transform', 'translateX(-50%)')
// candle
elem
.append('div')
.style('position', 'absolute')
.style("bottom", "-1px")
.style("left", "50%")
.style('height', `${yScale(d.lostYears)}px`)
.style('width', '12px')
.style('background', 'white')
.style('border', '1px solid rgba(0,0,0,0.4)')
.style('border-radius', '4px 4px 0 0')
.style("transform", "translate(-50%)")

// text
elem
.append('div')
.style('position', 'absolute')
.style("bottom", "-4px")
.style("right", "0px")
.style('z-index', '2')
.html(d => d.age);

// orange/yellow flame
const rand = getRandomInt(15, 20);
elem
.append('div')
.style('position', 'absolute')
.style('bottom', d => `${yScale(d.lostYears) + wickHeight + 2}px`)
.style('height', d => `${flameScale(d.age)}px`)
.style('width', `${flameScale(d.age)}px`)
.style('border-radius', '0 50% 50% 50%')
.style('left', '50%')
.style('transform-origin', 'bottom center')
.style('transform', 'translateX(-79%) rotate(35deg) skewY(30deg)')
.style('box-shadow', `inset 0 7px 12px -2px rgba(255, 255, 100, 1), inset 0 9px 57px -3px rgba(255,0,0,0.2), inset 0 -5px 8px 2px rgba(0,0,0,0.4), 0 0 3px 0px rgba(226, 88, 34, 0.8)`);



// wick
elem
.append('div')
.style('position', 'absolute')
.style('z-index', '10')
.style('bottom', d => `${yScale(d.lostYears) + 1}px`)
.style('height', `${wickHeight}px`)
.style('width', '3px')
.style('background-color', 'rgba(0,0,0,0.6)')
.style('left', '50%')
.style('transform', 'translateX(-50%)');


// orange flame
elem
.append('div')
.style('position', 'absolute')
.style('z-index', '1')
.style('bottom', d => `${yScale(d.lostYears) + wickHeight}px`)
.style('height', d => `${flameScale(d.age) * 0.66}px`)
.style('width', d => `${flameScale(d.age) * 0.66}px`)
.style('background-color', 'rgba(226, 88, 34, 0.8')
.style('border-radius', '0 50% 50% 50%')
.style('left', '50%')
.style('transform', 'translateX(-50%) rotate(45deg)');

// light blue flame
elem
.append('div')
.style('position', 'absolute')
.style('z-index', '2')
.style('bottom', d => `${yScale(d.lostYears) + + wickHeight}px`)
.style('height', d => `${flameScale(d.age) * 0.5}px`)
.style('width', d => `${flameScale(d.age) * 0.5}px`)
.style('background-color', 'rgba(73, 162, 186, 0.7)')
.style('border-radius', '0 50% 50% 50%')
.style('left', '50%')
.style('transform', 'translateX(-50%) rotate(45deg)');

// blue flame
elem
.append('div')
.style('position', 'absolute')
.style('z-index', '3')
.style('bottom', d => `${yScale(d.lostYears) + wickHeight}px`)
.style('height', d => `${flameScale(d.age) * 0.33}px`)
.style('width', d => `${flameScale(d.age) * 0.33}px`)
.style('background-color', 'rgba(48, 83, 125, 0.8)')
.style('border-radius', '0 50% 50% 50%')
.style('left', '50%')
.style('transform', 'translateX(-50%) rotate(45deg)');
})


return div.node();
}
Insert cell
import {vl} from "@vega/vega-lite-api"

Insert cell
Insert cell
d3 = require('d3')
Insert cell
embed = require("vega-embed")
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