@obliczeniowo/elementary
Version:
Library made in Angular version 20
185 lines (180 loc) • 9.95 kB
JavaScript
import * as i1 from '@obliczeniowo/elementary/svg';
import { SvgModule } from '@obliczeniowo/elementary/svg';
import * as i0 from '@angular/core';
import { EventEmitter, Output, Input, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ElementaryMath } from '@obliczeniowo/elementary/math';
import { Point2D } from '@obliczeniowo/elementary/classes';
class SimpleDiagram2DComponent {
element;
svg;
/**
* Points2D array table as diagram points
*/
points = [];
/**
* Gradient definition description including:
* array of:
* - colors;
* - opacity;
* - offset;
* coordinates of gradient:
* - x, y start/end position (optional)
*/
gradient;
/**
* When undefined or not set it will 1 on X is 100% object width, and similar on Y
* When 'userSpaceOnUse' it use space units system (not related to object size)
*/
gradientUnits;
/**
* diagram padding
*/
padding = 0;
/**
* bottom diagram padding (includes as part of diagram shape)
*/
diagramBottomPadding = 5;
/** */
height = 50;
/** */
width = 200;
/**
* When set to true emit cursor position value in diagram space coordinates
*/
interactive = false;
/**
* Emit when require recalculation
*/
recalculate = new EventEmitter();
hover = new EventEmitter();
convertedShape = '';
convertedLines = '';
gradientId = `SimpleDiagram2D-${Math.floor(Math.random() * 100000)}`;
xMinMax;
yMinMax;
dx;
dy;
sx;
sy;
constructor(element) {
this.element = element;
}
ngOnChanges(changes) {
if (changes.points) {
this.convert();
}
if (changes.width || changes.height) {
this.convert();
}
}
transform(p) {
const dHeight = (this.height - this.diagramBottomPadding);
return new Point2D((p.x - this.xMinMax.min) * this.sx * (this.width - 2 * this.padding) / this.width + this.padding, (dHeight - (p.y - this.yMinMax.min) * this.sy) * (this.height - 2 * this.padding) / this.height + this.padding);
}
mouseToDiagram(p) {
const width = +this.width;
const height = +this.height;
const dHeight = height - +this.diagramBottomPadding;
const padding = +this.padding;
return new Point2D((((p.x - padding) / this.sx) * width) / (width - padding * 2) + this.xMinMax.min, (dHeight - p.y + padding) / this.sy + this.yMinMax.min);
}
interpolate(x) {
if (x < this.xMinMax.min && x > this.xMinMax.max) {
return NaN;
}
const index = this.points.findIndex(pt => pt.x >= x) - 1;
if (index === -1) {
return this.points[0].y;
}
const fp = this.points[index];
const sp = this.points[index + 1];
const a = (sp.y - fp.y) / (sp.x - fp.x);
const b = fp.y - a * fp.x;
return a * x + b;
}
mouseMove(event) {
if (this.interactive && !this.points) {
return;
}
const element = this.element.nativeElement;
const mousePos = { x: event.x - element.offsetLeft, y: event.y - element.offsetTop };
const converted = this.mouseToDiagram(mousePos);
const original = this.points.reduce((p, c) => {
p = (p && Math.abs(p.x - converted.x) < Math.abs(c.x - converted.x) && p) || c;
return p;
});
const hovered = this.transform(original);
this.hover.emit({ converted: hovered, original });
}
convert() {
this.xMinMax = ElementaryMath.getMinMax(this.points.map(p => p.x));
this.yMinMax = ElementaryMath.getMinMax(this.points.map(p => p.y));
this.dx = (this.xMinMax.max - this.xMinMax.min) || 1;
this.dy = (this.yMinMax.max - this.yMinMax.min) || 1;
const dHeight = (this.height - this.diagramBottomPadding);
this.sx = this.width / this.dx;
this.sy = dHeight / this.dy;
const points = this.points.map(p => new Point2D((p.x - this.xMinMax.min) * this.sx, dHeight - (p.y - this.yMinMax.min) * this.sy));
this.convertedLines = 'M' + points.map(p => p.toString(' ')).join('');
this.convertedShape = points.concat([
new Point2D((this.xMinMax.max - this.xMinMax.min) * this.sx, (this.yMinMax.max - this.yMinMax.min) * this.sy +
this.diagramBottomPadding),
new Point2D(0, (this.yMinMax.max - this.yMinMax.min) * this.sy + this.diagramBottomPadding)
]).map(p => p.toString()).join('');
this.recalculate.emit({ component: this });
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: SimpleDiagram2DComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: SimpleDiagram2DComponent, isStandalone: false, selector: "obl-simple-diagram2-d", inputs: { points: "points", gradient: "gradient", gradientUnits: "gradientUnits", padding: "padding", diagramBottomPadding: "diagramBottomPadding", height: "height", width: "width", interactive: "interactive" }, outputs: { recalculate: "recalculate", hover: "hover" }, usesOnChanges: true, ngImport: i0, template: "<svg width=\"100%\" [attr.viewBox]=\"'0 0 ' + this.width + ' ' + this.height\" (mousemove)=\"mouseMove($event)\">\n <defs>\n @if (gradient) {\n <g\n obl-svg-linear-gradient\n [gradient]=\"gradient\"\n [name]=\"gradientId\"\n [gradientUnits]=\"gradientUnits\"\n ></g>\n }\n </defs>\n <g\n [attr.transform]=\"\n 'translate(' +\n padding +\n ',' +\n padding +\n ') scale(' +\n (width - padding * 2) / width +\n ', ' +\n (height - padding * 2) / height +\n ')'\n \"\n >\n <polygon\n [attr.points]=\"convertedShape\"\n [style.fill]=\"gradient ? 'URL(#' + gradientId + ')' : undefined\"\n ></polygon>\n <path [attr.d]=\"convertedLines\"></path>\n </g>\n <ng-content></ng-content>\n</svg>\n", styles: ["path{stroke:var(--obl-primary);stroke-width:var(--obl-simple-diagram-stroke-width, 2px);fill:none}polygon{fill:var(--obl-secondary)}:host{display:flex}\n"], dependencies: [{ kind: "component", type: i1.SvgLinearGradientComponent, selector: "g[obl-svg-linear-gradient]", inputs: ["gradient", "gradientUnits", "name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: SimpleDiagram2DComponent, decorators: [{
type: Component,
args: [{ selector: 'obl-simple-diagram2-d', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<svg width=\"100%\" [attr.viewBox]=\"'0 0 ' + this.width + ' ' + this.height\" (mousemove)=\"mouseMove($event)\">\n <defs>\n @if (gradient) {\n <g\n obl-svg-linear-gradient\n [gradient]=\"gradient\"\n [name]=\"gradientId\"\n [gradientUnits]=\"gradientUnits\"\n ></g>\n }\n </defs>\n <g\n [attr.transform]=\"\n 'translate(' +\n padding +\n ',' +\n padding +\n ') scale(' +\n (width - padding * 2) / width +\n ', ' +\n (height - padding * 2) / height +\n ')'\n \"\n >\n <polygon\n [attr.points]=\"convertedShape\"\n [style.fill]=\"gradient ? 'URL(#' + gradientId + ')' : undefined\"\n ></polygon>\n <path [attr.d]=\"convertedLines\"></path>\n </g>\n <ng-content></ng-content>\n</svg>\n", styles: ["path{stroke:var(--obl-primary);stroke-width:var(--obl-simple-diagram-stroke-width, 2px);fill:none}polygon{fill:var(--obl-secondary)}:host{display:flex}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { points: [{
type: Input
}], gradient: [{
type: Input
}], gradientUnits: [{
type: Input
}], padding: [{
type: Input
}], diagramBottomPadding: [{
type: Input
}], height: [{
type: Input
}], width: [{
type: Input
}], interactive: [{
type: Input
}], recalculate: [{
type: Output
}], hover: [{
type: Output
}] } });
class SimpleDiagram2DModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: SimpleDiagram2DModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.4", ngImport: i0, type: SimpleDiagram2DModule, declarations: [SimpleDiagram2DComponent], imports: [CommonModule,
SvgModule], exports: [SimpleDiagram2DComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: SimpleDiagram2DModule, imports: [CommonModule,
SvgModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: SimpleDiagram2DModule, decorators: [{
type: NgModule,
args: [{
declarations: [
SimpleDiagram2DComponent
],
imports: [
CommonModule,
SvgModule
],
exports: [
SimpleDiagram2DComponent
]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { SimpleDiagram2DComponent, SimpleDiagram2DModule };
//# sourceMappingURL=obliczeniowo-elementary-simple-diagram2-d.mjs.map