Published
Edited
Mar 27, 2019
3 stars
Insert cell
Insert cell
config = ({ padding: {left: 6, right: 6, top: 20, bottom: 6}, vAlign: 'bottom',
margin: {left: 2, right: 2, top: 6, bottom: 0}, edgeMargins: false,
minContSize: {width: 40, height: 40}, maxLineWidth: width})
Insert cell
chart = {
const svgW = (root.x1 - root.x0);
const svgH = (root.y1 - root.y0);
const svg = d3.select(DOM.svg(svgW, svgH))
.attr('width','100%')
.attr('height','auto')
.style('font', '10px sans-serif');
const chart = svg.append('g')

const shadow = DOM.uid('shadow');

chart.append('filter')
.attr('id', shadow.id)
.append('feDropShadow')
.attr('flood-opacity', 0.3)
.attr('dx', 0)
.attr('stdDeviation', 3);

const node = chart.selectAll('g')
.data(d3.nest().key(d => d.height).entries(root.descendants()))
.join('g')
.attr('filter', shadow)
.selectAll('g')
.data(d => d.values)
.join('g')
.attr('transform', d => `translate(${d.x0},${d.y0})`);

node.append('title')
.text(d => `${d.ancestors().reverse().map(d => d.data.name).join('/')}\n${format(d.value)}`);

node.append('rect')
.attr('id', d => (d.nodeUid = DOM.uid('node')).id)
.attr('fill', d => color(d.height))
.attr('width', d => d.x1 - d.x0)
.attr('height', d => d.y1 - d.y0);

node.append('clipPath')
.attr('id', d => (d.clipUid = DOM.uid('clip')).id)
.append('use')
.attr('xlink:href', d => d.nodeUid.href);

node.append('text')
.attr('clip-path', d => d.clipUid)
.selectAll('tspan')
.data(d => d.data.name.split(/(?=[A-Z][^A-Z])/g).concat(format(d.value)))
.join('tspan')
.attr('fill-opacity', (d, i, nodes) => i === nodes.length - 1 ? 0.7 : null)
.text(d => d);

node.filter(d => d.children).selectAll('tspan')
.attr('dx', 3)
.attr('y', 13);

node.filter(d => !d.children).selectAll('tspan')
.attr('x', 3)
.attr('y', (d, i, nodes) => `${(i === nodes.length - 1) * 0.3 + 1.1 + i * 0.9}em`);

const container = document.createElement('div');
container.setAttribute('style','overflow: scroll;');
container.appendChild(svg.node());
return container;
}
Insert cell
data = d3.json("https://raw.githubusercontent.com/d3/d3-hierarchy/v1.1.8/test/data/flare.json")
Insert cell
layout = data => boxmodel()
.vAlign(config.vAlign)
.edgeMargins(config.edgeMargins)
.spanHeight(d => false)
.isContainer(d => {
// return true; //
return !d.data.hasOwnProperty('value');
})
.padding(d => {
let p = Object.assign({}, config.padding);
return p;
})
.margin(d => {
let m = Object.assign({}, config.margin);
return m;
})
.minContainerSize(d => {
let w = config.minContSize.width;
let h = config.minContSize.height;
return {width: w, height: h};
})
.maxLineWidth(d => {
let w = config.maxLineWidth;
return w;
})
.nodeSize(d => {
let w = 0, h = 0;
if (d.data.hasOwnProperty('value')) {
w = Math.sqrt(d.data.value);
h = Math.sqrt(d.data.value);
}
return {width: w, height: h};
})
(d3.hierarchy(data)
.sum(d => d.value)
.sort((a, b) => b.value - a.value))
Insert cell
root = layout(data);
Insert cell
format = d3.format(",d")
Insert cell
color = d3.scaleSequential([8, 0], d3.interpolateMagma)
Insert cell
d3 = require("d3@5")
Insert cell
import {boxmodel} from '@formsandlines/custom-d3-layout-for-css-like-box-model'
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