ModsCodeMERGEBLE LLC Search Claude Code Mods

ModsCode / Gallery / Designs / Treemap

Treemap

Ten sectors laid out by the squarified method across the whole pane, sized by value and tinted by the sign of change.

TreemapTreemap
Parts of a whole · 380×300 · sample data
hooks/designs/treemap.mjs
// treemap: ten sample sectors in candle's look, laid out across the whole 380x300 pane by the squarified
// method so the cells stay close to square. Size is the value; fill is up or down at 25% by the sign of the
// change. Each cell is inset 1px, which leaves 2px gutters. A label appears only when its cell is big
// enough for it, since a clipped name reads worse than none. Sample data only.
const W = 380
const H = 300
const UP = '#2C7A39'
const DOWN = '#AB2B3F'
const INK = '#141413'
const MUTED = '#73726C'
const STAGE = '#FAF9F5'
const FONT = "'Inter Tight','Segoe UI',system-ui,sans-serif"
const NAMES = ['Software', 'Semis', 'Banks', 'Energy', 'Pharma', 'Retail', 'Autos', 'Utilities', 'Telecom', 'Materials']

// A seeded set of sizes and signs: the same picture every time. A product of two draws gives many
// small sectors and a few large ones, which is closer to a real sector spread than a flat range.
function sample() {
  let seed = 20261009
  const rnd = () => (seed = (Math.imul(seed, 1103515245) + 12345) & 0x7fffffff) / 0x7fffffff
  return NAMES.map(name => ({ name, value: 20 + 180 * rnd() * rnd(), up: rnd() < 0.55 }))
}

// Worst aspect ratio of a strip laid along a side of length `side`
function worst(row, side) {
  const sum = row.reduce((s, r) => s + r.area, 0)
  const max = Math.max(...row.map(r => r.area))
  const min = Math.min(...row.map(r => r.area))
  return Math.max((side * side * max) / (sum * sum), (sum * sum) / (side * side * min))
}

// Squarified layout: keep adding to a strip while its worst ratio improves, then cut the strip along
// the shorter side. Items must already be sorted largest first.
function squarify(items, x, y, w, h) {
  const out = []
  let rest = items
  while (rest.length) {
    const side = Math.min(w, h)
    let n = 1
    while (n < rest.length && worst(rest.slice(0, n + 1), side) <= worst(rest.slice(0, n), side)) n++
    const row = rest.slice(0, n)
    rest = rest.slice(n)
    const sum = row.reduce((s, r) => s + r.area, 0)
    if (w >= h) {
      // The strip is a column on the left
      const cw = sum / h
      let cy = y
      for (const r of row) {
        const rh = r.area / cw
        out.push({ ...r, x, y: cy, w: cw, h: rh })
        cy += rh
      }
      x += cw
      w -= cw
    } else {
      // The strip is a row along the top
      const rh = sum / w
      let cx = x
      for (const r of row) {
        const cw = r.area / rh
        out.push({ ...r, x: cx, y, w: cw, h: rh })
        cx += cw
      }
      y += rh
      h -= rh
    }
  }
  return out
}

const f = n => n.toFixed(1)
const text = (x, y, s, size, fill) =>
  `<text x="${f(x)}" y="${f(y)}" font-size="${size}" font-family="${FONT}" fill="${fill}">${s}</text>`

function treemapSource(items) {
  const total = items.reduce((s, it) => s + it.value, 0)
  const scale = (W * H) / total
  const sorted = items.slice().sort((a, b) => b.value - a.value).map(it => ({ ...it, area: it.value * scale }))
  const parts = [`<rect width="${W}" height="${H}" rx="4" fill="${STAGE}"/>`]
  for (const c of squarify(sorted, 0, 0, W, H)) {
    const left = c.x + 1
    const top = c.y + 1
    const cw = c.w - 2
    const ch = c.h - 2
    parts.push(`<rect x="${f(left)}" y="${f(top)}" width="${f(cw)}" height="${f(ch)}" fill="${c.up ? UP : DOWN}" fill-opacity="0.25" stroke="${INK}" stroke-opacity="0.12" stroke-width="1"/>`)
    // About 5.6px a character at 10px; the value line needs the taller cells
    if (cw >= c.name.length * 5.6 + 8 && ch >= 16) {
      parts.push(text(left + 6, top + 14, c.name, 10, INK))
      if (ch >= 32) parts.push(text(left + 6, top + 26, String(Math.round(c.value)), 9, MUTED))
    }
  }
  return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${W} ${H}" width="${W}" height="${H}">${parts.join('')}</svg>`
}

const SOURCE = treemapSource(sample())

export default {
  id: 'treemap',
  title: 'Treemap',
  category: 'parts',
  description: 'Ten sectors laid out by the squarified method across the whole pane, sized by value and tinted by the sign of change.',
  element: ui => ui.Svg({ source: SOURCE, alt: 'Treemap of ten sample sectors: size is value, fill is up or down', width: W, height: H }),
}

To use it in a mod: copy the file to your mod's hooks/designs/ and return its element(ui) from a pane's ui.render. How a pane is built.

Code: PolyForm Noncommercial License 1.0.0: noncommercial use only. Required Notice: Copyright 2026 Haruki Nakada (https://modscode.com).