UNPKG

@progress/kendo-angular-charts

Version:

Kendo UI Charts for Angular - A comprehensive package for creating beautiful and interactive data visualization. Every chart type, stock charts, and sparklines are included.

1,239 lines (1,223 loc) 545 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import * as i0 from '@angular/core'; import { Directive, Optional, Injectable, SimpleChange, TemplateRef, Component, ChangeDetectionStrategy, Input, ContentChild, ElementRef, ViewChild, ViewChildren, EventEmitter, Output, ContentChildren, forwardRef, LOCALE_ID, Inject, isDevMode, InjectionToken, HostBinding, NgModule } from '@angular/core'; import { isDocumentAvailable, shouldShowValidationUI, ResizeSensorComponent, WatermarkOverlayComponent, PreventableEvent as PreventableEvent$1, isChanged, ResizeBatchService } from '@progress/kendo-angular-common'; import * as i3 from '@progress/kendo-angular-intl'; import * as i1$1 from '@progress/kendo-angular-l10n'; import { ComponentMessages, LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n'; import { DateCategoryAxis, DateValueAxis, InstanceObserver, chartBaseTheme, chartTheme, deepExtend, Chart, StockChart, Sparkline, sankeyTheme, Sankey, createSankeyData } from '@progress/kendo-charts'; import { exportImage, exportSVG } from '@progress/kendo-drawing'; import { validatePackage } from '@progress/kendo-licensing'; import { Subject, BehaviorSubject, combineLatest, Subscription } from 'rxjs'; import { auditTime, tap } from 'rxjs/operators'; import * as i1 from '@progress/kendo-angular-popup'; import { PopupService, POPUP_CONTAINER } from '@progress/kendo-angular-popup'; import { NgStyle, NgFor, NgClass, NgIf, NgTemplateOutlet } from '@angular/common'; import { BreadCrumbComponent } from '@progress/kendo-angular-navigation'; import { homeIcon, arrowRightIcon, arrowLeftIcon } from '@progress/kendo-svg-icons'; import { IconWrapperComponent, IconsService } from '@progress/kendo-angular-icons'; import { getter } from '@progress/kendo-common'; const dateCategoryAxisFormats = DateCategoryAxis.prototype.options.labels.dateFormats; const dateValueAxisFormats = DateValueAxis.prototype.options.labels.dateFormats; const dateFormats = { milliseconds: "HH:mm:ss.SSS", seconds: { time: 'medium' }, minutes: { time: 'short' }, hours: { time: 'short' }, days: { skeleton: 'Md' }, weeks: { skeleton: 'Md' }, months: { skeleton: 'yyMMM' }, years: { skeleton: 'y' } }; Object.assign(dateCategoryAxisFormats, dateFormats); Object.assign(dateValueAxisFormats, dateFormats); /** * A directive which selects a [template](link:site.data.urls.angular['templatesyntax']) * within the `<kendo-chart>` component for the * [Donut center template](slug:donut_seriestypes_charts#toc-using-the-center-template). */ class DonutCenterTemplateDirective { templateRef; constructor(templateRef) { this.templateRef = templateRef; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DonutCenterTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DonutCenterTemplateDirective, isStandalone: true, selector: "[kendoChartDonutCenterTemplate]", ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DonutCenterTemplateDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoChartDonutCenterTemplate]', standalone: true }] }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{ type: Optional }] }]; } }); /** * A directive which selects a [template](link:site.data.urls.angular['templatesyntax']) * within the `<kendo-chart>` component for the * [No Data Overlay](slug:databinding_chart_charts#toc-no-data-overlay). */ class NoDataTemplateDirective { templateRef; constructor(templateRef) { this.templateRef = templateRef; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NoDataTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: NoDataTemplateDirective, isStandalone: true, selector: "[kendoChartNoDataTemplate]", ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NoDataTemplateDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoChartNoDataTemplate]', standalone: true }] }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{ type: Optional }] }]; } }); /** * @hidden */ class ItemChange { sender; options; constructor(sender, options) { this.sender = sender; this.options = options; } } /** * @hidden */ class CollectionService { onItemChange$; source; constructor() { this.source = new Subject(); this.onItemChange$ = this.source.asObservable(); } notify(change) { this.source.next(change); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CollectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CollectionService }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CollectionService, decorators: [{ type: Injectable }], ctorParameters: function () { return []; } }); /** * @hidden */ const THROTTLE_MS = 1000 / 60; /** * @hidden */ class Change { key; value; constructor(key, value) { this.key = key; this.value = value; } } /** * @hidden */ class ConfigurationService { ngZone; onChange$; onFastChange$; store = {}; source = new BehaviorSubject({}); constructor(ngZone) { this.ngZone = ngZone; this.initSource(); } initSource() { this.onFastChange$ = this.source.asObservable(); this.onChange$ = this.onFastChange$.pipe(auditTime(THROTTLE_MS)); } push(store) { this.store = store; this.next(); } notify(change) { this.set(change.key, change.value); this.next(); } set(field, value) { let store = this.store; const parts = field.split('.'); let key = parts.shift(); while (parts.length > 0) { store = store[key] = store[key] || {}; key = parts.shift(); } store[key] = value; } next() { this.ngZone.runOutsideAngular(() => { this.source.next(this.store); }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConfigurationService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConfigurationService }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConfigurationService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i0.NgZone }]; } }); /** * @hidden */ function copyChanges(changes, options) { for (const propertyName in changes) { if (!Object.hasOwnProperty.call(changes, propertyName)) { continue; } const value = changes[propertyName].currentValue; if (value === undefined) { delete options[propertyName]; } else { options[propertyName] = value; } } } /** * @hidden */ function toSimpleChanges(changes) { const result = {}; for (const propertyName in changes) { if (!Object.hasOwnProperty.call(changes, propertyName)) { continue; } result[propertyName] = new SimpleChange(null, changes[propertyName], false); } return result; } /** * @hidden */ class CollectionItemComponent { configurationService; collectionService; subscription; options = {}; hidden = false; constructor(configurationService, collectionService) { this.configurationService = configurationService; this.collectionService = collectionService; this.subscription = configurationService.onFastChange$.subscribe(store => { this.options = store; this.notify(); }); } ngOnChanges(changes) { const store = this.configurationService.store; copyChanges(changes, store); this.configurationService.push(store); } /** * Updates the component fields with the specified values and refreshes the Chart. * * Use this method when the configuration values cannot be set through the template. * * @example * ```ts-no-run * item.notifyChanges({ visible: true }); * ``` * * @param changes An object containing the updated input fields. */ notifyChanges(changes) { this.ngOnChanges(toSimpleChanges(changes)); } ngOnDestroy() { this.subscription.unsubscribe(); } notify() { if (!this.collectionService) { return; } this.collectionService.notify(new ItemChange(this, this.options)); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CollectionItemComponent, deps: [{ token: ConfigurationService }, { token: CollectionService }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CollectionItemComponent, usesOnChanges: true, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CollectionItemComponent, decorators: [{ type: Directive }], ctorParameters: function () { return [{ type: ConfigurationService }, { type: CollectionService }]; } }); /** * @hidden */ class SettingsComponent { configKey; configurationService; store = {}; constructor(configKey, configurationService) { this.configKey = configKey; this.configurationService = configurationService; if (configKey === undefined) { throw new Error('Configuration key not set'); } } ngOnDestroy() { this.store = undefined; this.notify(); } ngOnChanges(changes) { copyChanges(changes, this.store); this.notify(); } /** * Updates the component fields with the specified values and refreshes the Chart. * * Use this method when the configuration values cannot be set through the template. * * @example * ```ts-no-run * item.notifyChanges({ visible: true }); * ``` * * @param changes An object containing the updated input fields. */ notifyChanges(changes) { this.ngOnChanges(toSimpleChanges(changes)); } markAsVisible() { this.store.visible = true; this.notify(); } notify() { this.configurationService.notify(new Change(this.configKey, this.store)); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SettingsComponent, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: SettingsComponent, usesOnChanges: true, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SettingsComponent, decorators: [{ type: Directive }], ctorParameters: function () { return [{ type: undefined }, { type: ConfigurationService }]; } }); /** * The configuration options of the Chart series tooltip * ([see example]({% slug tooltips_chart_charts %})). */ class SeriesTooltipComponent extends SettingsComponent { configurationService; background; border; color; /** * The font of the tooltip. * @default '12px sans-serif' */ font; format; padding; /** * If set to `true`, the Chart displays the series tooltip. * @default false */ visible; seriesTooltipTemplate; constructor(configurationService) { super('tooltip', configurationService); this.configurationService = configurationService; this.markAsVisible(); } get seriesTooltipTemplateRef() { return this.seriesTooltipTemplate; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SeriesTooltipComponent, deps: [{ token: ConfigurationService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SeriesTooltipComponent, isStandalone: true, selector: "kendo-chart-series-item-tooltip", inputs: { background: "background", border: "border", color: "color", font: "font", format: "format", padding: "padding", visible: "visible" }, queries: [{ propertyName: "seriesTooltipTemplate", first: true, predicate: TemplateRef, descendants: true }], usesInheritance: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SeriesTooltipComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'kendo-chart-series-item-tooltip', template: '', standalone: true }] }], ctorParameters: function () { return [{ type: ConfigurationService }]; }, propDecorators: { background: [{ type: Input }], border: [{ type: Input }], color: [{ type: Input }], font: [{ type: Input }], format: [{ type: Input }], padding: [{ type: Input }], visible: [{ type: Input }], seriesTooltipTemplate: [{ type: ContentChild, args: [TemplateRef, { static: false }] }] } }); /** * Represents the series [template](link:site.data.urls.angular['templatesyntax']) * within the `<kendo-chart-series-item>` component for creating nested * [Drilldown](slug:drilldown_chart_charts) series. * * When the user clicks on a data point with drilldown data, * the Chart will create a new series based on this template. * * The template context is passes through the following fields: * - `drilldownValue`&mdash;The drilldown field value. * - `point`&mdash;The series point to drill down to. * - `series`&mdash;The series to drill down to. */ class SeriesDrilldownTemplateDirective { templateRef; constructor(templateRef) { this.templateRef = templateRef; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SeriesDrilldownTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: SeriesDrilldownTemplateDirective, isStandalone: true, selector: "[kendoChartDrilldownSeries]", ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SeriesDrilldownTemplateDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoChartDrilldownSeries]', standalone: true }] }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{ type: Optional }] }]; } }); const toggle = (flag) => flag === undefined ? false : !flag; /** * The configuration component for a series item. * * @example * ```html * <kendo-chart ...> * <kendo-chart-series> * <kendo-chart-series-item type="line" ...> </kendo-chart-series-item> * </kendo-chart-series> * </kendo-chart> * ``` */ class SeriesItemComponent extends CollectionItemComponent { configurationService; collectionService; /** * The aggregate function for the date series. * The function is used when a category (year, month, or other) contains two or more points. * The Chart displays the return value of the function instead of the individual points. * The `aggregate` option is supported for categorical chart axis only. * * The supported values are: * - `"avg"`&mdash;The average of all values for the date period. * - `"count"`&mdash;The number of values for the date period. * - `"max"`&mdash;The highest value for the date period. * - `"min"`&mdash;The lowest value for the date period. * - `"sum"`&mdash;The sum of all values for the date period. Defaults to `0` if no data points are defined. * - `"sumOrNull"`&mdash;The sum of all values for the date period. Defaults to `null` if no data points are defined. * - `"first"`&mdash;The first value. * - function (values, series, dataItems, category)&mdash;A user-defined aggregate function. Returns a single value or a data item. * - object (compound aggregate)&mdash;Applicable to the Candlestick, Box Plot, and OHLC series. Specifies the aggregate for each data item field. * * @default 'max' */ aggregate; /** * If set to `true`, the Chart automatically scales down to fit the content area. * Applicable for the Pie and Donut series. ([See example](slug:donut_seriestypes_charts#displaying-labels-in-angular-donut-chart)). * @default false */ autoFit; /** * The name of the value axis. * The axis option is supported for Scatter plots. For more information on Scatter plots, refer to * [`xAxis`]({% slug api_charts_xaxis %}) and [`yAxis`]({% slug api_charts_yaxis %}). * @default 'primary' */ axis; border; categoryAxis; /** * The data item field which contains the category name or date. * If the category is a date, the points are rendered in chronological order. * @default 'category' */ categoryField; /** * The data field that contains the `close` value. * The `closeField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"candlestick"` or `"ohlc"`. * @default 'close' */ closeField; color; /** * The data item field which contains the series color. * The `colorField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) * is set to `"bar"`, `"column"`, `"rangeBar"`, `"rangeColumn"`, `"bubble"`, `"donut"`, `"pie"`, `"candlestick"`, * `"ohlc"`, or `"waterfall"`. * @default 'color' */ colorField; connectors; /** * The data item field which contains the current value. * The `currentField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"bullet"` or `"verticalBullet"`. * @default 'current' */ currentField; /** * The dash type of line Chart. * The `dashType` option is considered only if the [`series.type`]({% slug api_charts_series %}#toc-type) option is set to `"line"`. * @default 'solid' */ dashType; data; downColor; /** * The data field which contains the color that is applied when the `open` value is greater than the `close` value. * The `downColorField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"candlestick"`. * @default 'downColor' */ downColorField; drilldownField; /** * The `dynamicHeight` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"funnel"` or `"pyramid"`. * When set to `false`, all segments become with the same height. * Otherwise, the height of each segment is based on its value. * @default true */ dynamicHeight; /** * The option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"funnel"`. * When set to `true`, the ratio of the bases of each segment is calculated based on the ratio of * `currentDataItem.value`/`nextDataItem.value`. * The last element is always created like a rectangle since there is no following element. * @default false */ dynamicSlope; /** * The data item field which contains the [`series.errorBars`]({% slug api_charts_series %}#toc-errorbars) high value. * The `errorHighField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"bar"`, `"column"`, `"line"`, or `"area"`. * @default 'errorHigh' */ errorHighField; /** * The data item field which contains the [`series.errorBars`]({% slug api_charts_series %}#toc-errorbars) low value. * The `errorLowField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"bar"`, `"column"`, `"line"`, or `"area"`. * @default 'errorLow' */ errorLowField; /** * The data item field which contains a Boolean value indicating whether the sector is exploded. * The `explodeField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"donut"` or `"pie"`. * @default 'explode' */ explodeField; /** * The data item field which contains the series value. * @default 'value' */ field; /** * The data item field which contains the series from value. * @default 'min' */ fromField; /** * The distance between the categories expressed as a percentage of the bar width. * See the related spacing setting. * The `gap` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"bar"`, `"column"`, `"candlestick"`, `"ohlc"`, * `"radarColumn"`, or `"waterfall"`. * @default 1.5 */ gap; /** * The data field which contains the high value. * The `highField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"candlestick"` or `"ohlc"`. * @default 'hight' */ highField; holeSize; line; /** * The data field containing the low value. * The `lowField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"candlestick"` or `"ohlc"`. * @default 'low' */ lowField; /** * The data item field which contains the series lower value. * The `lowerField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"boxPlot"`. * @default 'lower' */ lowerField; /** * The margin around each donut series (ring). A numeric value sets all margins. * @default 1 */ margin; /** * The maximum size of the Chart bubble series marker. * @default 100 */ maxSize; mean; /** * The data item field which contains the series mean value. * The `meanField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"boxPlot"`. * @default 'mean' */ meanField; median; /** * The data item field which contains the series median value. * The `medianField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"boxPlot"`. * @default 'median' */ medianField; /** * The minimum size of the Chart bubble series marker. * @default 5 */ minSize; missingValues; name; /** * Specifies the top-base/bottom-base ratio of the whole Funnel Chart. If the `neckRatio` is set to `3`, * it means the top base is three times smaller than the bottom base. * The `neckRatio` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"funnel"` and `dynamicSlope` is set to `false`. * @default 0.3 */ neckRatio; negativeColor; negativeValues; /** * The data item field which contains the series note text. * @default 'noteText' */ noteTextField; /** * The opacity of the series. By default, the series are opaque. * @default 1 */ opacity; openField; /** * The data item field which contains the series outliers value. * The `outliersField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"boxPlot"`. * @default 'outliers' */ outliersField; overlay; padding; /** * The data item field which contains the series `q1` value. * The `q1Field` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"boxPlot"`. * @default 'q1' */ q1Field; /** * The data item field which contains the series `q3` value. * The `q3Field` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"boxPlot"`. * @default 'q3' */ q3Field; /** * The space in pixels between the different segments of the Funnel or Pyramid Chart. * The `segmentSpacing` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"funnel"` or `"pyramid"`. * @default 0 */ segmentSpacing; size; /** * The data field which contains the bubble size value. * @default 'size' */ sizeField; /** * The distance between series points within a category. Expressed as a percentage of the bar width. * See the related `gap` setting. * The spacing option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"bar"`, `"column"`, `"candlestick"`, `"ohlc"`, or * `"radarColumn"`. * @default 0.4 */ spacing; /** * A Boolean value which indicates if the series have to be stacked. * A string value is interpreted as [`series.stack.group`]({% slug api_charts_seriesstack %}#toc-group). * * The `stack` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"bar"`, `"column"`, `"line"`, `"area"`, * `"verticalLine"`, `"verticalArea"`, `"radarLine"`, `"radarArea"`, and `"radarColumn"`. * If not overridden, the stack settings of the first series are inherited as a default value by the rest of the series. * @default false */ stack; /** * The start angle (in degrees) of the first Donut or Pie segment. * Angles increase clockwise with zero to the left. Negative values are acceptable. * @default 90 */ startAngle; /** * The `style` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to * `"line"`, `"scatterLine"`, `"radarLine"`, or `"polarLine"`. * @default 'normal' */ style; /** * The data item field which contains the summary type for the Waterfall series. * The value (if any) of a data item marked as a summary point will be discarded. * * Summary columns are optional and can be one of two types: * * `"runningTotal"`&mdash;Displays the sum of all items since the last `"runningTotal"` point. * `"total"`&mdash;Displays the sum of all previous items. * @default 'summary' */ summaryField; target; /** * The data item field which contains the series to value. * @default 'max' */ toField; /** * The type of the series. * @default 'column' */ type; /** * The data item field which contains the series upper value. * The `upperField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"boxPlot"`. * @default 'upper' */ upperField; /** * Sets the visible property of a Chart series. * @default true */ visible; /** * A value which indicates whether to show the point category (for Funnel, Pyramid, Donut, and Pie series) * or the series name (for other available series types) in the legend. * @default true */ visibleInLegend; visibleInLegendField; visual; width; whiskers; /** * The name of the X axis. * The [`xAxis`]({% slug api_charts_xaxis %}) option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"bubble"`, `"scatter"`, `"scatterLine"`, or `"polar"` series. * For the Polar series, the [`xAxis`]({% slug api_charts_xaxis %}) range is expressed in degrees. * @default 'primary' */ xAxis; /** * The data item field which contains the [`series.errorBars`]({% slug api_charts_series %}#toc-errorbars) xAxis low value. * The `xErrorLowField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"scatter"`, `"scatterLine"`, or * `"bubble"`. * @default 'xErrorHigh' */ xErrorHighField; /** * The data item field containing the x value. * The `xField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"bubble"`, `"scatter"`, `"scatterLine"`, or * `"polar"` series. * @default 'xErrorLow' */ xErrorLowField; /** * The data item field containing the x value. * The `xField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"bubble"`, `"scatter"`, `"scatterLine"`, or * `"polar"` series. * @default 'x' */ xField; /** * The name of the Y axis to use. * Available for the Bubble, Scatter, Scatter Line, and Polar series. * @default 'primary' */ yAxis; /** * The data item field which contains the [`series.errorBars`]({% slug api_charts_series %}#toc-errorbars) yAxis high value. * The `yErrorHighField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"scatter"`, `"scatterLine"`, or * `"bubble"`. * @default 'yErrorHigh' */ yErrorHighField; /** * The data item field which contains the [`series.errorBars`]({% slug api_charts_series %}#toc-errorbars) yAxis low value. * The `yErrorLowField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"scatter"`, `"scatterLine"`, or * `"bubble"`. * @default 'yErrorLow' */ yErrorLowField; /** * The data item field containing the y value. * The `yField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"bubble"`, `"scatter"`, or `"scatterLine"`. * @default 'y' */ yField; zIndex; /** * The configuration options of the trendline series. * * The `trendline` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to * "`linearTrendline`", "`exponentialTrendline`", "`logarithmicTrendline`", "`powerTrendline`", "`polynomialTrendline`" or "`movingAverageTrendline`". */ trendline; for; /** * The configuration options of the series legend item. */ legendItem; /** * The configuration options of the series pattern. */ pattern; /** * The data item field which contains the series pattern. * The `patternField` option is supported when [`series.type`]({% slug api_charts_series %}#toc-type) is set to `"pie"`, `"donut"`, `"funnel"`, `"heatmap"`, or `"pyramid"`. */ patternField; // These options are also available as child components errorBars; extremes; highlight; labels; markers; notes; outliers; tooltip; seriesTooltip; drilldownTemplate; constructor(configurationService, collectionService) { super(configurationService, collectionService); this.configurationService = configurationService; this.collectionService = collectionService; } /** * Toggles the series visibility and updates the parent Chart * without animated transitions. */ toggleVisibility() { this.options.visible = toggle(this.options.visible); this.notify(); } /** * Toggles the visibility of a point with the given index. * Applicable for the Pie, Donut, Funnel and Pyramid series. * * @param pointIndex - The zero-based index of the point to toggle. */ togglePointVisibility(pointIndex) { const pv = this.options.pointVisibility = this.options.pointVisibility || {}; pv[pointIndex] = toggle(pv[pointIndex]); this.notify(); } get seriesTooltipTemplateRef() { if (this.seriesTooltip) { return this.seriesTooltip.seriesTooltipTemplateRef; } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SeriesItemComponent, deps: [{ token: ConfigurationService }, { token: CollectionService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SeriesItemComponent, isStandalone: true, selector: "kendo-chart-series-item", inputs: { aggregate: "aggregate", autoFit: "autoFit", axis: "axis", border: "border", categoryAxis: "categoryAxis", categoryField: "categoryField", closeField: "closeField", color: "color", colorField: "colorField", connectors: "connectors", currentField: "currentField", dashType: "dashType", data: "data", downColor: "downColor", downColorField: "downColorField", drilldownField: "drilldownField", dynamicHeight: "dynamicHeight", dynamicSlope: "dynamicSlope", errorHighField: "errorHighField", errorLowField: "errorLowField", explodeField: "explodeField", field: "field", fromField: "fromField", gap: "gap", highField: "highField", holeSize: "holeSize", line: "line", lowField: "lowField", lowerField: "lowerField", margin: "margin", maxSize: "maxSize", mean: "mean", meanField: "meanField", median: "median", medianField: "medianField", minSize: "minSize", missingValues: "missingValues", name: "name", neckRatio: "neckRatio", negativeColor: "negativeColor", negativeValues: "negativeValues", noteTextField: "noteTextField", opacity: "opacity", openField: "openField", outliersField: "outliersField", overlay: "overlay", padding: "padding", q1Field: "q1Field", q3Field: "q3Field", segmentSpacing: "segmentSpacing", size: "size", sizeField: "sizeField", spacing: "spacing", stack: "stack", startAngle: "startAngle", style: "style", summaryField: "summaryField", target: "target", toField: "toField", type: "type", upperField: "upperField", visible: "visible", visibleInLegend: "visibleInLegend", visibleInLegendField: "visibleInLegendField", visual: "visual", width: "width", whiskers: "whiskers", xAxis: "xAxis", xErrorHighField: "xErrorHighField", xErrorLowField: "xErrorLowField", xField: "xField", yAxis: "yAxis", yErrorHighField: "yErrorHighField", yErrorLowField: "yErrorLowField", yField: "yField", zIndex: "zIndex", trendline: "trendline", for: "for", legendItem: "legendItem", pattern: "pattern", patternField: "patternField", errorBars: "errorBars", extremes: "extremes", highlight: "highlight", labels: "labels", markers: "markers", notes: "notes", outliers: "outliers", tooltip: "tooltip" }, providers: [ConfigurationService], queries: [{ propertyName: "seriesTooltip", first: true, predicate: SeriesTooltipComponent, descendants: true }, { propertyName: "drilldownTemplate", first: true, predicate: SeriesDrilldownTemplateDirective, descendants: true }], usesInheritance: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SeriesItemComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, providers: [ConfigurationService], selector: 'kendo-chart-series-item', template: '', standalone: true }] }], ctorParameters: function () { return [{ type: ConfigurationService }, { type: CollectionService }]; }, propDecorators: { aggregate: [{ type: Input }], autoFit: [{ type: Input }], axis: [{ type: Input }], border: [{ type: Input }], categoryAxis: [{ type: Input }], categoryField: [{ type: Input }], closeField: [{ type: Input }], color: [{ type: Input }], colorField: [{ type: Input }], connectors: [{ type: Input }], currentField: [{ type: Input }], dashType: [{ type: Input }], data: [{ type: Input }], downColor: [{ type: Input }], downColorField: [{ type: Input }], drilldownField: [{ type: Input }], dynamicHeight: [{ type: Input }], dynamicSlope: [{ type: Input }], errorHighField: [{ type: Input }], errorLowField: [{ type: Input }], explodeField: [{ type: Input }], field: [{ type: Input }], fromField: [{ type: Input }], gap: [{ type: Input }], highField: [{ type: Input }], holeSize: [{ type: Input }], line: [{ type: Input }], lowField: [{ type: Input }], lowerField: [{ type: Input }], margin: [{ type: Input }], maxSize: [{ type: Input }], mean: [{ type: Input }], meanField: [{ type: Input }], median: [{ type: Input }], medianField: [{ type: Input }], minSize: [{ type: Input }], missingValues: [{ type: Input }], name: [{ type: Input }], neckRatio: [{ type: Input }], negativeColor: [{ type: Input }], negativeValues: [{ type: Input }], noteTextField: [{ type: Input }], opacity: [{ type: Input }], openField: [{ type: Input }], outliersField: [{ type: Input }], overlay: [{ type: Input }], padding: [{ type: Input }], q1Field: [{ type: Input }], q3Field: [{ type: Input }], segmentSpacing: [{ type: Input }], size: [{ type: Input }], sizeField: [{ type: Input }], spacing: [{ type: Input }], stack: [{ type: Input }], startAngle: [{ type: Input }], style: [{ type: Input }], summaryField: [{ type: Input }], target: [{ type: Input }], toField: [{ type: Input }], type: [{ type: Input }], upperField: [{ type: Input }], visible: [{ type: Input }], visibleInLegend: [{ type: Input }], visibleInLegendField: [{ type: Input }], visual: [{ type: Input }], width: [{ type: Input }], whiskers: [{ type: Input }], xAxis: [{ type: Input }], xErrorHighField: [{ type: Input }], xErrorLowField: [{ type: Input }], xField: [{ type: Input }], yAxis: [{ type: Input }], yErrorHighField: [{ type: Input }], yErrorLowField: [{ type: Input }], yField: [{ type: Input }], zIndex: [{ type: Input }], trendline: [{ type: Input }], for: [{ type: Input }], legendItem: [{ type: Input }], pattern: [{ type: Input }], patternField: [{ type: Input }], errorBars: [{ type: Input }], extremes: [{ type: Input }], highlight: [{ type: Input }], labels: [{ type: Input }], markers: [{ type: Input }], notes: [{ type: Input }], outliers: [{ type: Input }], tooltip: [{ type: Input }], seriesTooltip: [{ type: ContentChild, args: [SeriesTooltipComponent, { static: false }] }], drilldownTemplate: [{ type: ContentChild, args: [SeriesDrilldownTemplateDirective, { static: false }] }] } }); const POSITION_MODE = 'absolute'; const COLLISION = { horizontal: "fit", vertical: "fit" }; /** * @hidden */ class BaseTooltip { popupService; localizationService; animate; style = {}; templateRef; popupRef = null; popupSettings; constructor(popupService, localizationService) { this.popupService = popupService; this.localizationService = localizationService; } get active() { return this.popupRef !== null; } show(e) { const align = e.anchor.align; const offset = this.position(e.anchor.point); this.style = e.style; if (!this.popupRef) { this.popupRef = this.popupService.open(Object.assign({ offset: offset, popupAlign: align, animate: this.animate, content: this.templateRef, collision: COLLISION, positionMode: POSITION_MODE }, this.popupSettings)); if (this.localizationService.rtl) { this.popupRef.popupElement.setAttribute('dir', 'rtl'); } this.onInit(); } else { const popup = this.popupRef.popup.instance; popup.offset = offset; popup.popupAlign = align; } } onInit() { /* noop */ } hide() { if (this.popupRef) { this.popupRef.close(); this.popupRef = null; } } ngOnDestroy() { this.hide(); } position(offset) { if (!this.popupSettings || !this.popupSettings.appendTo) { return offset; } const appendTo = this.popupSettings.appendTo.element.nativeElement; const bbox = appendTo.getBoundingClientRect(); const { scrollLeft, scrollTop } = this.scrollOffset(appendTo); return { left: offset.left - bbox.left - scrollLeft, top: offset.top - bbox.top - scrollTop }; } scrollOffset(element) { if (!element) { return null; } let scrollLeft = element.scrollLeft; let scrollTop = element.scrollTop; let parent = element.parentElement; while (parent) { scrollLeft += parent.scrollLeft; scrollTop += parent.scrollTop; parent = parent.parentElement; } return { scrollLeft, scrollTop }; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BaseTooltip, deps: [{ token: i1.PopupService }, { token: i1$1.LocalizationService }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: BaseTooltip, inputs: { popupSettings: "popupSettings" }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BaseTooltip, decorators: [{ type: Directive }], ctorParameters: function () { return [{ type: i1.PopupService }, { type: i1$1.LocalizationService }]; }, propDecorators: { popupSettings: [{ type: Input }] } }); /** * @hidden */ function bodyFactory() { if (isDocumentAvailable()) { return new ElementRef(document.body); } } /** * @hidden */ class CrosshairTooltipComponent extends BaseTooltip { renderer; templateRef; key; value; animate = false; constructor(popupService, localizationService, renderer) { super(popupService, localizationService); this.renderer = renderer; } onInit() { if (this.popupRef?.popupElement) { this.renderer.addClass(this.popupRef.popupElement, 'k-chart-tooltip-wrapper'); } } show(e) { super.show(e); this.value = e.value; this.popupRef.popup.changeDetectorRef.detectChanges(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CrosshairTooltipComponent, deps: [{ token: i1.PopupService }, { token: i1$1.LocalizationService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CrosshairTooltipComponent, isStandalone: true, selector: "kendo-chart-crosshair-tooltip", inputs: { key: "key" }, providers: [PopupService, { provide: POPUP_CONTAINER, useFactory: bodyFactory }], viewQueries: [{ propertyName: "templateRef", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: ` <ng-template #content> <div class="k-chart-tooltip k-chart-crosshair-tooltip" [ngStyle]="style"> {{ value }} </div> </ng-template> `, isInline: true, dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CrosshairTooltipComponent, decorators: [{ type: Component, args: [{ providers: [PopupService, { provide: POPUP_CONTAINER, useFactory: bodyFactory }], selector: 'kendo-chart-crosshair-tooltip', template: ` <ng-template #content> <div class="k-chart-tooltip k-chart-crosshair-tooltip" [ngStyle]="style"> {{ value }} </div> </ng-template> `, standalone: true, imports: [NgStyle] }] }], ctorParameters: function () { return [{ type: i1.PopupService }, { type: i1$1.LocalizationService }, { type: i0.Renderer2 }]; }, propDecorators: { templateRef: [{ type: ViewChild, args: ['content', { static: true }] }], key: [{ type: Input }] } }); const AXES = ["categoryAxis", "valueAxis", "xAxis", "yAxis"]; /** * @hidden */ class CrosshairTooltipsContainerComponent { popupSettings; crossahairTooltipComponents; tooltipKeys = []; tooltipsMap = {}; show(e) { const tooltipComponents = this.crossahairTooltipComponents.toArray(); const axisName = e.axisName; const axisIndex = e.axisIndex; for (let idx = 0; idx < tooltipComponents.length; idx++) { if (tooltipComponents[idx].key === axisName + axisIndex) { tooltipComponents[idx].show(e); break; } } } hide() { const tooltipComponents = this.crossahairTooltipComponents.toArray(); for (let idx = 0; idx < tooltipComponents.length; idx++) { tooltipComponents[idx].hide(); } } get active() { return this.tooltipKeys.length > 0; } createCrosshairTooltips(options) { const newMap = this.mapTooltips(options); const map = this.tooltipsMap; for (const key in map) { if (!newMap[key]) { this.removeTooltip(key); delete map[key]; } } for (const key in newMap) { if (!map[key] && key !== 'constructor' && key !==