Public
Edited
Aug 29, 2023
3 forks
Importers
7 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
colorScale = d3.scaleOrdinal( d3.schemeSet2 )
Insert cell
Insert cell
hierarchy = {
const dataCopy = JSON.parse( JSON.stringify( data ) )

return d3.hierarchy( dataCopy )
.sum(d => d.value)
.sort((a, b) => b.value - a.value)
}
Insert cell
Insert cell
treemap = d3.treemap()
// set the size of the treemap render area
.size([ width, height ])
// set the padding between every rectangle in px
.padding(2)
// set the padding at the top of each group of rectangles
// so that we can fit the country labels
.paddingTop(10)
// Set the generator to round pixel values to the nearest value
// (makes things look better)
.round(true)
Insert cell
Insert cell
root = treemap( hierarchy )
Insert cell
chart = {

const svg = d3.create('svg')
.style('font-family', 'sans-serif')
.attr('width', width)
.attr('height', height)

const g = svg.append('g')
.attr('class', 'treemap-container')
// Place the labels for our countries
g.selectAll('text.country')
// The data is the first "generation" of children
.data( root.children )
.join('text')
.attr('class', 'country')
// The rest is just placement/styling
.attr('x', d => d.x0)
.attr('y', d => d.y0)
.attr('dy', '0.6em')
.attr('dx', 3)
.style('font-size', 12)
// Remember, the data on the original node is available on node.data (d.data here)
.text(d => d.data.name)
// Now, we place the groups for all of the leaf nodes
const leaf = g.selectAll('g.leaf')
// root.leaves() returns all of the leaf nodes
.data(root.leaves())
.join('g')
.attr('class', 'leaf')
// position each group at the top left corner of the rect
.attr('transform', d => `translate(${ d.x0 },${ d.y0 })`)
.style('font-size', 10)

// A title element tells the browser to display its text value
// in a popover when the cursor is held over a rect. This is a simple
// way to add some interactivity
leaf.append('title')
.text(d => `${ d.parent.data.name }-${ d.data.name }\n${ d.value.toLocaleString() + ' GWh' }`)

// Now we append the rects. Nothing crazy here
leaf.append('rect')
.attr('fill', d => colorScale(d.parent.data.name))
.attr('opacity', 0.7)
// the width is the right edge position - the left edge position
.attr('width', d => d.x1 - d.x0)
// same for height, but bottom - top
.attr('height', d => d.y1 - d.y0)
// make corners rounded
.attr('rx', 3)
.attr('ry', 3)

// This next section checks the width and height of each rectangle
// If it's big enough, it places labels. If not, it doesn't.
leaf.each((d, i, arr) => {
// The current leaf element
const current = arr[i]
const left = d.x0,
right = d.x1,
// calculate its width from the data
width = right - left,
top = d.y0,
bottom = d.y1,
// calculate its height from the data
height = d.y1 - d.y0

// too small to show text
const tooSmall = width < 34 || height < 25
// and append the text (you saw something similar with the pie chart (day 6)
const text = d3.select( current ).append('text')
// If it's too small, don't show the text
.attr('opacity', tooSmall ? 0 : 0.9)
.selectAll('tspan')
.data(d => [ d.data.name, d.value.toLocaleString() ])
.join('tspan')
.attr('x', 3)
.attr('y', (d,i) => i ? '2.5em' : '1.15em')
.text(d => d)

})
return svg.node();

}
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