Published
Edited
Jul 11, 2022
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
text = FileAttachment("filesizes.txt").text()
Insert cell
Insert cell
// converting data into Objects
parsed = {
const splitText = text.split("\n"); // split by new line character
splitText.pop(); // trailing \n leaves undefined

return splitText.map((d) => {
const splitLine = d.trim().split(" ");
return {
bytes: +splitLine[0], // convert to int
path: splitLine[1].toLowerCase() // normalize
};
});
}
Insert cell
Insert cell
{
const readmes = [...parsed].filter((d) => d.path.includes("readme.md")); // filter
const meanSize = d3.mean(readmes, (d) => d.bytes);
const medianSize = d3.median(readmes, (d) => d.bytes);

return `Mean README size : ${d3.format(",.3~s")(
meanSize
)} bytes\n Median README size: ${d3.format(",.3~s")(medianSize)} bytes`;
}
Insert cell
Insert cell
libSizes = d3.rollup(
parsed,
(v) => d3.sum(v, (d) => d.bytes),
(d) => d.path.split("/")[1] // isolate the lib
)
Insert cell
Insert cell
// look for node_modules just once in the path string
libNoNestsSizes = d3.rollup(
[...parsed].filter((d) => d.path.match(/node_modules/g).length === 1), // if path has more than one node_modules, its nested
(v) => d3.sum(v, (d) => d.bytes),
(d) => d.path.split("/")[1] // isolate the lib
)
Insert cell
Insert cell
Insert cell
fileTypeSizes = d3.rollup(
parsed.filter((d) => d.path.includes(".")),
(v) => d3.sum(v, (d) => d.bytes), // sum bytes in local lib
(d) => d.path.split(".").pop(), // get last pkg name in path,
(d) => d.path
)
Insert cell
root = d3.hierarchy(fileTypeSizes)
Insert cell
ellipse = d3
.range(100)
.map((i) => [
(width * (1 + 0.99 * Math.cos((i / 50) * Math.PI))) / 2,
(width * (1 + 0.99 * Math.sin((i / 50) * Math.PI))) / 2
])
Insert cell
chart = {
const svg = d3
.select(DOM.svg(width, width))
.attr("viewBox", [0, 0, width, width]);

const voronoi = svg.append("g").attr("transform", `translate(${0},${0})`);

let seed = new Math.seedrandom(20);
const voronoiTreeMap = d3.voronoiTreemap().prng(seed).clip(ellipse);

voronoiTreeMap(root);

// let allNodes = root
// .descendants()
// .sort((a, b) => b.depth - a.depth)
// .map((d, i) => Object.assign({}, d, { id: i }));

// console.log(allNodes);

// voronoi
// .selectAll("path")
// .data(allNodes)
// .join("path")
// .attr("d", (d) => "M" + d.polygon.join("L") + "Z")
// .attr("stroke", "white")
// .style("fill-opacity", (d) => (d.depth === 2 ? 1 : 0))
// .style("fill", "#ff00ff")
// .attr("class", "path")
// .attr("stroke-width", (d) => 1 - d.depth * 3);

return svg.node();
}
Insert cell
bubbleChart = Pack(
d3.rollup(
parsed,
(v) => d3.sum(v, (d) => d.bytes), // sum bytes in local lib
(d) => d.path.split("node_modules").pop().split("/")[1], // get last pkg name in path
(d) => d.path.split("/")[1], // group by parent lib for convenience,
(d) => d.path
),
{
value: ([, value]) => value,
label: ([key]) => key?.split(/\s+/g).join("\n"),
title: ([key], n) =>
`${
n.depth
? `${n
.ancestors()
.reverse()
.slice(1)
.map(({ data: [key] }) => key)
.join("\n")}\n`
: ""
}${n.value.toLocaleString("en")}`,
width: 2000,
height: 2000
}
)
Insert cell
import { Pack } from "@d3/pack"
Insert cell
d3 = require("d3", "d3-weighted-voronoi", "d3-voronoi-map", "d3-voronoi-treemap", 'seedrandom@2.4.3/seedrandom.min.js')
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