Published
Edited
Oct 17, 2021
Insert cell
Insert cell
// viewof cols = Inputs.range([1, 8], {step: 1 , label: "tree per row"})
Insert cell
Insert cell
Insert cell
Insert cell
china_tree = {
const country_width = width
//create canvas
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, country_width])
.style("font", "10px sans-serif");

// hierarchy = root -> 3 groups -> 8 sections
const root = treemap(country_nested, country_width )
console.log(root)
// console.log(root.leaves())

// .leaves() 提取了8个section各自的array
//定位section's starting points
const leaf = svg.selectAll("g")
.data(root.leaves())
.join("g")
.attr("transform", d => `translate(${d.x0},${d.y0})`);

//draw sections
leaf.append("rect")
.attr("fill", d => color(d.data.key))
.attr("fill-opacity", .95)
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0);

return svg.node();
}
Insert cell
// draw in one svg
chart_all_provinces = {
// min width of each tree = 150
const chart_with = 250

//align width with responsive css
// const container_width = width < 800 ? width: width > 1200? width - 800: width-500
const container_width = width < 700 ? width: width > 1300? width - 800: width-400
const chart_gap_x = 20
const chart_gap_y = chart_gap_x * 1.2
const cols = Math.floor( container_width / ( chart_width + chart_gap) )
const label_height = 30
//create svg
const svg = d3.create("svg")
.attr("viewBox", [0, 0, container_width, (chart_width + chart_gap_y) * (Math.ceil( 32 / cols) )])
.style("font", "10px sans-serif");

const chart_offset = ( container_width - (cols * chart_width + ( cols - 1 )* chart_gap ) ) / 2
//prepare the starting point of each tree
const all_trees = svg.selectAll('g')
.data(provinces_nested)
.join('g')
//temp column = 6
.attr('transform', (d, i) => `translate(${Math.floor(i % cols) * (chart_width + chart_gap) + chart_offset }, ${Math.floor(i / cols) * (chart_width + chart_gap_y)})`)

//prepare the starting point of each rect in a tree
const leaf = all_trees.selectAll('g')
.data(d => treemap(d, chart_width).leaves())
.join('g')
.attr("transform", d => `translate(${d.x0},${d.y0 + label_height})`);

// console.log(provinces_nested)
//draw treemaps
leaf.append('rect')
.attr("fill", d => color(d.data.key))
.attr("fill-opacity", .95)
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0);

//label: region
const region_name = all_trees
.append('text')
.attr("x", 2)
.attr('y', label_height-5)
.attr('font-size', 12)
.attr('font-weight', 'bold')
.attr('fill', '#666666')
.text( d => `${d.key}`);
return svg.node()
}



Insert cell
//grouping by province
provinces_nested = d3.nest()
.key(d => d.region).sortKeys(d3.ascending)
.key(d => d.type).sortKeys(d3.ascending)
.key(d => d.section).sortKeys(function(a,b) { return section_order.indexOf(a) - section_order.indexOf(b); })
.rollup(v => d3.sum(v, d => d.area) )
.entries(dProvinces)
Insert cell
// country_nested = d3.nest()
// .key(d => d.region).sortKeys(d3.ascending)
// .key(d => d.type).sortKeys(d3.ascending)
// .key(d => d.section).sortKeys((a, b) => section_order.indexOf(a) - section_order.indexOf(b))
// .rollup(v => d3.sum(v, d => d.area) )
// .entries(dCountry)

//👆这个只能画出一个rect
country_nested =
({ name: 'root',
values: d3.nest()
.key(d => d.type).sortKeys(d3.ascending)
.key(d => d.section).sortKeys((a, b) => section_order.indexOf(a) - section_order.indexOf(b))
.rollup(v => d3.sum(v, d => d.area) )
.entries(dCountry)
})
Insert cell
treemap = (data, w) => d3.treemap()
.tile(d3.treemapSliceDice)
.size([w, w])
.padding(0.5)
.round(true)
(d3.hierarchy(data, d => d.values)
.sum(d => d.value)
)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more