@tetacom/svg-charts 1.7.23 → 1.7.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,12 @@ import { Align, TetaSize } from '@tetacom/ng-components';
2
2
  import { Series } from '../../model/series';
3
3
  import { BasePoint } from '../../model/base-point';
4
4
  import { SeriesType } from '../../model/enum/series-type';
5
+ import { FillType } from '../../model/enum/fill-type';
5
6
  import * as i0 from "@angular/core";
6
7
  export declare class SeriesControlsComponent {
7
8
  private chartService;
9
+ private dialogService;
10
+ private translocoService;
8
11
  protected readonly Align: typeof Align;
9
12
  series: import("@angular/core").InputSignal<Series<BasePoint>[]>;
10
13
  availableSeries: import("@angular/core").Signal<Series<BasePoint>[]>;
@@ -22,14 +25,20 @@ export declare class SeriesControlsComponent {
22
25
  id: SeriesType;
23
26
  value: string;
24
27
  }[];
28
+ fillType: {
29
+ id: FillType;
30
+ value: string;
31
+ }[];
25
32
  setSeriesEnabled(series: Series<BasePoint>, value: boolean): void;
26
33
  setSeriesColor(series: Series<BasePoint>, value: string): void;
27
34
  setSeriesStrokeWidth(series: Series<BasePoint>, value: number): void;
28
35
  setSeriesStrokeDasharray(series: Series<BasePoint>, value: string): void;
29
36
  setSeriesType(series: Series<BasePoint>, value: SeriesType): void;
37
+ setSeriesFillType(series: Series<BasePoint>, value: FillType): void;
30
38
  clear(): void;
31
39
  protected readonly TetaSize: typeof TetaSize;
32
40
  protected readonly SeriesType: typeof SeriesType;
41
+ protected readonly FillType: typeof FillType;
33
42
  static ɵfac: i0.ɵɵFactoryDeclaration<SeriesControlsComponent, never>;
34
43
  static ɵcmp: i0.ɵɵComponentDeclaration<SeriesControlsComponent, "teta-series-controls", never, { "series": { "alias": "series"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
35
44
  }
@@ -7,10 +7,10 @@ import { maxIndex } from 'd3-array';
7
7
  import { toSignal } from '@angular/core/rxjs-interop';
8
8
  import * as i3 from '@angular/platform-browser';
9
9
  import { AsyncPipe, NgTemplateOutlet, KeyValuePipe, NgStyle } from '@angular/common';
10
- import { Align as Align$1, TetaSize, ButtonComponent, DropdownComponent, DropdownContentDirective, DropdownHeadDirective, IconComponent, AccordionComponent, AccordionHeadComponent, AccordionItemComponent, AccordionContentDirective, ColorInputComponent, SelectComponent, SelectOptionDirective, SelectValueDirective, ScrollableComponent, InputComponent } from '@tetacom/ng-components';
10
+ import { DialogService, Align as Align$1, TetaSize, ButtonComponent, DropdownComponent, DropdownContentDirective, DropdownHeadDirective, IconComponent, AccordionComponent, AccordionHeadComponent, AccordionItemComponent, AccordionContentDirective, ColorInputComponent, SelectComponent, SelectOptionDirective, SelectValueDirective, ScrollableComponent, InputComponent } from '@tetacom/ng-components';
11
11
  import * as i1 from '@angular/forms';
12
12
  import { FormsModule } from '@angular/forms';
13
- import { TranslocoPipe } from '@jsverse/transloco';
13
+ import { TranslocoService, TranslocoPipe } from '@jsverse/transloco';
14
14
 
15
15
  const chartConfigPostfix = 'series_config';
16
16
 
@@ -313,6 +313,7 @@ class ChartService {
313
313
  enabled: _.enabled,
314
314
  color: _.color,
315
315
  type: _.type,
316
+ fillType: _.fillType,
316
317
  strokeDasharray: _.style?.strokeDasharray,
317
318
  strokeWidth: _.style?.strokeWidth,
318
319
  };
@@ -331,7 +332,14 @@ class ChartService {
331
332
  serie.visible = found.visible ?? serie.visible;
332
333
  serie.enabled = found.enabled ?? serie.enabled;
333
334
  serie.color = found.color ?? serie.color;
334
- serie.type = parseInt(found.type, 10) ?? serie.type;
335
+ const type = parseInt(found.type, 10);
336
+ if (type !== null && type !== undefined && !isNaN(type)) {
337
+ serie.type = type;
338
+ }
339
+ const fillType = parseInt(found.fillType, 10);
340
+ if (fillType !== null && fillType !== undefined && !isNaN(fillType)) {
341
+ serie.fillType = fillType;
342
+ }
335
343
  if (!serie.style) {
336
344
  serie.style = {};
337
345
  }
@@ -2174,42 +2182,84 @@ class BlockSeriesComponent extends SeriesBaseComponent {
2174
2182
  constructor() {
2175
2183
  super(...arguments);
2176
2184
  this.displayPoints = computed(() => {
2185
+ const domain = this.config().inverted ? this.y().domain() : this.x().domain();
2186
+ const [min, max] = domain;
2177
2187
  return this.series().data.filter((point, index, arr) => {
2178
- const [min, max] = this.y().domain();
2179
- return ((point.y >= min || point.y1 >= min || arr[index + 1]?.y >= min || arr[index + 1]?.y1 >= min) &&
2180
- (point.y <= max || point.y1 <= max || arr[index - 1]?.y <= max || arr[index - 1]?.y1 <= max));
2188
+ const next = arr[index + 1];
2189
+ const secondNext = arr[index + 2];
2190
+ if (this.config().inverted) {
2191
+ if (point.y1 === null || point.y1 === undefined) {
2192
+ point.y1 = next?.y ?? point.y;
2193
+ }
2194
+ if (next && (next.y1 === null || next.y1 === undefined)) {
2195
+ next.y1 = secondNext?.y ?? next.y;
2196
+ }
2197
+ return ((point.y >= min || point.y1 >= min || arr[index + 1]?.y >= min || arr[index + 1]?.y1 >= min) &&
2198
+ (point.y <= max || point.y1 <= max || arr[index - 1]?.y <= max || arr[index - 1]?.y1 <= max));
2199
+ }
2200
+ else {
2201
+ if (point.x1 === null || point.x1 === undefined) {
2202
+ point.x1 = next?.x ?? point.x;
2203
+ }
2204
+ if (next && (next.x1 === null || next.x1 === undefined)) {
2205
+ next.x1 = secondNext?.x ?? next.x;
2206
+ }
2207
+ return ((point.x >= min || point.x1 >= min || arr[index + 1]?.x >= min || arr[index + 1]?.x1 >= min) &&
2208
+ (point.x <= max || point.x1 <= max || arr[index - 1]?.x <= max || arr[index - 1]?.x1 <= max));
2209
+ }
2181
2210
  });
2182
2211
  });
2183
2212
  this.Math = Math;
2184
2213
  this.FillType = FillType;
2185
2214
  }
2186
2215
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: BlockSeriesComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2187
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: BlockSeriesComponent, isStandalone: true, selector: "svg:svg[teta-block-series]", usesInheritance: true, ngImport: i0, template: "@if ({ y: y(), x: x(), points: displayPoints() }; as data) {\n @if (series()?.fillType === FillType.gradient) {\n <svg:defs>\n <svg:linearGradient\n [id]=\"'gradient-fill-' + id\"\n gradientUnits=\"userSpaceOnUse\"\n x1=\"0%\"\n [attr.y1]=\"config()?.inverted ? '0%' : '100%'\"\n [attr.x2]=\"config()?.inverted ? '100%' : '0%'\"\n y2=\"0%\"\n >\n <svg:stop offset=\"0%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0\"></svg:stop>\n <svg:stop offset=\"5%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.1\"></svg:stop>\n <svg:stop offset=\"20%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.2\"></svg:stop>\n <svg:stop offset=\"60%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.5\"></svg:stop>\n <svg:stop offset=\"100%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.9\"></svg:stop>\n </svg:linearGradient>\n </svg:defs>\n }\n @if (data.x && data.y) {\n @for (point of data.points; track point) {\n <svg:g (mouseenter)=\"mouseenter(point)\" (mouseleave)=\"mouseleave(point)\">\n <svg:rect\n x=\"0\"\n [attr.y]=\"data.y(point.y)\"\n [attr.height]=\"Math.abs(data.y(point.y1) - data.y(point.y))\"\n [attr.fill]=\"\n series().fillType === FillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().style?.fill ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"\n width=\"100%\"\n ></svg:rect>\n @if (point.text && data.y(point.y1) - data.y(point.y) > 8) {\n <svg:text\n x=\"50%\"\n [attr.y]=\"(data.y(point.y1) + data.y(point.y)) / 2\"\n alignment-baseline=\"middle\"\n text-anchor=\"middle\"\n >\n {{ point.text }}\n </svg:text>\n }\n <svg:line\n x1=\"0\"\n x2=\"100%\"\n [attr.y1]=\"data.y(point.y)\"\n [attr.y2]=\"data.y(point.y)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n <svg:line\n x1=\"0\"\n x2=\"100%\"\n [attr.y1]=\"data.y(point.y1)\"\n [attr.y2]=\"data.y(point.y1)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n </svg:g>\n }\n }\n}\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2216
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: BlockSeriesComponent, isStandalone: true, selector: "svg:svg[teta-block-series]", usesInheritance: true, ngImport: i0, template: "@if ({ y: y(), x: x(), points: displayPoints() }; as data) {\n @if (series()?.fillType === FillType.gradient) {\n <svg:defs>\n <svg:linearGradient\n [id]=\"'gradient-fill-' + id\"\n gradientUnits=\"userSpaceOnUse\"\n x1=\"0%\"\n [attr.y1]=\"config()?.inverted ? '0%' : '100%'\"\n [attr.x2]=\"config()?.inverted ? '100%' : '0%'\"\n y2=\"0%\">\n <svg:stop offset=\"0%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0\"></svg:stop>\n <svg:stop offset=\"5%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.1\"></svg:stop>\n <svg:stop offset=\"20%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.2\"></svg:stop>\n <svg:stop offset=\"60%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.5\"></svg:stop>\n <svg:stop offset=\"100%\" [attr.stop-color]=\"series().style?.fill ?? series().color\"\n stop-opacity=\"0.9\"></svg:stop>\n </svg:linearGradient>\n </svg:defs>\n }\n @if (data.x && data.y) {\n @if (config()?.inverted) {\n @for (point of data.points; track index; let index = $index) {\n <svg:g (mouseenter)=\"mouseenter(point)\" (mouseleave)=\"mouseleave(point)\">\n <svg:rect\n x=\"0\"\n [attr.y]=\"data.y(point.y)\"\n [attr.height]=\"Math.abs(data.y(point.y1) - data.y(point.y))\"\n [attr.fill]=\"\n series().fillType === FillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().style?.fill ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"\n width=\"100%\"\n ></svg:rect>\n @if (point.text && data.y(point.y1) - data.y(point.y) > 8) {\n <svg:text\n x=\"50%\"\n [attr.y]=\"(data.y(point.y1) + data.y(point.y)) / 2\"\n alignment-baseline=\"middle\"\n text-anchor=\"middle\"\n >\n {{ point.text }}\n </svg:text>\n }\n <svg:line\n x1=\"0\"\n x2=\"100%\"\n [attr.y1]=\"data.y(point.y)\"\n [attr.y2]=\"data.y(point.y)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n <svg:line\n x1=\"0\"\n x2=\"100%\"\n [attr.y1]=\"data.y(point.y1)\"\n [attr.y2]=\"data.y(point.y1)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n </svg:g>\n }\n } @else {\n @for (point of data.points; track index; let index = $index) {\n <svg:g (mouseenter)=\"mouseenter(point)\" (mouseleave)=\"mouseleave(point)\">\n <svg:rect\n y=\"0\"\n height=\"100%\"\n [attr.x]=\"data.x(point.x)\"\n [attr.width]=\"Math.abs(data.x(point.x1) - data.x(point.x))\"\n [attr.fill]=\"\n series().fillType === FillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().style?.fill ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"\n\n ></svg:rect>\n @if (point.text && data.x(point.x1) - data.x(point.x) > 8) {\n <svg:text\n x=\"50%\"\n [attr.x]=\"(data.x(point.x1) + data.x(point.x)) / 2\"\n alignment-baseline=\"middle\"\n text-anchor=\"middle\"\n >\n {{ point.text }}\n </svg:text>\n }\n <svg:line\n y1=\"0\"\n y2=\"100%\"\n [attr.x1]=\"data.x(point.x)\"\n [attr.x2]=\"data.x(point.x)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n <svg:line\n y1=\"0\"\n y2=\"100%\"\n [attr.x1]=\"data.x(point.x1)\"\n [attr.x2]=\"data.x(point.x1)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n </svg:g>\n }\n }\n }\n}\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2188
2217
  }
2189
2218
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: BlockSeriesComponent, decorators: [{
2190
2219
  type: Component,
2191
- args: [{ selector: 'svg:svg[teta-block-series]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AsyncPipe], template: "@if ({ y: y(), x: x(), points: displayPoints() }; as data) {\n @if (series()?.fillType === FillType.gradient) {\n <svg:defs>\n <svg:linearGradient\n [id]=\"'gradient-fill-' + id\"\n gradientUnits=\"userSpaceOnUse\"\n x1=\"0%\"\n [attr.y1]=\"config()?.inverted ? '0%' : '100%'\"\n [attr.x2]=\"config()?.inverted ? '100%' : '0%'\"\n y2=\"0%\"\n >\n <svg:stop offset=\"0%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0\"></svg:stop>\n <svg:stop offset=\"5%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.1\"></svg:stop>\n <svg:stop offset=\"20%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.2\"></svg:stop>\n <svg:stop offset=\"60%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.5\"></svg:stop>\n <svg:stop offset=\"100%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.9\"></svg:stop>\n </svg:linearGradient>\n </svg:defs>\n }\n @if (data.x && data.y) {\n @for (point of data.points; track point) {\n <svg:g (mouseenter)=\"mouseenter(point)\" (mouseleave)=\"mouseleave(point)\">\n <svg:rect\n x=\"0\"\n [attr.y]=\"data.y(point.y)\"\n [attr.height]=\"Math.abs(data.y(point.y1) - data.y(point.y))\"\n [attr.fill]=\"\n series().fillType === FillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().style?.fill ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"\n width=\"100%\"\n ></svg:rect>\n @if (point.text && data.y(point.y1) - data.y(point.y) > 8) {\n <svg:text\n x=\"50%\"\n [attr.y]=\"(data.y(point.y1) + data.y(point.y)) / 2\"\n alignment-baseline=\"middle\"\n text-anchor=\"middle\"\n >\n {{ point.text }}\n </svg:text>\n }\n <svg:line\n x1=\"0\"\n x2=\"100%\"\n [attr.y1]=\"data.y(point.y)\"\n [attr.y2]=\"data.y(point.y)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n <svg:line\n x1=\"0\"\n x2=\"100%\"\n [attr.y1]=\"data.y(point.y1)\"\n [attr.y2]=\"data.y(point.y1)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n </svg:g>\n }\n }\n}\n" }]
2220
+ args: [{ selector: 'svg:svg[teta-block-series]', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if ({ y: y(), x: x(), points: displayPoints() }; as data) {\n @if (series()?.fillType === FillType.gradient) {\n <svg:defs>\n <svg:linearGradient\n [id]=\"'gradient-fill-' + id\"\n gradientUnits=\"userSpaceOnUse\"\n x1=\"0%\"\n [attr.y1]=\"config()?.inverted ? '0%' : '100%'\"\n [attr.x2]=\"config()?.inverted ? '100%' : '0%'\"\n y2=\"0%\">\n <svg:stop offset=\"0%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0\"></svg:stop>\n <svg:stop offset=\"5%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.1\"></svg:stop>\n <svg:stop offset=\"20%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.2\"></svg:stop>\n <svg:stop offset=\"60%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.5\"></svg:stop>\n <svg:stop offset=\"100%\" [attr.stop-color]=\"series().style?.fill ?? series().color\"\n stop-opacity=\"0.9\"></svg:stop>\n </svg:linearGradient>\n </svg:defs>\n }\n @if (data.x && data.y) {\n @if (config()?.inverted) {\n @for (point of data.points; track index; let index = $index) {\n <svg:g (mouseenter)=\"mouseenter(point)\" (mouseleave)=\"mouseleave(point)\">\n <svg:rect\n x=\"0\"\n [attr.y]=\"data.y(point.y)\"\n [attr.height]=\"Math.abs(data.y(point.y1) - data.y(point.y))\"\n [attr.fill]=\"\n series().fillType === FillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().style?.fill ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"\n width=\"100%\"\n ></svg:rect>\n @if (point.text && data.y(point.y1) - data.y(point.y) > 8) {\n <svg:text\n x=\"50%\"\n [attr.y]=\"(data.y(point.y1) + data.y(point.y)) / 2\"\n alignment-baseline=\"middle\"\n text-anchor=\"middle\"\n >\n {{ point.text }}\n </svg:text>\n }\n <svg:line\n x1=\"0\"\n x2=\"100%\"\n [attr.y1]=\"data.y(point.y)\"\n [attr.y2]=\"data.y(point.y)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n <svg:line\n x1=\"0\"\n x2=\"100%\"\n [attr.y1]=\"data.y(point.y1)\"\n [attr.y2]=\"data.y(point.y1)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n </svg:g>\n }\n } @else {\n @for (point of data.points; track index; let index = $index) {\n <svg:g (mouseenter)=\"mouseenter(point)\" (mouseleave)=\"mouseleave(point)\">\n <svg:rect\n y=\"0\"\n height=\"100%\"\n [attr.x]=\"data.x(point.x)\"\n [attr.width]=\"Math.abs(data.x(point.x1) - data.x(point.x))\"\n [attr.fill]=\"\n series().fillType === FillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().style?.fill ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"\n\n ></svg:rect>\n @if (point.text && data.x(point.x1) - data.x(point.x) > 8) {\n <svg:text\n x=\"50%\"\n [attr.x]=\"(data.x(point.x1) + data.x(point.x)) / 2\"\n alignment-baseline=\"middle\"\n text-anchor=\"middle\"\n >\n {{ point.text }}\n </svg:text>\n }\n <svg:line\n y1=\"0\"\n y2=\"100%\"\n [attr.x1]=\"data.x(point.x)\"\n [attr.x2]=\"data.x(point.x)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n <svg:line\n y1=\"0\"\n y2=\"100%\"\n [attr.x1]=\"data.x(point.x1)\"\n [attr.x2]=\"data.x(point.x1)\"\n [attr.stroke]=\"point.iconId ? 'var(--color-text-10)' : (point.color ?? series().style?.stroke ?? series().color)\"\n ></svg:line>\n </svg:g>\n }\n }\n }\n}\n" }]
2192
2221
  }] });
2193
2222
 
2194
2223
  class BlockAreaSeriesComponent extends SeriesBaseComponent {
2195
2224
  constructor() {
2196
2225
  super(...arguments);
2197
2226
  this.displayPoints = computed(() => {
2227
+ const domain = this.config().inverted ? this.y().domain() : this.x().domain();
2228
+ const [min, max] = domain;
2198
2229
  return this.series().data.filter((point, index, arr) => {
2199
- const [min, max] = this.y().domain();
2200
- return ((point.y >= min || point.y1 >= min || arr[index + 1]?.y >= min || arr[index + 1]?.y1 >= min) &&
2201
- (point.y <= max || point.y1 <= max || arr[index - 1]?.y <= max || arr[index - 1]?.y1 <= max));
2230
+ const next = arr[index + 1];
2231
+ const secondNext = arr[index + 2];
2232
+ if (this.config().inverted) {
2233
+ if (point.y1 === null || point.y1 === undefined) {
2234
+ point.y1 = next?.y ?? point.y;
2235
+ }
2236
+ if (next && (next.y1 === null || next.y1 === undefined)) {
2237
+ next.y1 = secondNext?.y ?? next.y;
2238
+ }
2239
+ return ((point.y >= min || point.y1 >= min || arr[index + 1]?.y >= min || arr[index + 1]?.y1 >= min) &&
2240
+ (point.y <= max || point.y1 <= max || arr[index - 1]?.y <= max || arr[index - 1]?.y1 <= max));
2241
+ }
2242
+ else {
2243
+ if (point.x1 === null || point.x1 === undefined) {
2244
+ point.x1 = next?.x ?? point.x;
2245
+ }
2246
+ if (next && (next.x1 === null || next.x1 === undefined)) {
2247
+ next.x1 = secondNext?.x ?? next.x;
2248
+ }
2249
+ return ((point.x >= min || point.x1 >= min || arr[index + 1]?.x >= min || arr[index + 1]?.x1 >= min) &&
2250
+ (point.x <= max || point.x1 <= max || arr[index - 1]?.x <= max || arr[index - 1]?.x1 <= max));
2251
+ }
2202
2252
  });
2203
2253
  });
2204
2254
  this.fillType = FillType;
2205
2255
  this.Math = Math;
2206
2256
  }
2207
2257
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: BlockAreaSeriesComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2208
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: BlockAreaSeriesComponent, isStandalone: true, selector: "svg:svg[teta-block-area-series]", usesInheritance: true, ngImport: i0, template: "@if ({ y: y(), x: x(), points: displayPoints() }; as data) {\n @if (series()?.fillType === fillType.gradient) {\n <svg:defs>\n <svg:linearGradient [id]=\"'gradient-fill-' + id\"\n gradientUnits=\"userSpaceOnUse\"\n x1=\"0%\"\n [attr.y1]=\"config()?.inverted ? '0%' : '100%'\"\n [attr.x2]=\"config()?.inverted ? '100%' : '0%'\"\n y2=\"0%\">\n <svg:stop offset=\"0%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0\"></svg:stop>\n <svg:stop offset=\"5%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.1\"></svg:stop>\n <svg:stop offset=\"20%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.2\"></svg:stop>\n <svg:stop offset=\"60%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.5\"></svg:stop>\n <svg:stop offset=\"100%\" [attr.stop-color]=\"series().style?.fill ?? series().color\"\n stop-opacity=\"0.9\"></svg:stop>\n </svg:linearGradient>\n </svg:defs>\n }\n @if (data.x && data.y) {\n @for (point of data.points; track point) {\n <svg:g (mouseenter)=\"mouseenter(point)\" (mouseleave)=\"mouseleave(point)\">\n @if (!!config().inverted) {\n <svg:rect [attr.x]=\"data.x(0) < data.x(point.x) ? data.x(0) : data.x(point.x)\"\n [attr.y]=\"data.y(point.y)\"\n [attr.height]=\"Math.abs(data.y(point.y1) - data.y(point.y))\"\n [attr.width]=\"data.x(0) < data.x(point.x) ? data.x(point.x) - data.x(0) : data.x(0) - data.x(point.x)\"\n [attr.stroke]=\"point.iconId ? '' : (point.color ?? series().style?.stroke ?? series().color)\"\n [attr.stroke-dasharray]=\"series().style?.strokeDasharray\"\n [attr.stroke-width]=\"series().style?.strokeWidth\"\n [attr.fill]=\"\n series().fillType === fillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().style?.fill ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"></svg:rect>\n } @else {\n <svg:rect [attr.x]=\"data.x(point.x)\"\n [attr.y]=\"data.y(0)\"\n [attr.height]=\"Math.abs(data.y(0) - data.y(point.y))\"\n [attr.width]=\"data.x(point.x1) - data.x(point.x)\"\n [attr.stroke]=\"point.iconId ? '' : (point.color ?? series().color)\"\n [attr.stroke-dasharray]=\"series().style?.strokeDasharray\"\n [attr.stroke-width]=\"series().style?.strokeWidth\"\n [attr.fill]=\"\n series().fillType === fillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"></svg:rect>\n }\n @if (point.text) {\n <svg:text x=\"50%\"\n fill=\"var(--color-text-50)\"\n [attr.y]=\"(data.y(point.y1) + data.y(point.y)) / 2\"\n alignment-baseline=\"middle\"\n text-anchor=\"middle\">\n {{ point.text }}\n </svg:text>\n }\n </svg:g>\n }\n }\n}\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2258
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: BlockAreaSeriesComponent, isStandalone: true, selector: "svg:svg[teta-block-area-series]", usesInheritance: true, ngImport: i0, template: "@if ({ y: y(), x: x(), points: displayPoints() }; as data) {\n @if (series()?.fillType === fillType.gradient) {\n <svg:defs>\n <svg:linearGradient [id]=\"'gradient-fill-' + id\"\n gradientUnits=\"userSpaceOnUse\"\n x1=\"0%\"\n [attr.y1]=\"config()?.inverted ? '0%' : '100%'\"\n [attr.x2]=\"config()?.inverted ? '100%' : '0%'\"\n y2=\"0%\">\n <svg:stop offset=\"0%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0\"></svg:stop>\n <svg:stop offset=\"5%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.1\"></svg:stop>\n <svg:stop offset=\"20%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.2\"></svg:stop>\n <svg:stop offset=\"60%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.5\"></svg:stop>\n <svg:stop offset=\"100%\" [attr.stop-color]=\"series().style?.fill ?? series().color\"\n stop-opacity=\"0.9\"></svg:stop>\n </svg:linearGradient>\n </svg:defs>\n }\n @if (data.x && data.y) {\n @for (point of data.points; track $index) {\n <svg:g (mouseenter)=\"mouseenter(point)\" (mouseleave)=\"mouseleave(point)\">\n @if (!!config().inverted) {\n <svg:rect [attr.x]=\"data.x(0) < data.x(point.x) ? data.x(0) : data.x(point.x)\"\n [attr.y]=\"data.y(point.y)\"\n [attr.height]=\"Math.abs(data.y(point.y1) - data.y(point.y))\"\n [attr.width]=\"data.x(0) < data.x(point.x) ? data.x(point.x) - data.x(0) : data.x(0) - data.x(point.x)\"\n [attr.stroke]=\"point.iconId ? '' : (point.color ?? series().style?.stroke ?? series().color)\"\n [attr.stroke-dasharray]=\"series().style?.strokeDasharray\"\n [attr.stroke-width]=\"series().style?.strokeWidth\"\n [attr.fill]=\"\n series().fillType === fillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().style?.fill ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"></svg:rect>\n } @else {\n <svg:rect [attr.x]=\"data.x(point.x)\"\n [attr.y]=\"point.y > 0 ? data.y(point.y) : data.y(0)\"\n [attr.height]=\"Math.abs(data.y(0) - data.y(point.y))\"\n [attr.width]=\"Math.abs(data.x(point.x1) - data.x(point.x))\"\n [attr.stroke]=\"point.iconId ? '' : (point.color ?? series().color)\"\n [attr.stroke-dasharray]=\"series().style?.strokeDasharray\"\n [attr.stroke-width]=\"series().style?.strokeWidth\"\n [attr.fill]=\"\n series().fillType === fillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"></svg:rect>\n }\n @if (point.text) {\n <svg:text x=\"50%\"\n fill=\"var(--color-text-50)\"\n [attr.y]=\"(data.y(point.y1) + data.y(point.y)) / 2\"\n alignment-baseline=\"middle\"\n text-anchor=\"middle\">\n {{ point.text }}\n </svg:text>\n }\n </svg:g>\n }\n }\n}\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2209
2259
  }
2210
2260
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: BlockAreaSeriesComponent, decorators: [{
2211
2261
  type: Component,
2212
- args: [{ selector: 'svg:svg[teta-block-area-series]', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if ({ y: y(), x: x(), points: displayPoints() }; as data) {\n @if (series()?.fillType === fillType.gradient) {\n <svg:defs>\n <svg:linearGradient [id]=\"'gradient-fill-' + id\"\n gradientUnits=\"userSpaceOnUse\"\n x1=\"0%\"\n [attr.y1]=\"config()?.inverted ? '0%' : '100%'\"\n [attr.x2]=\"config()?.inverted ? '100%' : '0%'\"\n y2=\"0%\">\n <svg:stop offset=\"0%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0\"></svg:stop>\n <svg:stop offset=\"5%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.1\"></svg:stop>\n <svg:stop offset=\"20%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.2\"></svg:stop>\n <svg:stop offset=\"60%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.5\"></svg:stop>\n <svg:stop offset=\"100%\" [attr.stop-color]=\"series().style?.fill ?? series().color\"\n stop-opacity=\"0.9\"></svg:stop>\n </svg:linearGradient>\n </svg:defs>\n }\n @if (data.x && data.y) {\n @for (point of data.points; track point) {\n <svg:g (mouseenter)=\"mouseenter(point)\" (mouseleave)=\"mouseleave(point)\">\n @if (!!config().inverted) {\n <svg:rect [attr.x]=\"data.x(0) < data.x(point.x) ? data.x(0) : data.x(point.x)\"\n [attr.y]=\"data.y(point.y)\"\n [attr.height]=\"Math.abs(data.y(point.y1) - data.y(point.y))\"\n [attr.width]=\"data.x(0) < data.x(point.x) ? data.x(point.x) - data.x(0) : data.x(0) - data.x(point.x)\"\n [attr.stroke]=\"point.iconId ? '' : (point.color ?? series().style?.stroke ?? series().color)\"\n [attr.stroke-dasharray]=\"series().style?.strokeDasharray\"\n [attr.stroke-width]=\"series().style?.strokeWidth\"\n [attr.fill]=\"\n series().fillType === fillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().style?.fill ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"></svg:rect>\n } @else {\n <svg:rect [attr.x]=\"data.x(point.x)\"\n [attr.y]=\"data.y(0)\"\n [attr.height]=\"Math.abs(data.y(0) - data.y(point.y))\"\n [attr.width]=\"data.x(point.x1) - data.x(point.x)\"\n [attr.stroke]=\"point.iconId ? '' : (point.color ?? series().color)\"\n [attr.stroke-dasharray]=\"series().style?.strokeDasharray\"\n [attr.stroke-width]=\"series().style?.strokeWidth\"\n [attr.fill]=\"\n series().fillType === fillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"></svg:rect>\n }\n @if (point.text) {\n <svg:text x=\"50%\"\n fill=\"var(--color-text-50)\"\n [attr.y]=\"(data.y(point.y1) + data.y(point.y)) / 2\"\n alignment-baseline=\"middle\"\n text-anchor=\"middle\">\n {{ point.text }}\n </svg:text>\n }\n </svg:g>\n }\n }\n}\n" }]
2262
+ args: [{ selector: 'svg:svg[teta-block-area-series]', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if ({ y: y(), x: x(), points: displayPoints() }; as data) {\n @if (series()?.fillType === fillType.gradient) {\n <svg:defs>\n <svg:linearGradient [id]=\"'gradient-fill-' + id\"\n gradientUnits=\"userSpaceOnUse\"\n x1=\"0%\"\n [attr.y1]=\"config()?.inverted ? '0%' : '100%'\"\n [attr.x2]=\"config()?.inverted ? '100%' : '0%'\"\n y2=\"0%\">\n <svg:stop offset=\"0%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0\"></svg:stop>\n <svg:stop offset=\"5%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.1\"></svg:stop>\n <svg:stop offset=\"20%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.2\"></svg:stop>\n <svg:stop offset=\"60%\" [attr.stop-color]=\"series().style?.fill ?? series().color\" stop-opacity=\"0.5\"></svg:stop>\n <svg:stop offset=\"100%\" [attr.stop-color]=\"series().style?.fill ?? series().color\"\n stop-opacity=\"0.9\"></svg:stop>\n </svg:linearGradient>\n </svg:defs>\n }\n @if (data.x && data.y) {\n @for (point of data.points; track $index) {\n <svg:g (mouseenter)=\"mouseenter(point)\" (mouseleave)=\"mouseleave(point)\">\n @if (!!config().inverted) {\n <svg:rect [attr.x]=\"data.x(0) < data.x(point.x) ? data.x(0) : data.x(point.x)\"\n [attr.y]=\"data.y(point.y)\"\n [attr.height]=\"Math.abs(data.y(point.y1) - data.y(point.y))\"\n [attr.width]=\"data.x(0) < data.x(point.x) ? data.x(point.x) - data.x(0) : data.x(0) - data.x(point.x)\"\n [attr.stroke]=\"point.iconId ? '' : (point.color ?? series().style?.stroke ?? series().color)\"\n [attr.stroke-dasharray]=\"series().style?.strokeDasharray\"\n [attr.stroke-width]=\"series().style?.strokeWidth\"\n [attr.fill]=\"\n series().fillType === fillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().style?.fill ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"></svg:rect>\n } @else {\n <svg:rect [attr.x]=\"data.x(point.x)\"\n [attr.y]=\"point.y > 0 ? data.y(point.y) : data.y(0)\"\n [attr.height]=\"Math.abs(data.y(0) - data.y(point.y))\"\n [attr.width]=\"Math.abs(data.x(point.x1) - data.x(point.x))\"\n [attr.stroke]=\"point.iconId ? '' : (point.color ?? series().color)\"\n [attr.stroke-dasharray]=\"series().style?.strokeDasharray\"\n [attr.stroke-width]=\"series().style?.strokeWidth\"\n [attr.fill]=\"\n series().fillType === fillType.gradient\n ? 'url(#gradient-fill-' + id + ')'\n : point.iconId\n ? 'url(#pattern' + point.iconId + ')'\n : (point.color ?? series().color)\n \"\n [attr.fill-opacity]=\"series().style?.fillOpacity\"></svg:rect>\n }\n @if (point.text) {\n <svg:text x=\"50%\"\n fill=\"var(--color-text-50)\"\n [attr.y]=\"(data.y(point.y1) + data.y(point.y)) / 2\"\n alignment-baseline=\"middle\"\n text-anchor=\"middle\">\n {{ point.text }}\n </svg:text>\n }\n </svg:g>\n }\n }\n}\n" }]
2213
2263
  }] });
2214
2264
 
2215
2265
  class AreaSeriesComponent extends LinearSeriesBaseComponent {
@@ -2636,6 +2686,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
2636
2686
  class SeriesControlsComponent {
2637
2687
  constructor() {
2638
2688
  this.chartService = inject(ChartService);
2689
+ this.dialogService = inject(DialogService);
2690
+ this.translocoService = inject(TranslocoService);
2639
2691
  this.Align = Align$1;
2640
2692
  this.series = input();
2641
2693
  this.availableSeries = computed(() => {
@@ -2668,8 +2720,13 @@ class SeriesControlsComponent {
2668
2720
  { id: SeriesType.blockArea, value: 'BlockArea' },
2669
2721
  { id: SeriesType.bar, value: 'Bar' },
2670
2722
  ];
2723
+ this.fillType = [
2724
+ { id: FillType.default, value: 'Default' },
2725
+ { id: FillType.gradient, value: 'Gradient' },
2726
+ ];
2671
2727
  this.TetaSize = TetaSize;
2672
2728
  this.SeriesType = SeriesType;
2729
+ this.FillType = FillType;
2673
2730
  }
2674
2731
  setSeriesEnabled(series, value) {
2675
2732
  series.enabled = value;
@@ -2696,13 +2753,28 @@ class SeriesControlsComponent {
2696
2753
  setSeriesType(series, value) {
2697
2754
  series.type = value;
2698
2755
  series.component = defaultSeriesTypeMapping.get(series.type) || LineSeriesComponent;
2756
+ if (value === SeriesType.area || value === SeriesType.blockArea || value === SeriesType.block) {
2757
+ series.fillType = FillType.gradient;
2758
+ }
2759
+ this.chartService.updateSeries(series);
2760
+ }
2761
+ setSeriesFillType(series, value) {
2762
+ series.fillType = value;
2699
2763
  this.chartService.updateSeries(series);
2700
2764
  }
2701
2765
  clear() {
2702
- this.chartService.clearSeriesSettings();
2766
+ this.dialogService
2767
+ .confirm({
2768
+ title: this.translocoService.translate('chart.confirm_settings_reset'),
2769
+ })
2770
+ .subscribe((result) => {
2771
+ if (result) {
2772
+ this.chartService.clearSeriesSettings();
2773
+ }
2774
+ });
2703
2775
  }
2704
2776
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SeriesControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2705
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SeriesControlsComponent, isStandalone: true, selector: "teta-series-controls", inputs: { series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<teta-dropdown [align]=\"Align.right\"\n #dropdown=\"dropdown\"\n [appendToBody]=\"true\">\n <button teta-button\n tetaDropdownHead\n [class.active]=\"dropdown.open\"\n [palette]=\"'text'\"\n [view]=\"'ghost'\">\n <teta-icon [name]=\"'gear'\"></teta-icon>\n {{ 'charts.settings' | transloco }}\n </button>\n <div tetaDropdownContent class=\"column shadow-2\" style=\"min-width: 200px;\">\n @if (disabledSeries().length > 0) {\n <div class=\"row padding-h-3 padding-top-3\">\n <teta-dropdown [align]=\"Align.left\" [appendToBody]=\"true\">\n <button teta-button\n tetaDropdownHead\n [palette]=\"'primary'\">\n <teta-icon [name]=\"'add'\"></teta-icon>\n {{ 'charts.add_curve' | transloco }}\n </button>\n <div tetaDropdownContent class=\"column list shadow-2\" style=\"min-width: 200px;\"\n (click)=\"$event.stopPropagation();\">\n @for (seriesItem of disabledSeries(); track seriesItem.id) {\n <div class=\"list-item list-item_interactive\"\n (click)=\"$event.stopPropagation();setSeriesEnabled(seriesItem, true)\">\n {{ seriesItem.name }}\n </div>\n }\n </div>\n </teta-dropdown>\n </div>\n }\n <teta-scrollable class=\"column column_auto\" [contentClass]=\"'column'\">\n <teta-accordion>\n @for (seriesItem of enabledSeries(); track seriesItem.id) {\n <teta-accordion-item [viewType]=\"'rounded'\" [divider]=\"true\">\n <teta-accordion-head style=\"padding: 2px 8px\">\n <div class=\"row align-center gap-12\">\n <div class=\"row align-center gap-8\" (click)=\"$event.stopPropagation()\">\n <teta-button (click)=\"setSeriesEnabled(seriesItem, false)\"\n [palette]=\"'text'\"\n [view]=\"'ghost'\"\n [square]=\"true\">\n <teta-icon [name]=\"'delete'\" [palette]=\"'red'\"></teta-icon>\n </teta-button>\n <teta-color-input [ngModel]=\"seriesItem.color\"\n (ngModelChange)=\"setSeriesColor(seriesItem, $event)\"></teta-color-input>\n </div>\n {{ seriesItem.name }}\n </div>\n </teta-accordion-head>\n <ng-template tetaAccordionContent>\n <div class=\"column gap-8\">\n <teta-input [label]=\"'charts.line_width' | transloco\">\n <teta-select [options]=\"strokeWidth\"\n [ngModel]=\"seriesItem.style?.strokeWidth ?? 1\"\n [valueRef]=\"'id'\"\n (ngModelChange)=\"setSeriesStrokeWidth(seriesItem, $event)\"\n [allowNull]=\"false\">\n <ng-template tetaSelectOption let-option>\n <div style=\"width: 50px;\"\n [style.height.px]=\"option.id\"\n [style.background-color]=\"seriesItem.color\"></div>\n </ng-template>\n <ng-template tetaSelectValue let-value>\n <div style=\"width: 50px;\"\n [style.height.px]=\"value?.id\"\n [style.background-color]=\"seriesItem.color\"></div>\n </ng-template>\n </teta-select>\n </teta-input>\n <teta-input [label]=\"'charts.line_style' | transloco\">\n <teta-select [options]=\"strokeArray\"\n [ngModel]=\"seriesItem.style?.strokeDasharray ?? ''\"\n [valueRef]=\"'id'\"\n (ngModelChange)=\"setSeriesStrokeDasharray(seriesItem, $event)\"\n [allowNull]=\"false\">\n <ng-template tetaSelectOption let-option>\n <div style=\"width: 50px;border:0;border-top: 2px;\"\n [style.border-style]=\"option.value\"\n [style.border-color]=\"seriesItem.color\"></div>\n </ng-template>\n <ng-template tetaSelectValue let-value>\n <div style=\"width: 50px;border:0;border-top: 2px;\"\n [style.border-style]=\"value?.value\"\n [style.border-color]=\"seriesItem.color\"></div>\n </ng-template>\n </teta-select>\n </teta-input>\n <teta-input [label]=\"'charts.chart_type' | transloco\">\n <teta-select [options]=\"seriesType\"\n [ngModel]=\"seriesItem.type ?? SeriesType.line\"\n [valueRef]=\"'id'\"\n [textRef]=\"'value'\"\n (ngModelChange)=\"setSeriesType(seriesItem, $event)\"\n [allowNull]=\"false\">\n </teta-select>\n </teta-input>\n </div>\n </ng-template>\n </teta-accordion-item>\n }\n </teta-accordion>\n </teta-scrollable>\n <div class=\"row padding-3\">\n <button teta-button\n [palette]=\"'red'\"\n [view]=\"'ghost'\"\n (click)=\"clear()\">\n <teta-icon [name]=\"'erase'\"></teta-icon>\n {{ 'charts.reset' | transloco }}\n </button>\n </div>\n </div>\n</teta-dropdown>\n", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[teta-button], teta-button", inputs: ["palette", "class", "view", "square", "viewType", "size"] }, { kind: "component", type: DropdownComponent, selector: "teta-dropdown", exportAs: ["dropdown"] }, { kind: "directive", type: DropdownContentDirective, selector: "[tetaDropdownContent]" }, { kind: "directive", type: DropdownHeadDirective, selector: "[tetaDropdownHead]" }, { kind: "component", type: IconComponent, selector: "teta-icon", inputs: ["name", "size", "palette", "class"] }, { kind: "component", type: AccordionComponent, selector: "teta-accordion" }, { kind: "component", type: AccordionHeadComponent, selector: "teta-accordion-head", inputs: ["showToggle"] }, { kind: "component", type: AccordionItemComponent, selector: "teta-accordion-item", inputs: ["open", "disabled", "divider", "viewType"] }, { kind: "directive", type: AccordionContentDirective, selector: "[tetaAccordionContent]" }, { kind: "component", type: ColorInputComponent, selector: "teta-color-input", inputs: ["disabled"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SelectComponent, selector: "teta-select", inputs: ["multiple", "options", "invalid", "align", "verticalAlign", "autoClose", "autoCloseIgnore", "disabled", "itemSize", "virtual", "icon", "placeholder", "appendToBody", "allowNull", "viewType", "notFoundText", "valueRef", "textRef", "searchRef"] }, { kind: "directive", type: SelectOptionDirective, selector: "[tetaSelectOption]" }, { kind: "directive", type: SelectValueDirective, selector: "[tetaSelectValue]" }, { kind: "component", type: ScrollableComponent, selector: "teta-scrollable", inputs: ["direction", "showScrollbars", "contentClass"], outputs: ["scroll"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "component", type: InputComponent, selector: "teta-input", inputs: ["label", "hint", "viewType", "horizontal", "required"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2777
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SeriesControlsComponent, isStandalone: true, selector: "teta-series-controls", inputs: { series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<teta-dropdown [align]=\"Align.right\"\n #dropdown=\"dropdown\"\n [appendToBody]=\"true\">\n <button teta-button\n tetaDropdownHead\n [class.active]=\"dropdown.open\"\n [palette]=\"'text'\"\n [view]=\"'ghost'\">\n <teta-icon [name]=\"'gear'\"></teta-icon>\n {{ 'charts.settings' | transloco }}\n </button>\n <div tetaDropdownContent class=\"column shadow-2\" style=\"min-width: 200px;\">\n @if (disabledSeries().length > 0) {\n <div class=\"row padding-h-3 padding-top-3\">\n <teta-dropdown [align]=\"Align.left\" [appendToBody]=\"true\">\n <button teta-button\n tetaDropdownHead\n [palette]=\"'primary'\">\n <teta-icon [name]=\"'add'\"></teta-icon>\n {{ 'charts.add_curve' | transloco }}\n </button>\n <div tetaDropdownContent class=\"column list shadow-2\" style=\"min-width: 200px;\"\n (click)=\"$event.stopPropagation();\">\n @for (seriesItem of disabledSeries(); track seriesItem.id) {\n <div class=\"list-item list-item_interactive\"\n (click)=\"$event.stopPropagation();setSeriesEnabled(seriesItem, true)\">\n {{ seriesItem.name }}\n </div>\n }\n </div>\n </teta-dropdown>\n </div>\n }\n <teta-scrollable class=\"column column_auto\" [contentClass]=\"'column'\">\n <teta-accordion>\n @for (seriesItem of enabledSeries(); track seriesItem.id) {\n <teta-accordion-item [viewType]=\"'rounded'\" [divider]=\"true\">\n <teta-accordion-head style=\"padding: 2px 8px\">\n <div class=\"row align-center gap-12\">\n <div class=\"row align-center gap-8\" (click)=\"$event.stopPropagation()\">\n <teta-button (click)=\"setSeriesEnabled(seriesItem, false)\"\n [palette]=\"'text'\"\n [view]=\"'ghost'\"\n [square]=\"true\">\n <teta-icon [name]=\"'delete'\" [palette]=\"'red'\"></teta-icon>\n </teta-button>\n <teta-color-input [ngModel]=\"seriesItem.color\"\n (ngModelChange)=\"setSeriesColor(seriesItem, $event)\"></teta-color-input>\n </div>\n {{ seriesItem.name }}\n </div>\n </teta-accordion-head>\n <ng-template tetaAccordionContent>\n <div class=\"column gap-8\">\n <teta-input [label]=\"'charts.line_width' | transloco\">\n <teta-select [options]=\"strokeWidth\"\n [ngModel]=\"seriesItem.style?.strokeWidth ?? 1\"\n [valueRef]=\"'id'\"\n (ngModelChange)=\"setSeriesStrokeWidth(seriesItem, $event)\"\n [allowNull]=\"false\">\n <ng-template tetaSelectOption let-option>\n <div style=\"width: 50px;\"\n [style.height.px]=\"option.id\"\n [style.background-color]=\"seriesItem.color\"></div>\n </ng-template>\n <ng-template tetaSelectValue let-value>\n <div style=\"width: 50px;\"\n [style.height.px]=\"value?.id\"\n [style.background-color]=\"seriesItem.color\"></div>\n </ng-template>\n </teta-select>\n </teta-input>\n <teta-input [label]=\"'charts.line_style' | transloco\">\n <teta-select [options]=\"strokeArray\"\n [ngModel]=\"seriesItem.style?.strokeDasharray ?? ''\"\n [valueRef]=\"'id'\"\n (ngModelChange)=\"setSeriesStrokeDasharray(seriesItem, $event)\"\n [allowNull]=\"false\">\n <ng-template tetaSelectOption let-option>\n <div style=\"width: 50px;border:0;border-top: 2px;\"\n [style.border-style]=\"option.value\"\n [style.border-color]=\"seriesItem.color\"></div>\n </ng-template>\n <ng-template tetaSelectValue let-value>\n <div style=\"width: 50px;border:0;border-top: 2px;\"\n [style.border-style]=\"value?.value\"\n [style.border-color]=\"seriesItem.color\"></div>\n </ng-template>\n </teta-select>\n </teta-input>\n <teta-input [label]=\"'charts.chart_type' | transloco\">\n <teta-select [options]=\"seriesType\"\n [ngModel]=\"seriesItem.type ?? SeriesType.line\"\n [valueRef]=\"'id'\"\n [textRef]=\"'value'\"\n (ngModelChange)=\"setSeriesType(seriesItem, $event)\"\n [allowNull]=\"false\">\n </teta-select>\n </teta-input>\n @if (seriesItem.type === SeriesType.area || seriesItem.type === SeriesType.blockArea || seriesItem.type === SeriesType.block) {\n <teta-input [label]=\"'charts.fill_type' | transloco\">\n <teta-select [options]=\"fillType\"\n [ngModel]=\"seriesItem.fillType ?? FillType.default\"\n [valueRef]=\"'id'\"\n [textRef]=\"'value'\"\n (ngModelChange)=\"setSeriesFillType(seriesItem, $event)\"\n [allowNull]=\"false\">\n </teta-select>\n </teta-input>\n }\n </div>\n </ng-template>\n </teta-accordion-item>\n }\n </teta-accordion>\n </teta-scrollable>\n <div class=\"row padding-3\">\n <button teta-button\n [palette]=\"'red'\"\n [view]=\"'ghost'\"\n (click)=\"clear()\">\n <teta-icon [name]=\"'erase'\"></teta-icon>\n {{ 'charts.reset' | transloco }}\n </button>\n </div>\n </div>\n</teta-dropdown>\n", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[teta-button], teta-button", inputs: ["palette", "class", "view", "square", "viewType", "size"] }, { kind: "component", type: DropdownComponent, selector: "teta-dropdown", exportAs: ["dropdown"] }, { kind: "directive", type: DropdownContentDirective, selector: "[tetaDropdownContent]" }, { kind: "directive", type: DropdownHeadDirective, selector: "[tetaDropdownHead]" }, { kind: "component", type: IconComponent, selector: "teta-icon", inputs: ["name", "size", "palette", "class"] }, { kind: "component", type: AccordionComponent, selector: "teta-accordion" }, { kind: "component", type: AccordionHeadComponent, selector: "teta-accordion-head", inputs: ["showToggle"] }, { kind: "component", type: AccordionItemComponent, selector: "teta-accordion-item", inputs: ["open", "disabled", "divider", "viewType"] }, { kind: "directive", type: AccordionContentDirective, selector: "[tetaAccordionContent]" }, { kind: "component", type: ColorInputComponent, selector: "teta-color-input", inputs: ["disabled"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SelectComponent, selector: "teta-select", inputs: ["multiple", "options", "invalid", "align", "verticalAlign", "autoClose", "autoCloseIgnore", "disabled", "itemSize", "virtual", "icon", "placeholder", "appendToBody", "allowNull", "viewType", "notFoundText", "valueRef", "textRef", "searchRef", "open"] }, { kind: "directive", type: SelectOptionDirective, selector: "[tetaSelectOption]" }, { kind: "directive", type: SelectValueDirective, selector: "[tetaSelectValue]" }, { kind: "component", type: ScrollableComponent, selector: "teta-scrollable", inputs: ["direction", "showScrollbars", "contentClass"], outputs: ["scroll"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "component", type: InputComponent, selector: "teta-input", inputs: ["label", "hint", "viewType", "horizontal", "required"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2706
2778
  }
2707
2779
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SeriesControlsComponent, decorators: [{
2708
2780
  type: Component,
@@ -2724,7 +2796,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
2724
2796
  ScrollableComponent,
2725
2797
  TranslocoPipe,
2726
2798
  InputComponent,
2727
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<teta-dropdown [align]=\"Align.right\"\n #dropdown=\"dropdown\"\n [appendToBody]=\"true\">\n <button teta-button\n tetaDropdownHead\n [class.active]=\"dropdown.open\"\n [palette]=\"'text'\"\n [view]=\"'ghost'\">\n <teta-icon [name]=\"'gear'\"></teta-icon>\n {{ 'charts.settings' | transloco }}\n </button>\n <div tetaDropdownContent class=\"column shadow-2\" style=\"min-width: 200px;\">\n @if (disabledSeries().length > 0) {\n <div class=\"row padding-h-3 padding-top-3\">\n <teta-dropdown [align]=\"Align.left\" [appendToBody]=\"true\">\n <button teta-button\n tetaDropdownHead\n [palette]=\"'primary'\">\n <teta-icon [name]=\"'add'\"></teta-icon>\n {{ 'charts.add_curve' | transloco }}\n </button>\n <div tetaDropdownContent class=\"column list shadow-2\" style=\"min-width: 200px;\"\n (click)=\"$event.stopPropagation();\">\n @for (seriesItem of disabledSeries(); track seriesItem.id) {\n <div class=\"list-item list-item_interactive\"\n (click)=\"$event.stopPropagation();setSeriesEnabled(seriesItem, true)\">\n {{ seriesItem.name }}\n </div>\n }\n </div>\n </teta-dropdown>\n </div>\n }\n <teta-scrollable class=\"column column_auto\" [contentClass]=\"'column'\">\n <teta-accordion>\n @for (seriesItem of enabledSeries(); track seriesItem.id) {\n <teta-accordion-item [viewType]=\"'rounded'\" [divider]=\"true\">\n <teta-accordion-head style=\"padding: 2px 8px\">\n <div class=\"row align-center gap-12\">\n <div class=\"row align-center gap-8\" (click)=\"$event.stopPropagation()\">\n <teta-button (click)=\"setSeriesEnabled(seriesItem, false)\"\n [palette]=\"'text'\"\n [view]=\"'ghost'\"\n [square]=\"true\">\n <teta-icon [name]=\"'delete'\" [palette]=\"'red'\"></teta-icon>\n </teta-button>\n <teta-color-input [ngModel]=\"seriesItem.color\"\n (ngModelChange)=\"setSeriesColor(seriesItem, $event)\"></teta-color-input>\n </div>\n {{ seriesItem.name }}\n </div>\n </teta-accordion-head>\n <ng-template tetaAccordionContent>\n <div class=\"column gap-8\">\n <teta-input [label]=\"'charts.line_width' | transloco\">\n <teta-select [options]=\"strokeWidth\"\n [ngModel]=\"seriesItem.style?.strokeWidth ?? 1\"\n [valueRef]=\"'id'\"\n (ngModelChange)=\"setSeriesStrokeWidth(seriesItem, $event)\"\n [allowNull]=\"false\">\n <ng-template tetaSelectOption let-option>\n <div style=\"width: 50px;\"\n [style.height.px]=\"option.id\"\n [style.background-color]=\"seriesItem.color\"></div>\n </ng-template>\n <ng-template tetaSelectValue let-value>\n <div style=\"width: 50px;\"\n [style.height.px]=\"value?.id\"\n [style.background-color]=\"seriesItem.color\"></div>\n </ng-template>\n </teta-select>\n </teta-input>\n <teta-input [label]=\"'charts.line_style' | transloco\">\n <teta-select [options]=\"strokeArray\"\n [ngModel]=\"seriesItem.style?.strokeDasharray ?? ''\"\n [valueRef]=\"'id'\"\n (ngModelChange)=\"setSeriesStrokeDasharray(seriesItem, $event)\"\n [allowNull]=\"false\">\n <ng-template tetaSelectOption let-option>\n <div style=\"width: 50px;border:0;border-top: 2px;\"\n [style.border-style]=\"option.value\"\n [style.border-color]=\"seriesItem.color\"></div>\n </ng-template>\n <ng-template tetaSelectValue let-value>\n <div style=\"width: 50px;border:0;border-top: 2px;\"\n [style.border-style]=\"value?.value\"\n [style.border-color]=\"seriesItem.color\"></div>\n </ng-template>\n </teta-select>\n </teta-input>\n <teta-input [label]=\"'charts.chart_type' | transloco\">\n <teta-select [options]=\"seriesType\"\n [ngModel]=\"seriesItem.type ?? SeriesType.line\"\n [valueRef]=\"'id'\"\n [textRef]=\"'value'\"\n (ngModelChange)=\"setSeriesType(seriesItem, $event)\"\n [allowNull]=\"false\">\n </teta-select>\n </teta-input>\n </div>\n </ng-template>\n </teta-accordion-item>\n }\n </teta-accordion>\n </teta-scrollable>\n <div class=\"row padding-3\">\n <button teta-button\n [palette]=\"'red'\"\n [view]=\"'ghost'\"\n (click)=\"clear()\">\n <teta-icon [name]=\"'erase'\"></teta-icon>\n {{ 'charts.reset' | transloco }}\n </button>\n </div>\n </div>\n</teta-dropdown>\n" }]
2799
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<teta-dropdown [align]=\"Align.right\"\n #dropdown=\"dropdown\"\n [appendToBody]=\"true\">\n <button teta-button\n tetaDropdownHead\n [class.active]=\"dropdown.open\"\n [palette]=\"'text'\"\n [view]=\"'ghost'\">\n <teta-icon [name]=\"'gear'\"></teta-icon>\n {{ 'charts.settings' | transloco }}\n </button>\n <div tetaDropdownContent class=\"column shadow-2\" style=\"min-width: 200px;\">\n @if (disabledSeries().length > 0) {\n <div class=\"row padding-h-3 padding-top-3\">\n <teta-dropdown [align]=\"Align.left\" [appendToBody]=\"true\">\n <button teta-button\n tetaDropdownHead\n [palette]=\"'primary'\">\n <teta-icon [name]=\"'add'\"></teta-icon>\n {{ 'charts.add_curve' | transloco }}\n </button>\n <div tetaDropdownContent class=\"column list shadow-2\" style=\"min-width: 200px;\"\n (click)=\"$event.stopPropagation();\">\n @for (seriesItem of disabledSeries(); track seriesItem.id) {\n <div class=\"list-item list-item_interactive\"\n (click)=\"$event.stopPropagation();setSeriesEnabled(seriesItem, true)\">\n {{ seriesItem.name }}\n </div>\n }\n </div>\n </teta-dropdown>\n </div>\n }\n <teta-scrollable class=\"column column_auto\" [contentClass]=\"'column'\">\n <teta-accordion>\n @for (seriesItem of enabledSeries(); track seriesItem.id) {\n <teta-accordion-item [viewType]=\"'rounded'\" [divider]=\"true\">\n <teta-accordion-head style=\"padding: 2px 8px\">\n <div class=\"row align-center gap-12\">\n <div class=\"row align-center gap-8\" (click)=\"$event.stopPropagation()\">\n <teta-button (click)=\"setSeriesEnabled(seriesItem, false)\"\n [palette]=\"'text'\"\n [view]=\"'ghost'\"\n [square]=\"true\">\n <teta-icon [name]=\"'delete'\" [palette]=\"'red'\"></teta-icon>\n </teta-button>\n <teta-color-input [ngModel]=\"seriesItem.color\"\n (ngModelChange)=\"setSeriesColor(seriesItem, $event)\"></teta-color-input>\n </div>\n {{ seriesItem.name }}\n </div>\n </teta-accordion-head>\n <ng-template tetaAccordionContent>\n <div class=\"column gap-8\">\n <teta-input [label]=\"'charts.line_width' | transloco\">\n <teta-select [options]=\"strokeWidth\"\n [ngModel]=\"seriesItem.style?.strokeWidth ?? 1\"\n [valueRef]=\"'id'\"\n (ngModelChange)=\"setSeriesStrokeWidth(seriesItem, $event)\"\n [allowNull]=\"false\">\n <ng-template tetaSelectOption let-option>\n <div style=\"width: 50px;\"\n [style.height.px]=\"option.id\"\n [style.background-color]=\"seriesItem.color\"></div>\n </ng-template>\n <ng-template tetaSelectValue let-value>\n <div style=\"width: 50px;\"\n [style.height.px]=\"value?.id\"\n [style.background-color]=\"seriesItem.color\"></div>\n </ng-template>\n </teta-select>\n </teta-input>\n <teta-input [label]=\"'charts.line_style' | transloco\">\n <teta-select [options]=\"strokeArray\"\n [ngModel]=\"seriesItem.style?.strokeDasharray ?? ''\"\n [valueRef]=\"'id'\"\n (ngModelChange)=\"setSeriesStrokeDasharray(seriesItem, $event)\"\n [allowNull]=\"false\">\n <ng-template tetaSelectOption let-option>\n <div style=\"width: 50px;border:0;border-top: 2px;\"\n [style.border-style]=\"option.value\"\n [style.border-color]=\"seriesItem.color\"></div>\n </ng-template>\n <ng-template tetaSelectValue let-value>\n <div style=\"width: 50px;border:0;border-top: 2px;\"\n [style.border-style]=\"value?.value\"\n [style.border-color]=\"seriesItem.color\"></div>\n </ng-template>\n </teta-select>\n </teta-input>\n <teta-input [label]=\"'charts.chart_type' | transloco\">\n <teta-select [options]=\"seriesType\"\n [ngModel]=\"seriesItem.type ?? SeriesType.line\"\n [valueRef]=\"'id'\"\n [textRef]=\"'value'\"\n (ngModelChange)=\"setSeriesType(seriesItem, $event)\"\n [allowNull]=\"false\">\n </teta-select>\n </teta-input>\n @if (seriesItem.type === SeriesType.area || seriesItem.type === SeriesType.blockArea || seriesItem.type === SeriesType.block) {\n <teta-input [label]=\"'charts.fill_type' | transloco\">\n <teta-select [options]=\"fillType\"\n [ngModel]=\"seriesItem.fillType ?? FillType.default\"\n [valueRef]=\"'id'\"\n [textRef]=\"'value'\"\n (ngModelChange)=\"setSeriesFillType(seriesItem, $event)\"\n [allowNull]=\"false\">\n </teta-select>\n </teta-input>\n }\n </div>\n </ng-template>\n </teta-accordion-item>\n }\n </teta-accordion>\n </teta-scrollable>\n <div class=\"row padding-3\">\n <button teta-button\n [palette]=\"'red'\"\n [view]=\"'ghost'\"\n (click)=\"clear()\">\n <teta-icon [name]=\"'erase'\"></teta-icon>\n {{ 'charts.reset' | transloco }}\n </button>\n </div>\n </div>\n</teta-dropdown>\n" }]
2728
2800
  }] });
2729
2801
 
2730
2802
  class ChartContainerComponent {