UNPKG

@obliczeniowo/elementary

Version:
185 lines (180 loc) 10.3 kB
import * as i0 from '@angular/core'; import { input, EventEmitter, effect, HostListener, HostBinding, Output, Component, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Point2D } from '@obliczeniowo/elementary/classes'; import { DrawingSvgInterface } from '@obliczeniowo/elementary/drawing'; class PagesLinearTreeComponent { elementRef; renderer; /** items to draw */ items = input([], { transform: (value) => structuredClone(value), }); onClicked = new EventEmitter(); /** drawing interface */ drawing; /** found under mouse item */ item; /** prepared points to redraw diagram */ points = []; /** width */ graphSize = 200; /** its width of diagram */ dGraphSize = 200; /** size of svg view box */ size = 500; /** categories */ categories = []; k = 5; get height() { return (this.items().length || 0) * this.k; } constructor(elementRef, renderer) { this.elementRef = elementRef; this.renderer = renderer; effect(() => { this.items(); this.calcPoints(); this.draw(); }); } ngAfterViewInit() { this.drawing = new DrawingSvgInterface(this.elementRef.nativeElement.querySelector('svg'), this.renderer); setTimeout(() => this.draw()); } move(event) { if (this.drawing && this.items().length) { const box = this.drawing.svgContainer.getBoundingClientRect(); const pt = new Point2D(event.x - box.left, event.y - box.top); const index = Math.floor((1 / this.k) * pt.y); this.item = this.items()[index]; this.draw(); } } clicked() { if (this.item) { this.onClicked.emit(structuredClone(this.item)); } } calcPoints() { if (this.items) { const max = this.getMax(); const k = this.dGraphSize / (max || 1); this.points = []; this.items().forEach((item, y) => { const x = k * item.value; const pos = new Point2D(x, y * this.k); item.data = { ...item.data, pos, }; this.points.push(pos); }); } this.calcCategories(); } calcCategories() { this.categories = []; const items = this.items(); for (let i = 1; i < items.length; i++) { if (i === 1) { const { rootName, parentName } = items[0]; this.categories.push({ parentName, rootName, pos: new Point2D(0, 0), endPos: new Point2D(this.dGraphSize, 0), pChanged: true, }); } else if (items[i].rootName !== items[i - 1].rootName || items[i].parentName !== items[i - 1].parentName) { const { rootName, parentName } = items[i]; const pChanged = items[i].rootName !== items[i - 1].rootName; this.categories.push({ rootName, parentName, pos: new Point2D(0, i * this.k), endPos: new Point2D(this.dGraphSize * (pChanged ? 1 : 0.8), i * this.k), pChanged, }); } } } draw() { if (!this.drawing) { return; } this.drawing.clear(); this.drawing.drawPolyline(this.points, 2, '#ffffff', { svgOnly: { classes: ['diagram'] }, }); this.categories.forEach((category) => { this.drawing.drawLine(category.pos, category.endPos, category.pChanged ? 0.6 : 0.3, '#969696', { svgOnly: { classes: [ 'categories', ...(category.pChanged ? ['root'] : ['parent']), ], }, }); }); if (this.item) { this.drawing.drawLine(new Point2D(0, this.item.data.pos.y), this.item.data.pos.add(new Point2D(this.dGraphSize, 0)), 2.5, '#ffffff', { svgOnly: { classes: ['current'], }, }); } } getMax() { let max = 0; this.items().forEach((item) => { if (max < item.value) { max = item.value; } }); return max; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: PagesLinearTreeComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: PagesLinearTreeComponent, isStandalone: false, selector: "obl-pages-linear-tree", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClicked: "onClicked" }, host: { listeners: { "mousemove": "move($event)", "click": "clicked($event)" }, properties: { "style.height.px": "this.height" } }, ngImport: i0, template: "<svg\n [attr.width]=\"dGraphSize\"\n [attr.viewBox]=\"'0 0 ' + dGraphSize + ' ' + items().length * k\"\n></svg>\n\n@for (category of categories; track $index) {\n @if (!$index || categories[$index - 1].pos.y - category.pos.y < -40) {\n <div\n class=\"category\"\n [style.left.px]=\"dGraphSize + 5\"\n [style.top.px]=\"category.endPos.y\"\n >\n {{ category.rootName }} &rarr; {{ category.parentName }}\n </div>\n }\n}\n\n@if (item) {\n <div\n class=\"category selected\"\n [style.left.px]=\"dGraphSize\"\n [style.top.px]=\"item.data.pos.y - 15\"\n >\n {{ item.rootName }} &rarr; {{ item.parentName }} &rarr; {{ item.name }}\n </div>\n}\n", styles: [":host{position:relative;display:flex;width:100%}:host ::ng-deep polyline.diagram{stroke:var(--default-text-color);stroke-width:1;fill:none}:host ::ng-deep polyline.categories{fill:none}:host ::ng-deep polyline.categories.root{stroke:red;stroke-width:.6}:host ::ng-deep polyline.categories.parent{stroke:#01cf01;stroke-width:.3}:host ::ng-deep circle.value,:host ::ng-deep circle.minimum{fill:none;stroke:var(--default-text-color);stroke-width:.1}:host ::ng-deep .current{stroke:var(--default-text-color);stroke-width:1px}svg{position:absolute;left:0;right:0}.category{position:absolute;color:var(--default-text-color)}.category.selected{border-radius:5px;background-color:var(--default-text-color);padding:5px;color:var(--default-background-color)}\n"] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: PagesLinearTreeComponent, decorators: [{ type: Component, args: [{ selector: 'obl-pages-linear-tree', standalone: false, template: "<svg\n [attr.width]=\"dGraphSize\"\n [attr.viewBox]=\"'0 0 ' + dGraphSize + ' ' + items().length * k\"\n></svg>\n\n@for (category of categories; track $index) {\n @if (!$index || categories[$index - 1].pos.y - category.pos.y < -40) {\n <div\n class=\"category\"\n [style.left.px]=\"dGraphSize + 5\"\n [style.top.px]=\"category.endPos.y\"\n >\n {{ category.rootName }} &rarr; {{ category.parentName }}\n </div>\n }\n}\n\n@if (item) {\n <div\n class=\"category selected\"\n [style.left.px]=\"dGraphSize\"\n [style.top.px]=\"item.data.pos.y - 15\"\n >\n {{ item.rootName }} &rarr; {{ item.parentName }} &rarr; {{ item.name }}\n </div>\n}\n", styles: [":host{position:relative;display:flex;width:100%}:host ::ng-deep polyline.diagram{stroke:var(--default-text-color);stroke-width:1;fill:none}:host ::ng-deep polyline.categories{fill:none}:host ::ng-deep polyline.categories.root{stroke:red;stroke-width:.6}:host ::ng-deep polyline.categories.parent{stroke:#01cf01;stroke-width:.3}:host ::ng-deep circle.value,:host ::ng-deep circle.minimum{fill:none;stroke:var(--default-text-color);stroke-width:.1}:host ::ng-deep .current{stroke:var(--default-text-color);stroke-width:1px}svg{position:absolute;left:0;right:0}.category{position:absolute;color:var(--default-text-color)}.category.selected{border-radius:5px;background-color:var(--default-text-color);padding:5px;color:var(--default-background-color)}\n"] }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { onClicked: [{ type: Output }], height: [{ type: HostBinding, args: ['style.height.px'] }], move: [{ type: HostListener, args: ['mousemove', ['$event']] }], clicked: [{ type: HostListener, args: ['click', ['$event']] }] } }); class PagesLinearTreeModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: PagesLinearTreeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.4", ngImport: i0, type: PagesLinearTreeModule, declarations: [PagesLinearTreeComponent], imports: [CommonModule], exports: [PagesLinearTreeComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: PagesLinearTreeModule, imports: [CommonModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: PagesLinearTreeModule, decorators: [{ type: NgModule, args: [{ declarations: [ PagesLinearTreeComponent ], imports: [ CommonModule, ], exports: [ PagesLinearTreeComponent ] }] }] }); /** * Generated bundle index. Do not edit. */ export { PagesLinearTreeComponent, PagesLinearTreeModule }; //# sourceMappingURL=obliczeniowo-elementary-pages-linear-tree.mjs.map