Skip to content

Commit

Permalink
feat(clinet): treemap color calc
Browse files Browse the repository at this point in the history
  • Loading branch information
nonzzz committed Jun 2, 2024
1 parent 4b0727c commit 76af118
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 32 deletions.
20 changes: 16 additions & 4 deletions src/client/components/treemap/shared.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import { hashCode } from '../../shared'
import type { Module, SquarifiedModule } from './interface'

export function sortChildrenBySize(a: Module, b: Module) {
return b.size - a.size || +(a.id > b.id) - +(a.id < b.id)
}

export function hueAngleToColor(hueAngle: number) {
const saturation = 0.6 + 0.4 * Math.max(0, Math.cos(hueAngle))
const lightness = 0.5 + 0.2 * Math.max(0, Math.cos(hueAngle + Math.PI * 2 / 3))
return 'hsl(' + hueAngle * 180 / Math.PI + 'deg, ' + Math.round(100 * saturation) + '%, ' + Math.round(100 * lightness) + '%)'
export function hueAngleToColor(hue: number, depth: number) {
const saturation = 60 - depth * 5
const lightness = 50 + depth * 5
return `hsla(${hue}deg, ${Math.max(saturation, 30)}%, ${Math.min(lightness, 70)}%, 0.9)`
}

export function evaluateHueFromModule(module: Module) {
const { filename } = module
const arc = Math.PI * 2
const isNumeric = (s: string) => {
const cp = s.charCodeAt(0)
return cp >= 48 && cp <= 57
}
const hash = isNumeric(filename) ? (parseInt(filename) / 1000) * arc : hashCode(filename)
return Math.round(Math.abs(hash) % arc)
}

export const STYLES = {
Expand Down
2 changes: 2 additions & 0 deletions src/client/components/treemap/squared.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { STYLES } from './shared'
import type { Module, SquarifiedModule } from './interface'

// Thanks Squarified Treemap by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
// https://www.win.tue.nl/~vanwijk/stm.pdf
function recursion<T extends Module>(data: T[], x: number, y: number, w: number, h: number): SquarifiedModule[] {
const squarifiedData: SquarifiedModule[] = []
if (!data) return squarifiedData
Expand Down
35 changes: 7 additions & 28 deletions src/client/components/treemap/treemap.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
/* eslint-disable no-use-before-define */
// According the bundle analyzed size. I deiced to implement the treemap component to replace Moduletree component.
// Alough the Moduletree component is more powerful and has more features, but it's too large to be used in the project.
// The treemap component is a simple component that can be used to display the data in a treemap format.

// Thanks Squarified Treemap by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
// https://www.win.tue.nl/~vanwijk/stm.pdf

import type { Module, SquarifiedModule } from './interface'
import { STYLES, charCodeWidth, findRelativeNode, hueAngleToColor, textOverflowEllipsis } from './shared'
import { STYLES, charCodeWidth, evaluateHueFromModule, findRelativeNode, hueAngleToColor, textOverflowEllipsis } from './shared'
import { squarify } from './squared'

interface Shape {
Expand Down Expand Up @@ -143,33 +137,18 @@ export class Paint {
}
}

private updateColorMapping() {
const colorMapping: Record<string, string> = {}
const defaultSweepAngle = Math.PI * 2

const totalSize = this.data.reduce((acc, module) => acc + module.size, 0)

const assignColorByDirectory = (module: Module, parent: Module, startAngle: number, sweepAngle: number) => {
const childSweepAngle = module.size / parent.size * sweepAngle
colorMapping[module.filename] = hueAngleToColor(startAngle + childSweepAngle / 2)
private setupColorMapping() {
const assignColorByDirectory = (module: Module, hue: number, depth: number) => {
this.colorMapping[module.filename] = hueAngleToColor(hue, depth)
if (module.groups) {
for (const child of module.groups) {
const childSweepAngle = child.size / module.size * sweepAngle
assignColorByDirectory(child, module, startAngle, childSweepAngle)
startAngle += childSweepAngle
assignColorByDirectory(child, hue, depth + 1)
}
}
}

for (const module of this.data) {
const initalAngle = module.size / totalSize * defaultSweepAngle
colorMapping[module.filename] = hueAngleToColor(initalAngle)
for (const group of module.groups) {
assignColorByDirectory(group, module, initalAngle, defaultSweepAngle)
}
assignColorByDirectory(module, evaluateHueFromModule(module), 0)
}

this.colorMapping = colorMapping
}

zoom(node: PaintEvent<MouseEvent | WheelEvent>) {
Expand Down Expand Up @@ -213,7 +192,7 @@ export class Paint {

mount(element: HTMLElement) {
this.mainEl = element
this.updateColorMapping()
this.setupColorMapping()
this.resize()
element.appendChild(this.canvas)
this.canvas.onmousemove = (e) =>
Expand Down

0 comments on commit 76af118

Please sign in to comment.