From e30dd0cadf36166a303d233fc079cfaa98728309 Mon Sep 17 00:00:00 2001 From: kanno <812137533@qq.com> Date: Sun, 29 Sep 2024 18:26:15 +0800 Subject: [PATCH] feat: init squarify algorithm --- src/client/components/treemap-v2/callee.tsx | 9 +++-- .../components/treemap-v2/component.tsx | 2 +- src/client/components/treemap-v2/interface.ts | 2 ++ src/client/components/treemap-v2/squarify.ts | 7 ++-- src/client/components/treemap-v2/treemap.ts | 33 +++++++++++++------ 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/client/components/treemap-v2/callee.tsx b/src/client/components/treemap-v2/callee.tsx index 8374a9d..f726607 100644 --- a/src/client/components/treemap-v2/callee.tsx +++ b/src/client/components/treemap-v2/callee.tsx @@ -2,11 +2,11 @@ import { forwardRef, useImperativeHandle, useMemo, useRef } from 'react' import { useApplicationContext } from '../../context' import { Treemap } from './component' import type { TreemapComponentInstance } from './component' -import { DuckModule, wrapperAsModule } from './squarify' -import { Module } from './interface' +import { wrapperAsModule } from './squarify' +import { PaintEventMap } from './treemap' export interface TreemapProps { - onMousemove: (data: any) => void + onMousemove: PaintEventMap['mousemove'] } export const TreemapV2 = forwardRef((props: TreemapProps, ref) => { @@ -15,8 +15,7 @@ export const TreemapV2 = forwardRef((props: TreemapProps, ref) => { useImperativeHandle(ref, () => instance.current!) - // @ts-expect-error - const visibleChunks = useMemo>(() => { + const visibleChunks = useMemo(() => { return analyzeModule.filter(m => scence.has(m.label)).map(m => { const { stats, source, ...rest } = m const groups = sizes === 'statSize' ? stats : source diff --git a/src/client/components/treemap-v2/component.tsx b/src/client/components/treemap-v2/component.tsx index 1adfc10..2085125 100644 --- a/src/client/components/treemap-v2/component.tsx +++ b/src/client/components/treemap-v2/component.tsx @@ -2,7 +2,7 @@ import { Ref, forwardRef, useCallback, useEffect, useImperativeHandle, useRef } import { inline } from '@stylex-extend/core' import { noop } from 'foxact/noop' import { PaintOptions, createTreemap } from './treemap' -import { DuckModule } from './squarify' +import type { DuckModule } from './interface' export interface TreemapProps { options?: PaintOptions diff --git a/src/client/components/treemap-v2/interface.ts b/src/client/components/treemap-v2/interface.ts index a8b067c..cd59957 100644 --- a/src/client/components/treemap-v2/interface.ts +++ b/src/client/components/treemap-v2/interface.ts @@ -6,3 +6,5 @@ export type Module = NativeModule & { groups: Module[] [key: string]: any } + +export type DuckModule = Record & { groups: T[] } diff --git a/src/client/components/treemap-v2/squarify.ts b/src/client/components/treemap-v2/squarify.ts index 91ca1db..f2144ae 100644 --- a/src/client/components/treemap-v2/squarify.ts +++ b/src/client/components/treemap-v2/squarify.ts @@ -5,8 +5,7 @@ // so we no need to sort the module at client side. (unlike the original squarify algorithm) import type { Sizes } from '../../interface' - -export type DuckModule = Record & { groups: T[] } +import type { DuckModule, Module } from './interface' // steps: recursive splitting. // 1. find the shortest side of the rectangle. @@ -92,6 +91,10 @@ export type DuckModule = Record & { groups: T[] } // if // end +export function squarify(data: DuckModule[], x: number, y: number, w: number, h: number) { + // +} + export function sortChildrenBySize>( a: T, b: T, diff --git a/src/client/components/treemap-v2/treemap.ts b/src/client/components/treemap-v2/treemap.ts index db1dd06..92fee2c 100644 --- a/src/client/components/treemap-v2/treemap.ts +++ b/src/client/components/treemap-v2/treemap.ts @@ -1,12 +1,21 @@ /* eslint-disable no-use-before-define */ // Alough foamtree is very useful, but we don't need too much function. // so implement a simple and lightweight treemap component. +import {} from './squarify' +import type { DuckModule, Module } from './interface' -export interface PaintOptions { - data: T - evt?: { - mousemove?: (this: Paint, data: any) => void - } +export interface PaintEvent { + nativeEvent: E + module: any +} + +export interface PaintEventMap { + mousemove: (this: Paint, event: PaintEvent) => void +} + +export interface PaintOptions[]> { + data: T[] + evt?: Partial } export interface PaintRect { @@ -19,10 +28,12 @@ class Paint { private _canvas: HTMLCanvasElement | null private context: CanvasRenderingContext2D | null private rect: PaintRect + private data: DuckModule[] constructor() { this.mountNode = null this._canvas = null this.context = null + this.data = [] this.rect = { w: 0, h: 0 } } @@ -31,7 +42,6 @@ class Paint { this._canvas = document.createElement('canvas') this.context = this.canvas.getContext('2d') this.mountNode.appendChild(this.canvas) - this.resize() return this } @@ -59,6 +69,7 @@ class Paint { this.mountNode = null this._canvas = null this.context = null + this.data = [] this.rect = { w: 0, h: 0 } } @@ -73,19 +84,21 @@ class Paint { this.canvas.style.cssText = `width: ${width}px; height: ${height}px` this.ctx.scale(ratio, ratio) if (previousRect.w !== width || previousRect.h !== height) { - // + // squarify layout } this.draw() } - setOptions(options?: PaintOptions) { + setOptions(options?: PaintOptions>) { if (!options || !this.canvas) return - const { evt: userEvent } = options + const { evt: userEvent, data } = options + this.data = data + this.resize() if (userEvent) { this.canvas.onmousemove = (e) => this.eventHandler(e, (evt) => { this.canvas.style.cursor = 'pointer' - userEvent.mousemove?.call(this, null) + userEvent.mousemove?.call(this, evt) }) } }