@obliczeniowo/elementary
Version:
Library made in Angular version 20
1,160 lines • 63.9 kB
JavaScript
import * as i0 from '@angular/core';
import { ContentChild, HostBinding, Component, input, effect, Input, ViewChild, ChangeDetectionStrategy, EventEmitter, Output, NgModule } from '@angular/core';
import * as i1 from '@angular/common';
import { DecimalPipe, CommonModule } from '@angular/common';
import * as i1$1 from '@obliczeniowo/elementary/buttons';
import { ButtonsModule } from '@obliczeniowo/elementary/buttons';
import * as i5 from '@obliczeniowo/elementary/text-pipes';
import { TranslationPipe, TextPipesModule } from '@obliczeniowo/elementary/text-pipes';
import * as i3 from '@obliczeniowo/elementary/input';
import { InputModule } from '@obliczeniowo/elementary/input';
import * as i2 from '@obliczeniowo/elementary/numeric-pipes';
import { AbsPipe, MinPipe } from '@obliczeniowo/elementary/numeric-pipes';
import { ElementaryMath } from '@obliczeniowo/elementary/math';
import { Point2D, LinearFunction2D } from '@obliczeniowo/elementary/classes';
import { TextAlign, LinePattern, TextBaseline, Rect, DrawingSvgInterface } from '@obliczeniowo/elementary/drawing';
import { Subject } from 'rxjs';
import { ns } from '@obliczeniowo/elementary/svg';
import { DrawingPdfInterface } from '@obliczeniowo/elementary/drawing-pdf';
import { keysValues } from '@obliczeniowo/elementary/objects';
import * as i1$2 from '@obliczeniowo/elementary/files';
/**
* Create hover over element on obl-linear-diagram-2d element by ng-content
*
* example with own template
*
* <obl-linear-diagram-2d [points]="points">
* <ng-template #xyTemplate let-x="x" let-y="y">
* <div class="xy-template">
* <div>x = {{ x | number: '0.5-5' }}</div>
* <div>y = {{ y | number: '0.5-5' }}</div>
* </div>
* </ng-template>
* </obl-linear-diagram-2d>
*/
class DiagramPointHoverComponent {
x;
y;
pOnMouseOver;
set onMouseOver(value) {
if (this.pOnMouseOver && !this.pOnMouseOver.closed) {
this.pOnMouseOver.unsubscribe();
}
if (value) {
this.pOnMouseOver = value.subscribe((element) => {
const point = JSON.parse(element.dataset.point);
const pointSvg = JSON.parse(element.dataset.pointSvg);
this.x = point.x;
this.y = point.y;
const rect = element.getBoundingClientRect();
const svgHeight = element.ownerSVGElement?.clientHeight;
const svgWidth = element.ownerSVGElement?.clientWidth;
const viewBox = (element.ownerSVGElement?.getAttribute('viewBox')).split(' ').slice(2).map(v => parseFloat(v));
this.left = pointSvg.x / viewBox[0] * svgWidth + rect.width / 2;
this.top = pointSvg.y / viewBox[1] * svgHeight + rect.height / 2;
this.over = '';
});
}
}
pOnMouseOut;
set onMouseOut(value) {
if (this.pOnMouseOut && !this.pOnMouseOut.closed) {
this.pOnMouseOut.unsubscribe();
}
if (value) {
this.pOnMouseOut = value.subscribe(() => {
this.over = 'none';
});
}
}
over = 'none';
top = 0;
left = 0;
xyTemplate;
ngOnDestroy() {
this.onMouseOut = undefined;
this.onMouseOver = undefined;
if (this.pOnMouseOut && !this.pOnMouseOut.closed) {
this.pOnMouseOut.unsubscribe();
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: DiagramPointHoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: DiagramPointHoverComponent, isStandalone: false, selector: "obl-diagram-point-hover", host: { properties: { "style.display": "this.over", "style.top.px": "this.top", "style.left.px": "this.left" } }, queries: [{ propertyName: "xyTemplate", first: true, predicate: ["xyTemplate"], descendants: true }], ngImport: i0, template: "@if (!xyTemplate) {\n <div>\n <p>x: {{ x }}</p>\n <p>y: {{ y }}</p>\n </div>\n}\n\n<ng-container *ngTemplateOutlet=\"xyTemplate; context: { x: x, y: y }\"></ng-container>\n\n<ng-content></ng-content>", styles: [":root{--obl-spinner-width: 30px;--obl-font-size: 14px}:host{position:absolute;top:0;left:0}:host div{min-width:100px;background-color:#000;border-radius:5px;opacity:.8;padding:6px}:host div p{margin:4px;font-size:14px;color:#fff}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: DiagramPointHoverComponent, decorators: [{
type: Component,
args: [{ selector: 'obl-diagram-point-hover', standalone: false, template: "@if (!xyTemplate) {\n <div>\n <p>x: {{ x }}</p>\n <p>y: {{ y }}</p>\n </div>\n}\n\n<ng-container *ngTemplateOutlet=\"xyTemplate; context: { x: x, y: y }\"></ng-container>\n\n<ng-content></ng-content>", styles: [":root{--obl-spinner-width: 30px;--obl-font-size: 14px}:host{position:absolute;top:0;left:0}:host div{min-width:100px;background-color:#000;border-radius:5px;opacity:.8;padding:6px}:host div p{margin:4px;font-size:14px;color:#fff}\n"] }]
}], propDecorators: { over: [{
type: HostBinding,
args: ['style.display']
}], top: [{
type: HostBinding,
args: ['style.top.px']
}], left: [{
type: HostBinding,
args: ['style.left.px']
}], xyTemplate: [{
type: ContentChild,
args: ['xyTemplate']
}] } });
class YAxisI {
textAlign = TextAlign.RIGHT;
/** pipe used for formatting x/y axis text */
decimalPipe = new DecimalPipe('en-US');
/**
* Function that give you control over format of y axis values
* this function can be overrided let programmer use whatever he want
* @param y value on scale to draw
* @param yK y * pow(10, yK) - power of 10 that provide number into n.xxxx format
* @returns formatted string value of y scale
*/
yFormatter = (y, yK) => this.decimalPipe.transform(y * Math.pow(10, yK), '0.3-3') || 'NaN';
}
class YAxis extends YAxisI {
draw(dc, startPoint, startScale, dY, minMax, yScale, yK, diagramArea, yLabel, yOptions) {
dc.group({ name: 'yAxis' });
const color = yOptions?.color;
this.textAlign = yOptions?.textAlign || this.textAlign;
if (this.textAlign !== TextAlign.RIGHT) {
const m = new Point2D(diagramArea.width, 0);
startPoint = startPoint.add(m);
startScale = startScale.add(m);
}
let posy = new Point2D(startPoint.x, startScale.y);
const eP = startPoint.add(new Point2D(0, -diagramArea.height));
dc.drawArrow(startPoint, eP, yOptions?.stroke || 1, color || '#000000', !!yOptions?.arrow);
dc.setTextAlign(this.textAlign);
let lengthYLabel = 0;
let yText = '';
dc.group({ name: 'values' });
const dm = new Point2D(this.textAlign === TextAlign.RIGHT ? -2 : 4, 1.5);
const dsc = new Point2D(0, -dY * yScale);
if (minMax.min !== minMax.max) {
for (let y = Math.ceil(minMax.min / dY) * dY; y <= minMax.max; y += dY) {
yText = this.yFormatter(y, yK);
const tw = dc.getTextWidth(yText);
lengthYLabel = tw > lengthYLabel ? tw : lengthYLabel;
dc.drawText(yText, posy.add(dm), color || '#000000', 0);
posy = posy.add(dsc);
if (posy.y < eP.y) {
break;
}
}
}
dc.setTextAlign(TextAlign.LEFT);
dc.endGroup();
dc.endGroup();
if (yLabel) {
const textWidth = dc.getTextWidth(yLabel);
const offset = this.textAlign === TextAlign.RIGHT
? new Point2D(diagramArea.x, diagramArea.y + diagramArea.height * 0.5).add(new Point2D(-lengthYLabel - 10, textWidth / 2))
: new Point2D(diagramArea.x + diagramArea.width, diagramArea.y + diagramArea.height * 0.5).add(new Point2D(lengthYLabel + 20, textWidth / 2));
dc.drawText(yLabel, offset, color || '#009900', 90);
}
if (yK) {
const offset = this.textAlign === TextAlign.RIGHT
? new Point2D(diagramArea.x, diagramArea.y).add(new Point2D(-lengthYLabel - 10, 0))
: new Point2D(diagramArea.x + diagramArea.width, diagramArea.y).add(new Point2D(lengthYLabel + 20, 0));
dc.setTextAlign(TextAlign.RIGHT);
dc.drawText(`×e${-yK}`, offset, color || '#009900', 90);
}
return lengthYLabel;
}
}
var PointType;
(function (PointType) {
PointType["NONE"] = "none";
PointType["CIRCLE"] = "circle";
PointType["X"] = "x";
PointType["STAR"] = "star";
})(PointType || (PointType = {}));
class LinearDiagram2D {
static drawingPoints = new Map();
options;
/** min max for x */
xMinMax;
/** min max for y */
yMinMax;
/** */
yAxis = new YAxis();
/** */
xScale;
/** */
yScale;
xCursorLine;
yCursorLine;
xyCursor;
selectionRange;
/** diagram area rect (area where diagram data will be drawn) */
diagramArea;
pPoints = [[]];
/** diagram title text */
title = '';
/** x label description */
xLabel = '';
/** y label description */
yLabel = '';
/** legend description table */
legend = [];
/** pipe used for formatting x/y axis text */
decimalPipe = new DecimalPipe('en-US');
/** */
xK = 0;
/** */
yK = 0;
redraw = new Subject();
onPointMouseOver = new Subject();
onPointMouseOut = new Subject();
static registerDrawingPointFu(name, fu) {
if (LinearDiagram2D.drawingPoints.has(name)) {
return false;
}
LinearDiagram2D.drawingPoints.set(name, fu);
return true;
}
/**
* Function that give you control over format of x axis values
* this function can be overridden let programmer use whatever he want
* @param x value on scale to draw
* @param xK x * pow(10, xK) - power of 10 that provide number into n.xxxx format
* @returns formatted string value of x scale
*/
xFormatter = (x, xK) => this.decimalPipe.transform(x * Math.pow(10, xK), '0.2-2') || 'NaN';
set yFormatter(fu) {
this.yAxis.yFormatter = fu;
}
/**
* set points vector and recalculate xMinMax & yMinMax values for diagram
*/
set points(points) {
this.pPoints = points;
this.xMinMax = this.getXMinMax();
this.xK = -Math.floor(Math.log10(Math.max(Math.abs(this.xMinMax.max), Math.abs(this.xMinMax.min))));
this.yMinMax = this.getYMinMax();
this.yK = -Math.floor(Math.log10(Math.max(Math.abs(this.yMinMax.max), Math.abs(this.yMinMax.min))));
}
/**
* @param area diagram area
* @param points points vectors as table of Point2D
* @param options options settings for diagram (most of them override default one)
*/
constructor(area, points, options) {
if (!LinearDiagram2D.drawingPoints.has(PointType.CIRCLE)) {
LinearDiagram2D.drawingPoints.set(PointType.CIRCLE, (point, dc, stroke, color) => dc.drawCircle(point, 2, stroke, color, 'none'));
LinearDiagram2D.drawingPoints.set(PointType.STAR, (point, dc, stroke, color) => [0, 1, 2, 3, 4, 5].forEach((i) => dc.drawLine(point, new Point2D(0, 5)
.rotate(ElementaryMath.degreesToRadians(60) * i)
.add(point), stroke, color)));
LinearDiagram2D.drawingPoints.set(PointType.X, (point, dc, stroke, color) => [0, 1, 2, 3].forEach((i) => dc.drawLine(point, new Point2D(0, 5)
.rotate((Math.PI / 2) * i + Math.PI / 4)
.add(point), stroke, color)));
}
this.diagramArea = area;
this.options = {
xAxis: {
display: true,
arrow: true,
color: '#ff0000',
stroke: 1,
},
yAxis: {
display: true,
arrow: true,
color: '#009900',
stroke: 1,
},
greed: {
display: true,
color: {
hex: '#777777',
html: 'var(--obl-linear-diagram-greed-color)',
},
stroke: 0.25,
linePattern: LinePattern.DASHED,
},
};
this.setOptions(options);
this.points = points;
}
normalizeMinMax(min, max) {
if (min === max) {
if (min && max) {
if (min > 0) {
min = 0;
}
else {
max = 0;
}
}
else {
max = 1;
}
}
return {
min,
max,
};
}
filterByRange() {
const { selectionRange } = this;
const { min, max } = selectionRange || { min: 0, max: 1 };
const check = (p) => p && p.x >= min && p.x <= max;
const between = (p1, p2) => p1 && p1.x < min && p2 && p2.x > max;
return selectionRange
? this.pPoints.map((points) => points.filter((p, index) => check(p) ||
check(points[index - 1]) ||
check(points[index + 1]) ||
between(p, points[index + 1]) ||
between(points[index + 1], p) ||
between(p, points[index - 1]) ||
between(points[index - 1], p)))
: this.pPoints;
}
/**
* Get min and max of x axis
* @returns return min & max for x axis
*/
getXMinMax() {
let min;
let max;
const filtered = this.filterByRange();
filtered.forEach((points) => {
points.forEach((point, index) => {
if (min === undefined || min > point.x) {
min = point.x;
}
if (max === undefined || max < point.x) {
max = point.x;
}
});
});
if (!this.selectionRange) {
if (min === undefined ||
(this.options?.xMinMax?.min !== undefined &&
min > this.options?.xMinMax?.min)) {
min = this.options?.xMinMax?.min || 0;
}
if (max === undefined ||
(this.options?.xMinMax?.max !== undefined &&
max < this.options?.xMinMax?.max)) {
max = this.options?.xMinMax?.max || min + 1;
}
}
else {
return this.normalizeMinMax(this.selectionRange.min, this.selectionRange.max);
}
return this.normalizeMinMax(min, max);
}
/**
* Find minimum & maximum for y axis
* @returns MinMax interface of displayed values
*/
getYMinMax() {
let min;
let max;
const filtered = this.filterByRange();
const { selectionRange } = this;
filtered.forEach((points) => {
if (selectionRange && points.length > 1) {
let fu = LinearFunction2D.fromTwoPoints(points[0], points[1]);
if (fu) {
const calculated = Math.max(Math.min(points[0].x, points[1].x), selectionRange.min);
if (min !== undefined) {
min = Math.min(fu.yPoint(calculated), min);
max = Math.max(min, max);
}
else {
min = fu.yPoint(calculated);
max = min;
}
}
const fp = points[points.length - 2];
const lp = points[points.length - 1];
fu = LinearFunction2D.fromTwoPoints(fp, lp);
if (fu) {
const calculated = Math.min(Math.max(lp.x, fp.x), selectionRange.max);
if (min !== undefined) {
min = Math.min(fu.yPoint(calculated), min);
max = Math.max(fu.yPoint(calculated), max);
}
else {
min = fu.yPoint(calculated);
max = min;
}
}
}
points.forEach((point, index) => {
if ((index === 0 || index === points.length - 1) && selectionRange) {
return;
}
if (min === undefined || min > point.y) {
min = point.y;
}
if (max === undefined || max < point.y) {
max = point.y;
}
});
});
if (min === undefined ||
(this.options?.yMinMax?.min !== undefined &&
min > this.options?.yMinMax?.min)) {
min = this.options?.yMinMax?.min || 0;
}
if (max === undefined ||
(this.options?.yMinMax?.max !== undefined &&
max < this.options?.yMinMax?.max)) {
max = this.options?.yMinMax?.max || min + 1;
}
return this.normalizeMinMax(min, max);
}
/**
* Convert point diagram pos to SVG pos
* @param point point to transform
* @param startPoint diagram start point
* @param xScale x scale
* @param yScale y scale
* @returns Point2D instance
*/
diagramPosToSVG(point, startPoint) {
return new Point2D((point.x - this.xMinMax.min) * this.xScale + startPoint.x, -(point.y - this.yMinMax.min) * this.yScale + startPoint.y);
}
svgPosToDiagram(point, startPoint, xScale, yScale) {
return new Point2D((point.x - startPoint.x) / xScale + this.xMinMax.min, (startPoint.y - point.y) / yScale + this.yMinMax.min);
}
getDAxis(range, autoIncreaseDecrease, dp) {
if (!dp) {
dp = range;
}
if (autoIncreaseDecrease) {
while (range / dp > 10) {
dp *= 2;
}
while (range / dp < 5) {
dp /= 2;
}
}
return dp;
}
getDx() {
const range = this.xMinMax.max - this.xMinMax.min;
return this.getDAxis(this.xMinMax.max - this.xMinMax.min, !this.options?.xAxis?.autoIncreaseDecrease, (this.options.xAxis?.dp && this.options.xAxis.dp) ||
this.recalcDScale(range, this.options.xAxis?.precision !== undefined &&
this.options.xAxis?.precision >= 0
? this.options.xAxis.precision
: 2));
}
getDy() {
const range = this.yMinMax.max - this.yMinMax.min;
return this.getDAxis(range, !this.options?.yAxis?.autoIncreaseDecrease, (this.options.yAxis?.dp && this.options.yAxis.dp) ||
this.recalcDScale(range, this.options.yAxis?.precision && this.options.yAxis?.precision >= 0
? this.options.yAxis.precision
: 2));
}
drawGreed(dc, startPoint) {
if (!this.options.greed?.display) {
return;
}
dc.group({ name: 'greed' }).setLinePattern(this.options.greed?.linePattern);
const dx = this.getDx();
const dy = this.getDy();
const startScale = this.diagramPosToSVG(new Point2D(Math.ceil(this.xMinMax.min / dx) * dx, Math.ceil(this.yMinMax.min / dy) * dy), startPoint);
const dxy = new Point2D(dx * this.xScale, dy * this.yScale);
let posX = new Point2D(startScale.x, startPoint.y);
let posY = new Point2D(startPoint.x, startScale.y);
while (posX.x <=
posY.x + (this.xMinMax.max - this.xMinMax.min) * this.xScale) {
dc.drawLine(posX, new Point2D(posX.x, posX.y - (this.yMinMax.max - this.yMinMax.min) * this.yScale), this.options?.greed?.stroke || 0, this.options?.greed?.color || '#000000');
posX = posX.add(new Point2D(dxy.x, 0));
}
while (posY.y >=
posX.y - (this.yMinMax.max - this.yMinMax.min) * this.yScale) {
dc.drawLine(posY, new Point2D(posY.x + (this.xMinMax.max - this.xMinMax.min) * this.xScale, posY.y), this.options.greed?.stroke || 0, this.options.greed?.color || '#000000');
posY = posY.add(new Point2D(0, -dxy.y));
}
dc.setLinePattern(LinePattern.NONE).endGroup();
}
/**
* Calc scale elementary increase value with given precision
* @param value (max - min)
* @param precision integer number should be >= 0
* @returns scale elementary increase value
*/
recalcDScale(value, precision = 2) {
const power = Math.floor(Math.log10(value));
return +(Math.ceil((Math.pow(10, -power + precision) * value) / 10) *
Math.pow(10, power - precision)).toFixed(precision);
}
drawXAxis(dc, startPoint) {
if (!this.options.xAxis?.display) {
return 0;
}
dc.group({ name: 'xAxis' });
const dx = this.getDx();
const startScale = this.diagramPosToSVG(new Point2D(Math.ceil(this.xMinMax.min / dx) * dx, 0), startPoint);
let posX = new Point2D(startScale.x, startPoint.y);
const bP = this.diagramPosToSVG(new Point2D(this.xMinMax.min, this.yMinMax.min), startPoint);
const eP = this.diagramPosToSVG(new Point2D(this.xMinMax.max, this.yMinMax.min), startPoint);
dc.drawArrow(bP, eP, this.options.xAxis?.stroke || 0, this.options.xAxis?.color || '#000000', !!this.options?.xAxis?.arrow);
let xText = '';
let textWidth = 0;
dc.group({ name: 'values' });
for (let x = Math.ceil(this.xMinMax.min / dx) * dx; x <= this.xMinMax.max; x += dx) {
xText = this.xFormatter(x, this.xK);
textWidth = dc.getTextWidth(xText) + 5;
dc.drawText(xText, posX.add(new Point2D(1.5, textWidth)), this.options.xAxis?.color || '#000000', 90);
posX = posX.add(new Point2D(dx * this.xScale, 0));
if (posX.x > eP.x) {
break;
}
}
dc.endGroup().endGroup();
return textWidth;
}
drawYAxis(dc, startPoint) {
if (!this.options.yAxis?.display) {
return 0;
}
const dy = this.getDy();
const startScale = this.diagramPosToSVG(new Point2D(0, Math.ceil(this.yMinMax.min / dy) * dy), startPoint);
return this.yAxis.draw(dc, startPoint, startScale, dy, this.yMinMax, this.yScale, this.yK, this.diagramArea, this.yLabel, this.options.yAxis);
}
drawLegend(dc) {
if (this.legend?.length &&
this.pPoints &&
this.legend.length <= this.pPoints.length &&
this.options?.set?.length) {
dc.setFontSize(8);
const maxTextWidth = this.legend
.map((text) => dc.getTextWidth(text))
.reduce((prev, current) => ((prev = prev < current ? current : prev), prev), 0);
const padding = 5;
const keyHeight = 10;
const keyWidth = 15;
const totalWidth = keyWidth + padding * 3 + maxTextWidth;
const totalHeight = padding + (keyHeight + padding) * this.legend.length;
const pc = new Point2D(this.diagramArea.x + this.diagramArea.width - padding - totalWidth, this.diagramArea.y + padding);
dc.group({ name: 'legend' }).drawRect(pc.x, pc.y, totalWidth, totalHeight, 1, '#aaaaaa', '#ffffff', { opacity: 0.6 });
this.legend.forEach((text, index) => {
const pt = new Point2D(padding, padding + index * (keyHeight + padding) + keyHeight / 2).add(pc);
const styles = this.options.set
? this.options.set[index % this.options.set.length]
: {};
dc.group({ name: `key-${index + 1}` }).setLinePattern(styles.linePattern);
if (styles.linePattern !== LinePattern.DISABLED) {
dc.drawLine(pt, pt.add(new Point2D(keyWidth, 0)), styles.stroke || 1, styles.color || '#000000');
}
dc.setLinePattern(undefined);
this.getDrawPointFu(styles.drawPoint || PointType.NONE)(pt.add(new Point2D(keyWidth / 2, 0)), dc, styles.stroke || 1, styles.color || '#000000', 0, 0);
dc.endGroup()
.setFontSize(8)
.setTextAlign(TextAlign.LEFT)
.drawText(text, pc.add(new Point2D(padding * 2 + keyWidth, padding + index * (keyHeight + padding) + keyHeight * 0.75)), '#000000', 0);
});
dc.endGroup();
}
}
drawVectors(dc, startPoint) {
const pos = new Point2D(this.diagramArea.x, this.diagramArea.y - 2);
const width = this.diagramArea.width;
const height = this.diagramArea.height + 2;
dc.group({
name: 'vectors-tables',
clipRect: {
pos,
width,
height,
},
});
this.pPoints.forEach((points, index) => {
const setIndex = (this.options.set && index % this.options.set.length) || 0;
const stroke = this.options?.set?.[setIndex].stroke || 2;
const color = this.options?.set?.[setIndex].color || '#000000';
const linePattern = this.options?.set?.[setIndex].linePattern;
dc.setLinePattern(this.options?.set?.[setIndex].linePattern).group({
name: `vectors-${index + 1}`,
});
points = points.map((point) => this.diagramPosToSVG(point, startPoint));
points = points.map((point, i) => {
const prev = points[i - 1];
const next = points[i + 1];
if (point.isPtInRect(pos.x, pos.y, width, height) || // current in rect
prev?.isPtInRect(pos.x, pos.y, width, height) || // prev in rect
next?.isPtInRect(pos.x, pos.y, width, height) || // next in rect
(prev && prev.x <= pos.x && point.x >= pos.x + width) || // prev outside left and current outside of right
(next && point.x <= pos.x && next.x >= pos.x + width) // current outside left and next outside of right
) {
return point;
}
return undefined;
})
.filter(pt => pt);
if (linePattern !== LinePattern.DISABLED) {
dc.drawPolyline(points, stroke, color);
}
if (this.options.set) {
if (this.options.set[setIndex].drawPoint &&
this.options.set[setIndex].drawPoint !== PointType.NONE) {
const pointType = this.options.set[setIndex].drawPoint || PointType.NONE;
if (pointType !== PointType.NONE) {
const drawPointFu = this.getDrawPointFu(pointType);
dc.group({ name: 'points-marks' });
points.forEach((point, pIndex) => {
dc.group({
data: {
point: JSON.stringify(point),
pointSvg: JSON.stringify(point),
},
onMouseOver: (g) => this.onPointMouseOver.next(g),
onMouseOut: () => this.onPointMouseOut.next(),
});
drawPointFu(point, dc, stroke, color, pIndex, point.y);
dc.endGroup();
});
dc.endGroup();
}
}
}
dc.endGroup();
});
dc.endGroup();
}
draw(dc) {
dc.clear();
this.xCursorLine = undefined;
this.yCursorLine = undefined;
this.xyCursor = undefined;
this.xScale =
this.diagramArea.width / (this.xMinMax.max - this.xMinMax.min);
this.yScale =
this.diagramArea.height / (this.yMinMax.max - this.yMinMax.min);
const startPoint = new Point2D(this.diagramArea.x, this.diagramArea.y + this.diagramArea.height);
dc.setFontSize(10);
this.drawGreed(dc, startPoint);
this.drawVectors(dc, startPoint);
dc.setLinePattern(LinePattern.NONE);
dc.setTextAlign(TextAlign.CENTER);
dc.setTextBaseline(TextBaseline.ALPHABETIC);
if (this.title) {
dc.setFontSize(30);
dc.drawText(this.title, this.diagramPosToSVG(new Point2D((this.xMinMax.max + this.xMinMax.min) * 0.5, this.yMinMax.max), startPoint).add(new Point2D(0, -20)), '#ff0000', 0);
dc.setFontSize(15);
}
dc.setTextBaseline(TextBaseline.ALPHABETIC)
.setTextAlign(TextAlign.LEFT)
.setFontSize(10);
const lengthXLabel = this.drawXAxis(dc, startPoint);
this.drawYAxis(dc, startPoint);
dc.setTextAlign(TextAlign.CENTER);
if (this.options.xAxis?.display) {
if (this.xLabel) {
dc.drawText(this.xLabel, this.diagramPosToSVG(new Point2D((this.xMinMax.max + this.xMinMax.min) * 0.5, this.yMinMax.min), startPoint).add(new Point2D(0, lengthXLabel + 20)), this.options.xAxis?.color || '#000000', 0);
}
if (this.xK) {
dc.setTextAlign(TextAlign.RIGHT).drawText(`×e${-this.xK}`, this.diagramPosToSVG(new Point2D(this.xMinMax.max, this.yMinMax.min), startPoint).add(new Point2D(0, lengthXLabel + 20)), this.options.xAxis?.color || '#000000', 0);
}
}
dc.setTextAlign(TextAlign.LEFT).setTextBaseline(TextBaseline.ALPHABETIC);
this.drawLegend(dc);
this.redraw.next();
}
setOptions(options) {
if (!options) {
options = {};
}
this.options = {
displayCursor: options.displayCursor,
xAxis: {
...this.options.xAxis,
...options?.xAxis,
},
yAxis: {
...this.options.yAxis,
...options?.yAxis,
},
xMinMax: {
...this.options.xMinMax,
...options?.xMinMax,
},
yMinMax: {
...this.options.xMinMax,
...options?.yMinMax,
},
greed: {
...this.options.greed,
...options?.greed,
},
set: options?.set ||
this.options.set || [
{
color: '#37abc8',
stroke: 2,
linePattern: LinePattern.NONE,
drawPoint: PointType.NONE,
},
{
color: '#ab37c8',
stroke: 2,
linePattern: LinePattern.NONE,
drawPoint: PointType.NONE,
},
{
color: '#ffc837',
stroke: 2,
linePattern: LinePattern.NONE,
drawPoint: PointType.NONE,
},
],
};
}
drawCursor(mousePos, svg) {
if (!this.options?.displayCursor ||
!mousePos ||
this.xScale === undefined ||
this.yScale === undefined) {
return;
}
const legend = svg.querySelector('.legend');
const vectors = svg.querySelector('.vectors-tables');
const append = (element, before) => {
if (before) {
svg.insertBefore(element, before);
}
else {
svg.appendChild(element);
}
};
if (!this.xCursorLine) {
this.xCursorLine = document.createElementNS(ns, 'polyline');
append(this.xCursorLine, vectors || legend);
this.xCursorLine.style.stroke = '#ff0000';
this.xCursorLine.style.strokeWidth = '.2';
}
if (!this.yCursorLine) {
this.yCursorLine = document.createElementNS(ns, 'polyline');
append(this.yCursorLine, vectors || legend);
this.yCursorLine.style.stroke = '#ff0000';
this.yCursorLine.style.strokeWidth = '.2';
}
if (!this.xyCursor) {
this.xyCursor = document.createElementNS(ns, 'text');
append(this.xyCursor, legend);
this.xyCursor.style.fill = '#ff0000';
this.xyCursor.style.textAnchor = 'left';
this.xyCursor.style.fontSize = '8px';
}
if (!this.diagramArea.isPtInRect(mousePos)) {
this.yCursorLine.style.display = 'none';
this.xCursorLine.style.display = 'none';
this.xyCursor.style.display = 'none';
}
else {
this.yCursorLine.style.display = '';
this.xCursorLine.style.display = '';
this.xyCursor.style.display = '';
}
const startPoint = new Point2D(this.diagramArea.x, this.diagramArea.y + this.diagramArea.height);
const diagramPos = this.svgPosToDiagram(mousePos, startPoint, this.xScale, this.yScale);
this.xyCursor.textContent = `${this.decimalPipe.transform(diagramPos.x, '0.3-3')}; ${this.decimalPipe.transform(diagramPos.y, '0.3-3')}`;
this.xyCursor.setAttribute('x', (mousePos.x + 2).toString());
this.xyCursor.setAttribute('y', (mousePos.y - 2).toString());
this.xCursorLine.setAttribute('points', `${this.diagramArea.x},${mousePos.y} ${this.diagramArea.x + this.diagramArea.width},${mousePos.y}`);
this.yCursorLine.setAttribute('points', `${mousePos.x},${this.diagramArea.y} ${mousePos.x},${this.diagramArea.y + this.diagramArea.height}`);
}
svgToDiagram(point) {
const startPoint = new Point2D(this.diagramArea.x, this.diagramArea.y + this.diagramArea.height);
return this.svgPosToDiagram(point, startPoint, this.xScale, this.yScale);
}
getDrawPointFu(pointType) {
const fu = LinearDiagram2D.drawingPoints.get(pointType);
// eslint-disable-next-line no-unneeded-ternary
return fu
? fu
: (point, dc, stroke, color) => { };
}
}
class LinearDiagram2DComponent {
renderer;
dc;
diagram2d;
mousePos = new Point2D();
selectArea;
width = 800;
height = 528;
diagram;
legend = input([]);
points = input([]);
xFormatter = input();
yFormatter = input();
pOptions;
get options() {
return this.pOptions;
}
set options(value) {
this.pOptions = value;
if (this.diagram2d && this.dc) {
this.diagram2d.setOptions(value);
this.diagram2d.draw(this.dc);
}
}
pLabels = {
x: '',
y: '',
title: '',
};
set labels(labels) {
this.pLabels = labels;
if (this.diagram2d) {
this.diagram2d.draw(this.dc);
}
}
diagramPointHover;
subscriptions = [];
constructor(renderer) {
this.renderer = renderer;
effect(() => {
this.points();
this.legend();
this.draw();
});
}
ngOnDestroy() {
this.subscriptions.forEach((subscription) => {
if (!subscription.closed) {
subscription.unsubscribe();
}
});
}
ngAfterContentInit() {
if (this.diagramPointHover && this.diagram2d) {
this.diagramPointHover.onMouseOut = this.diagram2d.onPointMouseOut;
this.diagramPointHover.onMouseOver = this.diagram2d.onPointMouseOver;
}
}
ngAfterViewInit() {
this.draw();
}
pdf() {
const dc = new DrawingPdfInterface(new Rect(new Point2D(0, 0), new Point2D(800, 600), 20, 20));
this.draw(dc);
dc.save(this.diagram2d?.title.length ? this.diagram2d.title : 'Diagram 2D');
}
draw(dc = this.dc) {
if (!dc) {
if (!this.diagram) {
return;
}
this.dc = new DrawingSvgInterface(this.diagram.nativeElement, this.renderer);
dc = this.dc;
}
if (!this.diagram2d) {
this.diagram2d = new LinearDiagram2D(new Rect(new Point2D(120, 50), new Point2D(700, 400)), this.points(), this.options);
if (this.diagramPointHover) {
this.diagramPointHover.onMouseOut = this.diagram2d.onPointMouseOut;
this.diagramPointHover.onMouseOver = this.diagram2d.onPointMouseOver;
}
}
else {
this.diagram2d.points = this.points();
}
this.diagram2d.legend = this.legend();
this.diagram2d.xLabel = this.pLabels.x;
this.diagram2d.yLabel = this.pLabels.y;
this.diagram2d.title = this.pLabels.title;
const xFormatter = this.xFormatter();
if (xFormatter) {
this.diagram2d.xFormatter = xFormatter;
}
const yFormatter = this.yFormatter();
if (yFormatter) {
this.diagram2d.yFormatter = yFormatter;
}
this.diagram2d.draw(dc);
if (dc instanceof DrawingSvgInterface) {
this.diagram2d.drawCursor(this.mousePos, dc.svgContainer);
}
}
move(event) {
const rect = this.diagram.nativeElement.getBoundingClientRect();
this.mousePos = new Point2D(((event.clientX - rect.left) / rect.width) * this.width, ((event.clientY - rect.top) / rect.height) * this.height);
if (!this.diagram2d) {
return;
}
this.diagram2d.drawCursor(this.mousePos, this.diagram.nativeElement);
const area = this.diagram2d.diagramArea;
if (event.buttons === 1 &&
this.mousePos.isPtInRect(area.x, area.y, area.width, area.height)) {
if (this.selectArea) {
this.selectArea.width = this.mousePos.x - this.selectArea.x;
}
else {
const startPoint = new Point2D(this.mousePos.x, this.diagram2d.diagramArea.y);
const endPoint = new Point2D(Math.min(this.mousePos.x, this.diagram2d.diagramArea.x + this.diagram2d.diagramArea.width), this.diagram2d.diagramArea.y + this.diagram2d.diagramArea.height);
this.selectArea = new Rect(startPoint, endPoint);
}
}
}
keyup(event) {
if (!this.diagram2d) {
return;
}
const { selectArea } = this;
if (selectArea) {
const xMin = selectArea.x < selectArea.x + selectArea.width ? selectArea.x : selectArea.x + selectArea.width;
const xMax = selectArea.x < selectArea.x + selectArea.width ? selectArea.x + selectArea.width : selectArea.x;
this.diagram2d.selectionRange = {
min: this.diagram2d.svgToDiagram(new Point2D(xMin, selectArea.y)).x,
max: this.diagram2d.svgToDiagram(new Point2D(xMax, selectArea.y)).x,
};
this.selectArea = undefined;
this.draw();
}
}
left() {
if (!this.diagram2d) {
return;
}
const { selectionRange } = this.diagram2d;
if (selectionRange) {
this.diagram2d.selectionRange = undefined;
const range = selectionRange.max - selectionRange.min;
const minMax = this.diagram2d.getXMinMax();
selectionRange.min = Math.max(selectionRange.min - range, minMax.min);
selectionRange.max = selectionRange.min + range;
this.diagram2d.selectionRange = selectionRange;
this.draw();
}
}
right() {
if (!this.diagram2d) {
return;
}
const { selectionRange } = this.diagram2d;
if (selectionRange) {
this.diagram2d.selectionRange = undefined;
const range = selectionRange.max - selectionRange.min;
const minMax = this.diagram2d.getXMinMax();
selectionRange.max = Math.min(selectionRange.max + range, minMax.max);
selectionRange.min = selectionRange.max - range;
this.diagram2d.selectionRange = selectionRange;
this.draw();
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LinearDiagram2DComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: LinearDiagram2DComponent, isStandalone: false, selector: "obl-linear-diagram-2d", inputs: { legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null }, points: { classPropertyName: "points", publicName: "points", isSignal: true, isRequired: false, transformFunction: null }, xFormatter: { classPropertyName: "xFormatter", publicName: "xFormatter", isSignal: true, isRequired: false, transformFunction: null }, yFormatter: { classPropertyName: "yFormatter", publicName: "yFormatter", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: false, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: false, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "diagramPointHover", first: true, predicate: DiagramPointHoverComponent, descendants: true }], viewQueries: [{ propertyName: "diagram", first: true, predicate: ["diagram"], descendants: true }], ngImport: i0, template: "<div class=\"svgContainer\">\n <svg\n #diagram\n [attr.viewBox]=\"'0 0 ' + width + ' ' + height\"\n (mousemove)=\"move($event)\"\n (mouseup)=\"keyup($event)\"\n >\n @if (selectArea) {\n <rect\n [attr.x]=\"[selectArea.x, selectArea.x + selectArea.width] | oblMin\"\n [attr.y]=\"selectArea.y\"\n [attr.width]=\"([selectArea.width] | oblAbs)[0]\"\n [attr.height]=\"([selectArea.height] | oblAbs)[0]\"\n ></rect>\n }\n <g class=\"root\"></g>\n </svg>\n <div class=\"buttons\">\n <button class=\"pdf-button\" oblButton icon=\"file\" (click)=\"pdf()\"></button>\n @if (diagram2d?.selectionRange) {\n <button\n oblButton\n icon=\"cancel\"\n (click)=\"diagram2d && diagram2d.selectionRange = undefined; this.draw()\"\n ></button>\n <button oblButton icon=\"left\" (click)=\"left()\"></button>\n <button oblButton icon=\"right\" (click)=\"right()\"></button>\n }\n </div>\n <ng-content></ng-content>\n</div>\n", styles: [":host .svgContainer{overflow:auto;max-width:100%;position:relative}:host .svgContainer .buttons{position:absolute;right:20px;top:20px;--obl-default-button-padding: 5px;display:flex}:host .svgContainer .pdf-button{display:none}:host .svgContainer:hover .pdf-button{display:block}svg>rect{fill:var(--obl-linear-2d-select-area-color, #a7f5ff)}svg::ng-deep text{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: i1$1.ButtonDirective, selector: "oblButton, [oblButton]", inputs: ["oblButton", "icon", "blockWhenLoading", "loading", "toggle", "selected", "link", "target"], exportAs: ["oblButton"] }, { kind: "pipe", type: i2.AbsPipe, name: "oblAbs" }, { kind: "pipe", type: i2.MinPipe, name: "oblMin" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LinearDiagram2DComponent, decorators: [{
type: Component,
args: [{ selector: 'obl-linear-diagram-2d', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<div class=\"svgContainer\">\n <svg\n #diagram\n [attr.viewBox]=\"'0 0 ' + width + ' ' + height\"\n (mousemove)=\"move($event)\"\n (mouseup)=\"keyup($event)\"\n >\n @if (selectArea) {\n <rect\n [attr.x]=\"[selectArea.x, selectArea.x + selectArea.width] | oblMin\"\n [attr.y]=\"selectArea.y\"\n [attr.width]=\"([selectArea.width] | oblAbs)[0]\"\n [attr.height]=\"([selectArea.height] | oblAbs)[0]\"\n ></rect>\n }\n <g class=\"root\"></g>\n </svg>\n <div class=\"buttons\">\n <button class=\"pdf-button\" oblButton icon=\"file\" (click)=\"pdf()\"></button>\n @if (diagram2d?.selectionRange) {\n <button\n oblButton\n icon=\"cancel\"\n (click)=\"diagram2d && diagram2d.selectionRange = undefined; this.draw()\"\n ></button>\n <button oblButton icon=\"left\" (click)=\"left()\"></button>\n <button oblButton icon=\"right\" (click)=\"right()\"></button>\n }\n </div>\n <ng-content></ng-content>\n</div>\n", styles: [":host .svgContainer{overflow:auto;max-width:100%;position:relative}:host .svgContainer .buttons{position:absolute;right:20px;top:20px;--obl-default-button-padding: 5px;display:flex}:host .svgContainer .pdf-button{display:none}:host .svgContainer:hover .pdf-button{display:block}svg>rect{fill:var(--obl-linear-2d-select-area-color, #a7f5ff)}svg::ng-deep text{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none}\n"] }]
}], ctorParameters: () => [{ type: i0.Renderer2 }], propDecorators: { diagram: [{
type: ViewChild,
args: ['diagram']
}], options: [{
type: Input
}], labels: [{
type: Input
}], diagramPointHover: [{
type: ContentChild,
args: [DiagramPointHoverComponent]
}] } });
/* eslint-disable @typescript-eslint/no-dynamic-delete */
class DiagramDataFilterComponent {
file;
models = {
smooth: {
filter: (data, options) => {
const tolerance = options?.tolerance.value ?? 0.5;
const sampleSize = options?.sampleSize.value ?? 10;
data.forEach((r, index) => {
const sample = data.slice(index, index + sampleSize).map((d) => d.y);
const max = Math.max(...sample);
const min = Math.min(...sample);
if (max - min < tolerance && sample.length) {
r.y = ElementaryMath.average(sample);
}
});
return data;
},
options: {
tolerance: { value: 0.5, min: 0, max: 5, step: 0.1 },
sampleSize: { value: 10, min: 2, max: 25, step: 1 },
},
},
'index-range': {
filter: (data, options) => {
const start = ElementaryMath.minmax(options?.start?.value ?? 0, 0, data.length - 1);
const end = ElementaryMath.minmax(options?.end?.value ?? data.length, 0, data.length - 1);
return data.slice(start, end);
},
options: {
start: { value: 0 },
end: { value: 20 },
},
},
'x-range': {
filter: (data, options) => {
const start = options?.start?.value || 0;
const end = options?.end?.value || data.length;
return data.filter((v) => v.x >= start && v.x <= end);
},
options: {
start: { value: 0 },
end: { value: 20 },
},
},
'y-range': {
filter: (data, options) => {
const y = data.map(p => p.y);
const start = options?.start?.value ?? Math.min(...y);
const end = options?.end?.value ?? Math.max(...y);
return data.filter((v) => v.y >= start && v.y <= end);
},
options: {
start: { value: 0 },
end: { value: 20, step: 0.1 },
},
},
diff: {
filter: (data, options) => {
const points = [];
data.forEach((p, index) => {
if (index < data.length - 1) {
const pt = data[index + 1].copy();
pt.y = (pt.y - p.y) / (pt.x - p.x);
points.push(pt);
}
});
return points;
},
options: {},
},
'nth-filter': {
filter: (data, options) => {
const nth = options?.nth?.value ?? 1;
return data.filter((_, index) => index % nth === 0);
},
options: {
nth: { value: 1, min: 1, max: 100, step: 1 },
},
},
multiply: {
filter: (data, options) => {
const k = options?.k?.value ?? 1;
return data.map((v) => new Point2D(v.x, v.y * k));
},
options: {
k: { value: 1, step: 0 },
},
},
add: {
filter: (data, options) => {
const add = options?.adding?.value ?? 1;
return data.map((v) => new Point2D(v.x, v.y + add));
},
options: {
adding: { value: 1, step: 0 },
},
},
};
_filters = {};
selected;
lastData;
set filters(filters) {
this._filters = filters;
keysValues(filters).forEach(([name, value]) => (this.models[name].options = value));
}
get filters() {
return this._filters;
}
translations = {};
allow;
filtersChanged = new EventEmitter();
constructor(file) {
this.file = file;
}
filtering(data) {
this.lastData = data;
let copy = data.map((d) => d.copy());
const filters = this.models;
keysValues(this._filters).forEach(([name, value]) => {
filters[name] = { ...value, ...filters[name] };
const filter = filters[name];
copy = filter.filter(copy, filter);
});
return copy;
}
remove(name) {
delete this._filters[name];
this.selected = undefined;
this.changed();
}
changed() {
const filters = keysValues(this.models)
.filter(([name]) => this._filters[name])
.map(([name, value]) => {
return { [name]: { ...value.options } };
})
.reduce((p, c) => ({ ...p, ...c }), {});
this.filtersChanged.emit(filters);
}
compare = (f, s) => {
return 0;
};
download() {
const translationPipe = new TranslationPipe();
if (this.lastData) {
return this.file.saveTextFile(JSON.stringify(this.filtering(this.lastData)), translationPipe.transform('filtered data', this.translations), 'application/json');
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: DiagramDataFilterComponent, deps: [{ token: i1$2.OblFileService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: DiagramDataFilterComponent, isStandalone: false, selector: "obl-diagram-data-filter", inputs: { filters: "filters", translations: "translations", allow: "allow" }, outputs: { filtersChanged: "filtersChanged" }, ngImport: i0, template: "@if ((filters | keyvalue).length) {\n <fieldset class=\"filters\">\n <legend>{{ 'Chosen' | oblTranslation : translations }}</legend>\n <div class=\"items\">\n @for (filter of filters | keyvalue : compare; track filter.key) {\n <div\n class=\"filter\"\n (click)=\"selected = filter.key\"\n >\n <span>{{ filter.key | oblTranslation : translations }}</span>\n <button oblButton icon=\"cancel\" (click)=\"remove(filter.key); $event.stopPropagation()\"></button>\n </div>\n }\n </div>\n <div class=\"buttons\">\n <button oblButton icon=\"save\" (click)=\"download()\"></button>\n <ng-content></ng-content>\n </div>\n </fieldset>\n}\n\n@if ((filters | keyvalue).length !== (allow?.length || (models | keyvalue).length)) {\n <fieldset class=\"filters\">\n <legend>{{ 'Others' | oblTranslation : translations }}</legend>\n <div class=\"items\">\n @for (filter of models | keyvalue : compare; track filter.key) {\n @if (!filters[filter.key] && (!allow || allow.includes(filter.key))) {\n <div\n class=\"filter\"\n (click)=\"filters[filter.key] = filter.value.options; changed()\"\n >\n <span>{{ filter.key | oblTranslation : translations }}</span>\n </div>\n }\n }\n </div>\n </fieldset>\n}\n\n@if (selected && (models[selected].options | keyvalue).length) {\n <div>\n <div class=\"head\">\n {{ 'Edit filter option of name:' | oblTranslation : translations }}\n {{ selected | oblTranslation : translations }}\n </div>\n @for(filter of models[selected].options | keyvalue : compare; track filter.key) {\n <div class=\"filter-option-control\">\n <obl-input-wrapper [label]=\"filter.key | oblTranslation : translations\">\n <input\n oblInput\n type=\"number\"\n [value]=\"filter.value.value\"\n (change)=\"\n models[selected].options[filter.key].value = input.valueAsNumber;\n changed()\n \"\n [step]=\"filter.value.step\"\n [min]=\"filter.value.min\"\n [max]=\"filter.value.max\"\n #input\n />\n </obl-input-wrapper>\n </div>\n }\n </div>\n}", styles: [":root{--obl-primary: #00afaf;--obl-secondary: #008caf;--default-border-color: gray;--default-focus-color: gray;--default-border-outline-color: #080808;--default-disabled-color: gray;--default-background-color: white;--default-hover-color: #eeeeee;--obl-default-error-color: red;--obl-dialog-background: #d3d3d3;--default-radio-color: black;--disabled-color: gray;--default-hex-button-border-color: #008caf;--default-hex-button-hover-border-color: #00afaf;--select-item-background-color: #e4e4e4;--select-item-text-color: #5a5a5a;--default-text-color: black;--obl-default-button-text-color: black;--obl-default-icon-color: black;--equalizer-background-bar-color: #575656;--equalizer-value-bar-color: #e6e6e6;--diagram-3d-background-color: black;--slider-value-container-color: gray;--slider-value-color: #d1d1d1;--slider-hover-value-color: white;--digit-fill-color: #cccccc;--digit-lighted-color: black;--horizontal-progress-bar-value-color: #504f4f;--horizontal-progress-bar-background-pattern-color: #dddddd;--horizontal-progress-bar-value-pattern-color: #b3b3b3;--horizontal-progress-bar-border-rect-color: #cccccc;--temperature-text-color: black;--temperature-path-stroke-color: black;--post-diagram-scale-line-color: #c8c8c8;--volume-channel-secondary-color: gray;--volume-channel-primary-color: #f2f2f2;--arch-progress-secondary-color: #eeeeee;--obl-linear-diagram-greed-color: gray;--obl-rating-selected-color: gold;--obl-rating-color: #cccccc}.filters{display:flex;gap:5px;border:1px solid var(--default-border-color);border-radius:5px;padding:5px;align-items:center;justify-content:space-between}.filters .items{display:flex;flex-wrap:wrap;gap:5px}.filters .filter{background-color:var(--obl-filter-background, #e2e2e2);color:var(--obl-filter-color, gray);padding:5px;border-radius:5px;display:flex;align-items:center;gap:5px;cursor:pointer}.filters .filter:hover{background-color:var(--obl-filter-background-hover, #ebebeb)}.filters .filter button{padding:5px}legend{font-size:12px}.head{padding:10px 10px 5px;font-size:12px}\n"], dependencies: [{ kind: "directive", type: i1$1.ButtonDirective, selector: "oblButton, [oblButton]", inputs: ["oblButton", "icon", "blockWhenLoading", "loading", "toggle", "selected", "link", "target"], exportAs: ["oblButton"] }, { kind: "directive", type: i3.InputDirective, selector: "input[oblInput]", inputs: ["outlined"], exportAs: ["oblInput"] }, { kind: "component", type: i3.InputWrapperComponent, selector: "obl-input-wrapper", inputs: ["label", "display", "cancellable", "step", "errors", "translations", "labelAnimation", "small"], outputs: ["loaded"] }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i5.TranslationPipe, name: "oblTranslation" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: DiagramDataFilterComponent, decorators: [{
type: Component,
args: [{ selector: 'obl-diagram-data-filter', standalone: false, template: "@if ((filters | keyvalue).length) {\n <fieldset class=\"filters\">\n <legend>{{ 'Chosen' | oblTranslation : translations }}</legend>\n <div class=\"items\">\n @for (filter of filters | keyvalue : compare; track filter.key) {\n <div\n class=\"filter\"\n (click)=\"selected = filter.key\"\n >\n <span>{{ filter.key | oblTranslation : translations }}</span>\n <button oblButton icon=\"cancel\" (click)=\"remove(filter.key); $event.stopPropagation()\"></button>\n </div>\n }\n </div>\n <div class=\"buttons\">\n <button oblButton icon=\"save\" (click)=\"download()\"></button>\n <ng-content></ng-content>\n </div>\n </fieldset>\n}\n\n@if ((filters | keyvalue).length !== (allow?.length || (models | keyvalue).length)) {\n <fieldset class=\"filters\">\n <legend>{{ 'Others' | oblTranslation : translations }}</legend>\n <div class=\"items\">\n @for (filter of models | keyvalue : compare; track filter.key) {\n @if (!filters[filter.key] && (!allow || allow.includes(filter.key))) {\n <div\n class=\"filter\"\n (click)=\"filters[filter.key] = filter.value.options; changed()\"\n >\n <span>{{ filter.key | oblTranslation : translations }}</span>\n </div>\n }\n }\n </div>\n </fieldset>\n}\n\n@if (selected && (models[selected].options | keyvalue).length) {\n <div>\n <div class=\"head\">\n {{ 'Edit filter option of name:' | oblTranslation : translations }}\n {{ selected | oblTranslation : translations }}\n </div>\n @for(filter of models[selected].options | keyvalue : compare; track filter.key) {\n <div class=\"filter-option-control\">\n <obl-input-wrapper [label]=\"filter.key | oblTranslation : translations\">\n <input\n oblInput\n type=\"number\"\n [value]=\"filter.value.value\"\n (change)=\"\n models[selected].options[filter.key].value = input.valueAsNumber;\n changed()\n \"\n [step]=\"filter.value.step\"\n [min]=\"filter.value.min\"\n [max]=\"filter.value.max\"\n #input\n />\n </obl-input-wrapper>\n </div>\n }\n </div>\n}", styles: [":root{--obl-primary: #00afaf;--obl-secondary: #008caf;--default-border-color: gray;--default-focus-color: gray;--default-border-outline-color: #080808;--default-disabled-color: gray;--default-background-color: white;--default-hover-color: #eeeeee;--obl-default-error-color: red;--obl-dialog-background: #d3d3d3;--default-radio-color: black;--disabled-color: gray;--default-hex-button-border-color: #008caf;--default-hex-button-hover-border-color: #00afaf;--select-item-background-color: #e4e4e4;--select-item-text-color: #5a5a5a;--default-text-color: black;--obl-default-button-text-color: black;--obl-default-icon-color: black;--equalizer-background-bar-color: #575656;--equalizer-value-bar-color: #e6e6e6;--diagram-3d-background-color: black;--slider-value-container-color: gray;--slider-value-color: #d1d1d1;--slider-hover-value-color: white;--digit-fill-color: #cccccc;--digit-lighted-color: black;--horizontal-progress-bar-value-color: #504f4f;--horizontal-progress-bar-background-pattern-color: #dddddd;--horizontal-progress-bar-value-pattern-color: #b3b3b3;--horizontal-progress-bar-border-rect-color: #cccccc;--temperature-text-color: black;--temperature-path-stroke-color: black;--post-diagram-scale-line-color: #c8c8c8;--volume-channel-secondary-color: gray;--volume-channel-primary-color: #f2f2f2;--arch-progress-secondary-color: #eeeeee;--obl-linear-diagram-greed-color: gray;--obl-rating-selected-color: gold;--obl-rating-color: #cccccc}.filters{display:flex;gap:5px;border:1px solid var(--default-border-color);border-radius:5px;padding:5px;align-items:center;justify-content:space-between}.filters .items{display:flex;flex-wrap:wrap;gap:5px}.filters .filter{background-color:var(--obl-filter-background, #e2e2e2);color:var(--obl-filter-color, gray);padding:5px;border-radius:5px;display:flex;align-items:center;gap:5px;cursor:pointer}.filters .filter:hover{background-color:var(--obl-filter-background-hover, #ebebeb)}.filters .filter button{padding:5px}legend{font-size:12px}.head{padding:10px 10px 5px;font-size:12px}\n"] }]
}], ctorParameters: () => [{ type: i1$2.OblFileService }], propDecorators: { filters: [{
type: Input
}], translations: [{
type: Input
}], allow: [{
type: Input
}], filtersChanged: [{
type: Output
}] } });
class LinearDiagramModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LinearDiagramModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.4", ngImport: i0, type: LinearDiagramModule, declarations: [LinearDiagram2DComponent,
DiagramPointHoverComponent,
DiagramDataFilterComponent], imports: [CommonModule, ButtonsModule, TextPipesModule, InputModule, AbsPipe, MinPipe], exports: [LinearDiagram2DComponent,
DiagramPointHoverComponent,
DiagramDataFilterComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LinearDiagramModule, imports: [CommonModule, ButtonsModule, TextPipesModule, InputModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LinearDiagramModule, decorators: [{
type: NgModule,
args: [{
declarations: [
LinearDiagram2DComponent,
DiagramPointHoverComponent,
DiagramDataFilterComponent,
],
imports: [CommonModule, ButtonsModule, TextPipesModule, InputModule, AbsPipe, MinPipe],
exports: [
LinearDiagram2DComponent,
DiagramPointHoverComponent,
DiagramDataFilterComponent,
],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { DiagramDataFilterComponent, DiagramPointHoverComponent, LinearDiagram2D, LinearDiagram2DComponent, LinearDiagramModule, PointType };
//# sourceMappingURL=obliczeniowo-elementary-linear-diagram.mjs.map