/
githubmirror
/
angular
Обзор
Документация
Войти
/
githubmirror
/
angular
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
devtools/projects/ng-devtools/src/lib/shared/tree-visualizer/tree-visualizer.component.ts
129 строк
3 KB
hawkgs
refactor(devtools): use ng-filter for the router tree search
08 июн 2026, 21:19
08 июн 2026, 21:19
a7d6845
Код
Авторство
О чём код?
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.dev/license */ import { afterNextRender, Component, DestroyRef, effect, ElementRef, inject, input, output, signal, viewChild, } from '@angular/core'; import { TreeD3Node, TreeNode, TreeNodeEqualityFn, TreeVisualizer, TreeVisualizerConfig, } from './tree-visualizer'; let instanceIdx = 0; @Component({ selector: 'ng-tree-visualizer', template: ` <svg #container [class.panning]="panning()" (pointerdown)="panning.set(true)" (pointerup)="panning.set(false)" [attr.aria-labelledby]="a11yTitleId" > <title [id]="a11yTitleId">{{ this.a11yTitle() }}</title> <g #group></g> </svg> `, styleUrl: 'tree-visualizer.component.scss', }) export class TreeVisualizerComponent<T extends TreeNode = TreeNode> { protected readonly container = viewChild.required<ElementRef>('container'); protected readonly group = viewChild.required<ElementRef>('group'); readonly root = input.required<T>(); protected readonly nodeEqualityFn = input<TreeNodeEqualityFn<T> | null>(null); protected readonly config = input<Partial<TreeVisualizerConfig<T>>>(); protected readonly a11yTitle = input.required<string>(); protected readonly a11yTitleId = `tree-vis-host-${++instanceIdx}`; protected readonly ready = output<void>(); protected readonly render = output<{initial: boolean}>(); protected readonly nodeClick = output<TreeD3Node<T>>(); protected readonly nodeMouseout = output<TreeD3Node<T>>(); protected readonly nodeMouseover = output<TreeD3Node<T>>(); readonly panning = signal(false); private readonly visualizer = signal<TreeVisualizer<T> | null>(null); private initialRender: boolean = true; constructor() { afterNextRender({ write: () => this.visualizer()?.cleanup(), // Cleans up the visualization DOM read: () => { this.visualizer.set( new TreeVisualizer<T>( this.container().nativeElement, this.group().nativeElement, this.nodeEqualityFn(), this.config(), ), ); this.ready.emit(); }, }); effect(() => { this.renderGraph(this.root()); }); inject(DestroyRef).onDestroy(() => { this.visualizer()?.dispose(); }); } get svg(): HTMLElement { return this.container().nativeElement; } snapToRoot(scale?: number) { this.visualizer()?.snapToRoot(scale); } snapToNode(node: T, scale?: number) { this.visualizer()?.snapToNode(node, scale); } highlightNode(node: T | null) { this.visualizer()?.highlightNode(node); } getNodeById(id: string) { return this.visualizer()?.getInternalNodeById(id); } private renderGraph(root: T): void { const visualizer = this.visualizer(); if (!visualizer) { return; } visualizer.render(root); visualizer.onNodeClick((_, node) => this.nodeClick.emit(node)); visualizer.onNodeMouseout((_, node) => this.nodeMouseout.emit(node)); visualizer.onNodeMouseover((_, node) => this.nodeMouseover.emit(node)); this.render.emit({initial: this.initialRender}); if (this.initialRender) { this.initialRender = false; } } }