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,018 lines (1,015 loc) 39.7 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, NgZone, Renderer2, ContentChildren, QueryList, ViewChild, EventEmitter, Input, Output, ElementRef } from '@angular/core'; import { ResizeSensorComponent, WatermarkOverlayComponent, isDocumentAvailable, shouldShowValidationUI } from '@progress/kendo-angular-common'; import { IntlService } from '@progress/kendo-angular-intl'; import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n'; import { Chart } from '@progress/kendo-charts'; import { exportImage, exportSVG } from '@progress/kendo-drawing'; import { validatePackage } from '@progress/kendo-licensing'; import { combineLatest } from 'rxjs'; import { auditTime, tap } from 'rxjs/operators'; import './chart-defaults'; import { DonutCenterTemplateDirective } from './chart/donut-center-template.directive'; import { NoDataTemplateDirective } from './chart/no-data-template.directive'; import { SeriesItemComponent } from './chart/series-item.component'; import { CrosshairTooltipsContainerComponent } from './chart/tooltip/crosshair-tooltips-container.component'; import { TooltipPopupComponent } from './chart/tooltip/tooltip-popup.component'; import { ChartInstanceObserver } from './common/chart-instance-observer'; import { ConfigurationService, THROTTLE_MS } from './common/configuration.service'; import { copyChanges } from './common/copy-changes'; import { hasParent } from './common/has-parent'; import { ThemeService } from './common/theme.service'; import { toSimpleChanges } from './common/to-simple-changes'; import { TooltipTemplateService } from './common/tooltip-template.service'; import { InstanceEventService } from './events/instance-event.service'; import { LegendItemClickEvent } from './events/legend-item-click-event'; import { RenderEvent } from './events/render-event'; import { packageMetadata } from './package-metadata'; import { SeriesComponent } from './chart/series.component'; import { DrilldownEvent } from './events/drilldown-event'; import { hasObservers } from './common/has-observers'; import { NgIf, NgStyle, NgTemplateOutlet } from '@angular/common'; import { LocalizedChartMessagesDirective } from './chart/localization/localized-messages.directive'; import * as i0 from "@angular/core"; import * as i1 from "./common/configuration.service"; import * as i2 from "./common/theme.service"; import * as i3 from "@progress/kendo-angular-intl"; import * as i4 from "@progress/kendo-angular-l10n"; import * as i5 from "./events/instance-event.service"; /** * The root Chart component. * * @example * ```ts * import { Component } from '@angular/core'; * * _@Component({ * selector: 'my-app', * template: ` * <button kendoButton (click)="toggleLegend()">Toggle Legend</button> * <button kendoButton (click)="toggleSeries()">Toggle Series</button> * <kendo-chart> * <kendo-chart-legend [visible]="legendVisible"> * </kendo-chart-legend> * <kendo-chart-series> * <kendo-chart-series-item *ngIf="seriesVisible" name="Series #1" * type="line" [data]="[1, 2, 3]"> * </kendo-chart-series-item> * </kendo-chart-series> * </kendo-chart> * ` * }) * class AppComponent { * public legendVisible: boolean = true; * public seriesVisible: boolean = true; * * public toggleSeries(): void { * this.seriesVisible = !this.seriesVisible; * } * * public toggleLegend(): void { * this.legendVisible = !this.legendVisible; * } * } * * ``` */ export class ChartComponent { configurationService; themeService; element; intl; localizationService; ngZone; instanceEventService; changeDetector; renderer; /** * Specifies if the Chart can be panned. * Panning is not available for the `Donut`, `Pie`, `Funnel`, `Pyramid`, `Polar`, and `Radar` series. * @default false */ pannable; renderAs; seriesColors; subtitle; title; noData = true; /** * If set to `true`, the Chart plays animations when it displays the series. * By default, animations are enabled. * @default true */ transitions; zoomable; axisDefaults; categoryAxis; chartArea; legend; panes; paneDefaults; plotArea; series; seriesDefaults; tooltip; valueAxis; xAxis; yAxis; /** * Fires when the user clicks an axis label ([see example](slug:events_chart)). */ axisLabelClick = new EventEmitter(); /** * Fires as long as the user is dragging the Chart with the mouse or through swipe gestures. */ drag = new EventEmitter(); /** * Fires when the user stops dragging the Chart. */ dragEnd = new EventEmitter(); /** * Fires when the user starts dragging the Chart. */ dragStart = new EventEmitter(); /** * Fires when the user hovers over a legend item ([see example](slug:events_chart)). */ legendItemHover = new EventEmitter(); /** * Fires when the cursor leaves a legend item. */ legendItemLeave = new EventEmitter(); /** * Fires when the user clicks a note. */ noteClick = new EventEmitter(); /** * Fires when the user hovers over a note. */ noteHover = new EventEmitter(); /** * Fires when the cursor leaves a note. */ noteLeave = new EventEmitter(); /** * Fires when a pane is rendered because the Chart is rendered, performs panning or zooming, or is exported with different options. * The event is used to render custom visuals in the panes. */ paneRender = new EventEmitter(); /** * Fires when the user clicks the plot area ([see example](slug:events_chart)). * The `click` event is triggered by the `tap` and `contextmenu` events. * To distinguish between the original events, inspect the `e.originalEvent.type` field. */ plotAreaClick = new EventEmitter(); /** * Fires when the user hovers the plot area ([see example](slug:events_chart)). */ plotAreaHover = new EventEmitter(); /** * Fires when the cursor leaves the plot area. */ plotAreaLeave = new EventEmitter(); /** * Fires when the Chart is ready to render on screen ([see example](slug:events_chart)). * For example, you can use it to remove loading indicators. * Any changes made to the options are ignored. */ render = new EventEmitter(); /** * Fires when the user modifies the selection. * * The range units include a generic axis category index (0-based) and a date axis represented by a date instance. */ select = new EventEmitter(); /** * Fires when the user completes the modification of the selection. * * The range units include a generic axis category index (0-based) and a date axis represented by a date instance. */ selectEnd = new EventEmitter(); /** * Fires when the user starts modifying the axis selection. * * The range units include a generic axis category index (0-based) and a date axis represented by a date instance. */ selectStart = new EventEmitter(); /** * Fires when the user clicks the Chart series. * * The `click` event will be triggered by the `tap` and `contextmenu` events ([see example](slug:events_chart)). * To distinguish between the original events, inspect the `e.originalEvent.type` field. */ seriesClick = new EventEmitter(); /** * Fires when the user when the user wants to drill down on a specific point. */ drilldown = new EventEmitter(); /** * Fires when the user hovers the Chart series ([see example](slug:events_chart)). */ seriesHover = new EventEmitter(); /** * Fires when the cursor enters a series. */ seriesOver = new EventEmitter(); /** * Fires when the cursor leaves a series. */ seriesLeave = new EventEmitter(); /** * Fires as long as the user is zooming the Chart by using the mousewheel operation. */ zoom = new EventEmitter(); /** * Fires when the user stops zooming the Chart. */ zoomEnd = new EventEmitter(); /** * Fires when the user uses the mousewheel to zoom the Chart. */ zoomStart = new EventEmitter(); /** * Fires when a legend item is clicked before the selected series visibility is toggled. * Can be prevented. */ legendItemClick = new EventEmitter(); /** * Fires when the drill-down level has changed. */ drilldownLevelChange = new EventEmitter(); /** * Limits the automatic resizing of the Chart. Sets the maximum number of times per second * that the component redraws its content when the size of its container changes. * Defaults to `10`. To disable the automatic resizing, set it to `0`. * * @default 10 */ resizeRateLimit = 10; /** * The settings for the tooltip popup. */ popupSettings; /** * Gets or sets the current drill-down level for [Drilldown Charts](slug:drilldown_chart_charts). * * To return to a previous level, set the value to a number less than the current level. * To return to the root chart, set the value to 0. * * Setting the value to a number greater than the current level will have no effect. */ get drilldownLevel() { return this.drilldownState.length; } set drilldownLevel(level) { const currentLevel = this.drilldownState.length; if (currentLevel <= level || !this.seriesComponents) { return; } this.drilldownState.slice(level, currentLevel).forEach((view) => { const hiddenSeries = view.hiddenSeries; hiddenSeries?.forEach(series => { series.hidden = false; }); view.destroy(); }); this.drilldownState.length = level; this.drilldownLevelChange.emit(level); } /** * The Drawing `Surface` of the Chart. */ surface; seriesCollectionComponent; seriesComponents; donutCenterTemplate; noDataTemplate; tooltipInstance; crossahirTooltips; surfaceElement; /** * @hidden */ donutCenterStyle; /** * @hidden */ messageFor(key) { return this.localizationService.get(key); } /** * @hidden */ showLicenseWatermark = false; instance; options; theme = null; optionsChange; suppressTransitions = false; resizeTimeout; redrawTimeout; domSubscriptions; destroyed; subscriptions; rtl = false; hostClasses = ['k-chart', 'k-widget']; drilldownState = []; constructor(configurationService, themeService, element, intl, localizationService, ngZone, instanceEventService, changeDetector, renderer) { this.configurationService = configurationService; this.themeService = themeService; this.element = element; this.intl = intl; this.localizationService = localizationService; this.ngZone = ngZone; this.instanceEventService = instanceEventService; this.changeDetector = changeDetector; this.renderer = renderer; const isValid = validatePackage(packageMetadata); this.showLicenseWatermark = shouldShowValidationUI(isValid); this.themeService.loadTheme(); this.refreshWait(); } ngOnInit() { if (this.element) { this.hostClasses.forEach(name => { this.renderer.addClass(this.element.nativeElement, name); }); this.renderer.setStyle(this.element.nativeElement, 'position', 'relative'); } } ngAfterViewInit() { if (this.canRender) { this.ngZone.runOutsideAngular(() => { const chartMouseleave = this.renderer.listen(this.surfaceElement.nativeElement, 'mouseleave', this.chartMouseleave.bind(this)); this.domSubscriptions = () => { chartMouseleave(); }; }); } this.setDirection(); this.subscriptions = this.intl.changes.subscribe(this.intlChange.bind(this)); this.subscriptions.add(this.localizationService.changes.subscribe(this.rtlChange.bind(this))); } onDrilldown(e) { const seriesComponent = this.seriesComponents.find(sc => sc.name === e.series.name); const seriesCollection = this.seriesCollectionComponent.first; if (!seriesComponent?.drilldownTemplate || !seriesCollection) { return; } const args = new DrilldownEvent(e, this); this.run(() => this.drilldown.emit(args)); if (args.isDefaultPrevented()) { return; } const hiddenSeries = []; this.seriesComponents.forEach(series => { if (!series.hidden) { series.hidden = true; hiddenSeries.push(series); } }); const view = seriesCollection.viewContainer.createEmbeddedView(seriesComponent.drilldownTemplate.templateRef, { drilldownValue: e.value, point: e.point, series: e.series }); view.hiddenSeries = hiddenSeries; view.markForCheck(); this.drilldownState.push(view); this.drilldownLevelChange.emit(this.drilldownLevel); } ngAfterViewChecked() { if (this.instance && this.autoResize) { this.ngZone.runOutsideAngular(() => { clearTimeout(this.resizeTimeout); this.resizeTimeout = setTimeout(() => { this.resize(); }, 0); }); } } ngOnChanges(changes) { const store = this.configurationService.store; copyChanges(changes, store); store.popupSettings = null; 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 * chart.notifyChanges({ title: { text: 'New Title' } }); * ``` * * @param changes An object containing the updated input fields. */ notifyChanges(changes) { this.ngOnChanges(toSimpleChanges(changes)); } ngOnDestroy() { this.destroyed = true; if (this.optionsChange) { this.optionsChange.unsubscribe(); } if (this.domSubscriptions) { this.domSubscriptions(); this.domSubscriptions = null; } if (this.instance) { this.instance.destroy(); this.instance = null; } if (this.subscriptions) { this.subscriptions.unsubscribe(); } clearTimeout(this.resizeTimeout); clearTimeout(this.redrawTimeout); } createInstance(element, observer) { this.instance = new Chart(element, this.options, this.theme, { intlService: this.intl, observer: observer, rtl: this.rtl, sender: this }); } /** * Exports the Chart as an image. The export operation is asynchronous and returns a promise. * * @param {ImageExportOptions} options - The parameters for the exported image. * @returns {Promise<string>} - A promise that will be resolved with a PNG image encoded as a Data URI. */ exportImage(options = {}) { return exportImage(this.exportVisual(options), options); } /** * Exports the Chart as an SVG document. The export operation is asynchronous and returns a promise. * * @param options - The parameters for the exported file. * @returns - A promise that will be resolved with an SVG document that is encoded as a Data URI. */ exportSVG(options = {}) { return exportSVG(this.exportVisual(options), options); } /** * Exports the Chart as a Drawing `Scene`. * * @param options - The parameters for the export operation. * @returns - The root Group of the scene. */ exportVisual(options = {}) { return this.instance.exportVisual(options); } /** * Returns the axis with the specified name. * * @param {string} name - The axis name. * @returns {ChartAxis} - The axis with a corresponding name. */ findAxisByName(name) { if (this.instance) { return this.instance.findAxisByName(name); } } /** * Returns the pane at the specified index. * * @param {number} index - The pane index. * @returns {ChartPane} - The pane at the specified index. */ findPaneByIndex(index) { if (this.instance) { return this.instance.findPaneByIndex(index); } } /** * Returns the pane with the specified name. * * @param {string} name - The name of the pane. * @returns {ChartPane} - The pane with the provided name. */ findPaneByName(name) { if (this.instance) { return this.instance.findPaneByName(name); } } /** * Returns the plot area of the Chart. * @returns {ChartPlotArea} - The plot area of the Chart. */ getPlotArea() { if (this.instance) { return this.instance.plotArea(); } } /** * Highlights the series points or the segments of a Pie, Donut, Funnel or Pyramid charts. * * See [Series Highlight]({% slug serieshighlight_chart_charts %}) for more details (with an [example](slug:serieshighlight_chart_charts#toc-toggling-the-highlight-with-code)). * @param show - A Boolean value that indicates whether the highlight is shown or hidden. * @param filter - A string that represents the series or category name, an object with the series and category name, or a function which will be called for each point. The function should return `true` for the points for which the highlight is toggled. */ toggleHighlight(show, filter) { if (this.instance) { this.instance.toggleHighlight(show, filter); } } /** * Hides the tooltip of the Chart. */ hideTooltip() { if (this.instance) { this.instance.hideTooltip(); } } /** * Shows the Chart tooltip of a specific point or the shared tooltip of a specific category. * * @param filter - The category for a shared tooltip or a function which will be called for each point until the function returns `true`. */ showTooltip(filter) { if (this.instance) { this.instance.showTooltip(filter); } } init() { if (!this.canRender) { return; } const element = this.surfaceElement.nativeElement; const instanceObserver = new ChartInstanceObserver(this); this.createInstance(element, instanceObserver); } /** * Detects the size of the container and redraws the Chart. * Resizing is automatic unless you set the `resizeRateLimit` option to `0`. */ resize() { if (this.instance) { this.instance.resize(); } } /** * @hidden */ onResize() { if (this.autoResize) { this.resize(); } } /** * Reloads the Chart appearance settings from the current [Kendo UI Theme]({% slug themesandstyles %}). * * Call this method after loading a different theme stylesheet. */ reloadTheme() { if (!this.instance) { return; } this.themeService.reset(); this.instance.destroy(); this.instance = null; } onLegendItemClick(e) { this.run(() => { const args = new LegendItemClickEvent(e, this); this.legendItemClick.emit(args); if (!args.isDefaultPrevented()) { const series = this.seriesComponents.toArray()[e.series.index]; if (!series) { return; } if (e.pointIndex !== undefined) { series.togglePointVisibility(e.pointIndex); } else { series.toggleVisibility(); } this.suppressTransitions = true; } }, hasObservers(this.legendItemClick), this.seriesComponents.length > 0); } onInit(e) { this.instance = e.sender; } onRender(e) { const donutCenterStyle = this.getDonutCenterStyle(); this.run(() => { const args = new RenderEvent(e, this); this.surface = e.sender.surface; this.render.emit(args); this.donutCenterStyle = donutCenterStyle; }, hasObservers(this.render), this.donutCenterStyle !== donutCenterStyle); } onShowTooltip(e) { this.run(() => { if (!e.crosshair) { this.tooltipInstance.show(e); } else { this.crossahirTooltips.show(e); } }, !e.crosshair, true); } onHideTooltip(e) { if (!e.crosshair) { if (this.tooltipInstance.active) { this.tooltipInstance.hide(); this.detectChanges(); } } else if (this.crossahirTooltips.active) { this.crossahirTooltips.hide(); this.detectChanges(); } } trigger(name, e) { if (name === 'resize') { return; } if (name === 'drilldown') { this.onDrilldown(e); return; } const emitter = this.activeEmitter(name); if (emitter) { const args = this.instanceEventService.create(name, e, this); this.run(() => { emitter.emit(args); }); return args.isDefaultPrevented && args.isDefaultPrevented(); } } requiresHandlers(names) { for (let idx = 0; idx < names.length; idx++) { if (this.activeEmitter(names[idx])) { return true; } } return false; } refresh() { clearTimeout(this.redrawTimeout); this.updateDirection(); this.crossahirTooltips.createCrosshairTooltips(this.options); this.setChartAreaSize(); if (!this.instance) { this.init(); return; } const transitions = this.options.transitions; if (this.suppressTransitions) { this.options.transitions = false; } this.updateOptions(); if (this.suppressTransitions) { this.options.transitions = transitions; this.suppressTransitions = false; } } setChartAreaSize() { if (!this.element) { return; } const element = this.element.nativeElement; const chartArea = this.options.chartArea || {}; if (chartArea.width) { element.style.width = `${chartArea.width}px`; } if (chartArea.height) { element.style.height = `${chartArea.height}px`; } } updateOptions() { this.instance.setOptions(this.options); } /** * @hidden */ tooltipMouseleave(e) { const relatedTarget = e.relatedTarget; const chartElement = this.element.nativeElement; if (this.instance && (!relatedTarget || !hasParent(relatedTarget, chartElement))) { this.instance.hideElements(); } } /** * @hidden */ chartMouseleave(e) { const relatedTarget = e.relatedTarget; const chartElement = this.element.nativeElement; if (this.instance && (!relatedTarget || !(this.tooltipInstance.containsElement(relatedTarget) || hasParent(relatedTarget, chartElement))) && !this.instance.handlingTap) { this.instance.hideElements(); } } get canRender() { return isDocumentAvailable() && Boolean(this.surfaceElement); } get autoResize() { return this.resizeRateLimit > 0; } activeEmitter(name) { const emitter = this[name]; if (emitter && emitter.emit && hasObservers(emitter)) { return emitter; } } getDonutCenterStyle() { if (!this.instance || !this.options || !this.options.series) { return; } const firstSeries = this.options.series[0]; const charts = this.instance._plotArea.charts; if (!firstSeries || firstSeries.type !== 'donut' || !charts || charts[0].points.length === 0) { return; } const firstPoint = charts[0].points[0]; const center = firstPoint.box.center(); const radius = firstPoint.sector.innerRadius; const top = center.y - radius; const left = center.x - radius; const size = radius * 2; return { height: size + 'px', left: left + 'px', top: top + 'px', width: size + 'px' }; } refreshWait() { this.ngZone.runOutsideAngular(() => { this.optionsChange = combineLatest(this.configurationService.onChange$, this.themeService.onChange$).pipe(tap((result) => { this.options = result[0]; this.theme = result[1]; }), auditTime(THROTTLE_MS)) .subscribe(() => { this.refresh(); }); }); } run(callback, inZone = true, detectChanges) { if (inZone) { if (detectChanges) { this.changeDetector.markForCheck(); } this.ngZone.run(callback); } else { callback(); if (detectChanges) { this.detectChanges(); } } } detectChanges() { if (!this.destroyed) { this.changeDetector.detectChanges(); } } intlChange() { if (this.instance) { this.deferredRedraw(); } } rtlChange() { if (this.instance && this.rtl !== this.isRTL) { this.deferredRedraw(); } } deferredRedraw() { this.ngZone.runOutsideAngular(() => { clearTimeout(this.redrawTimeout); this.redrawTimeout = setTimeout(() => { this.updateDirection(); this.instance.noTransitionsRedraw(); }, 0); }); } updateDirection() { const current = this.isRTL; if (this.rtl !== current) { this.setDirection(); if (this.instance) { this.instance.setDirection(current); } } } setDirection() { this.rtl = this.isRTL; if (this.element) { this.renderer.setAttribute(this.element.nativeElement, 'dir', this.rtl ? 'rtl' : 'ltr'); } } get isRTL() { return Boolean(this.localizationService.rtl); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChartComponent, deps: [{ token: i1.ConfigurationService }, { token: i2.ThemeService }, { token: i0.ElementRef }, { token: i3.IntlService }, { token: i4.LocalizationService }, { token: i0.NgZone }, { token: i5.InstanceEventService }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ChartComponent, isStandalone: true, selector: "kendo-chart", inputs: { pannable: "pannable", renderAs: "renderAs", seriesColors: "seriesColors", subtitle: "subtitle", title: "title", noData: "noData", transitions: "transitions", zoomable: "zoomable", axisDefaults: "axisDefaults", categoryAxis: "categoryAxis", chartArea: "chartArea", legend: "legend", panes: "panes", paneDefaults: "paneDefaults", plotArea: "plotArea", series: "series", seriesDefaults: "seriesDefaults", tooltip: "tooltip", valueAxis: "valueAxis", xAxis: "xAxis", yAxis: "yAxis", resizeRateLimit: "resizeRateLimit", popupSettings: "popupSettings", drilldownLevel: "drilldownLevel" }, outputs: { axisLabelClick: "axisLabelClick", drag: "drag", dragEnd: "dragEnd", dragStart: "dragStart", legendItemHover: "legendItemHover", legendItemLeave: "legendItemLeave", noteClick: "noteClick", noteHover: "noteHover", noteLeave: "noteLeave", paneRender: "paneRender", plotAreaClick: "plotAreaClick", plotAreaHover: "plotAreaHover", plotAreaLeave: "plotAreaLeave", render: "render", select: "select", selectEnd: "selectEnd", selectStart: "selectStart", seriesClick: "seriesClick", drilldown: "drilldown", seriesHover: "seriesHover", seriesOver: "seriesOver", seriesLeave: "seriesLeave", zoom: "zoom", zoomEnd: "zoomEnd", zoomStart: "zoomStart", legendItemClick: "legendItemClick", drilldownLevelChange: "drilldownLevelChange" }, providers: [ ConfigurationService, TooltipTemplateService, InstanceEventService, LocalizationService, { provide: L10N_PREFIX, useValue: 'kendo.chart' } ], queries: [{ propertyName: "donutCenterTemplate", first: true, predicate: DonutCenterTemplateDirective, descendants: true }, { propertyName: "noDataTemplate", first: true, predicate: NoDataTemplateDirective, descendants: true }, { propertyName: "seriesCollectionComponent", predicate: SeriesComponent }, { propertyName: "seriesComponents", predicate: SeriesItemComponent, descendants: true }], viewQueries: [{ propertyName: "tooltipInstance", first: true, predicate: TooltipPopupComponent, descendants: true, static: true }, { propertyName: "crossahirTooltips", first: true, predicate: CrosshairTooltipsContainerComponent, descendants: true, static: true }, { propertyName: "surfaceElement", first: true, predicate: ["surface"], descendants: true, static: true }], exportAs: ["kendoChart"], usesOnChanges: true, ngImport: i0, template: ` <ng-container kendoChartLocalizedMessages i18n-noData="kendo.chart.noData|The message to display when no series are defined, or all series are empty" noData="No data available" ></ng-container> <div #surface class="k-chart-surface"> <div *ngIf="noData" class='k-chart-overlay' [style.display]="'none'"> <div class='k-no-data'> <ng-template *ngIf="noDataTemplate; else noDataMessage" [ngTemplateOutlet]="noDataTemplate.templateRef"></ng-template> <ng-template #noDataMessage> {{ messageFor('noData') }} </ng-template> </div> </div> </div> <kendo-chart-crosshair-tooltips-container [popupSettings]="popupSettings"> </kendo-chart-crosshair-tooltips-container> <kendo-chart-tooltip-popup (leave)="tooltipMouseleave($event)" [popupSettings]="popupSettings"> </kendo-chart-tooltip-popup> <kendo-resize-sensor (resize)="onResize()" [rateLimit]="resizeRateLimit"></kendo-resize-sensor> <div class="k-chart-donut-center" [ngStyle]="donutCenterStyle" *ngIf="donutCenterStyle && donutCenterTemplate"> <ng-template [ngTemplateOutlet]="donutCenterTemplate.templateRef"></ng-template> </div> <div kendoWatermarkOverlay *ngIf="showLicenseWatermark"></div> `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedChartMessagesDirective, selector: "[kendoChartLocalizedMessages]" }, { kind: "component", type: CrosshairTooltipsContainerComponent, selector: "kendo-chart-crosshair-tooltips-container", inputs: ["popupSettings"] }, { kind: "component", type: TooltipPopupComponent, selector: "kendo-chart-tooltip-popup", inputs: ["animate", "classNames", "wrapperClass"], outputs: ["leave"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: WatermarkOverlayComponent, selector: "div[kendoWatermarkOverlay]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChartComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, exportAs: 'kendoChart', providers: [ ConfigurationService, TooltipTemplateService, InstanceEventService, LocalizationService, { provide: L10N_PREFIX, useValue: 'kendo.chart' } ], selector: 'kendo-chart', template: ` <ng-container kendoChartLocalizedMessages i18n-noData="kendo.chart.noData|The message to display when no series are defined, or all series are empty" noData="No data available" ></ng-container> <div #surface class="k-chart-surface"> <div *ngIf="noData" class='k-chart-overlay' [style.display]="'none'"> <div class='k-no-data'> <ng-template *ngIf="noDataTemplate; else noDataMessage" [ngTemplateOutlet]="noDataTemplate.templateRef"></ng-template> <ng-template #noDataMessage> {{ messageFor('noData') }} </ng-template> </div> </div> </div> <kendo-chart-crosshair-tooltips-container [popupSettings]="popupSettings"> </kendo-chart-crosshair-tooltips-container> <kendo-chart-tooltip-popup (leave)="tooltipMouseleave($event)" [popupSettings]="popupSettings"> </kendo-chart-tooltip-popup> <kendo-resize-sensor (resize)="onResize()" [rateLimit]="resizeRateLimit"></kendo-resize-sensor> <div class="k-chart-donut-center" [ngStyle]="donutCenterStyle" *ngIf="donutCenterStyle && donutCenterTemplate"> <ng-template [ngTemplateOutlet]="donutCenterTemplate.templateRef"></ng-template> </div> <div kendoWatermarkOverlay *ngIf="showLicenseWatermark"></div> `, standalone: true, imports: [LocalizedChartMessagesDirective, CrosshairTooltipsContainerComponent, TooltipPopupComponent, ResizeSensorComponent, NgIf, NgStyle, NgTemplateOutlet, WatermarkOverlayComponent] }] }], ctorParameters: function () { return [{ type: i1.ConfigurationService }, { type: i2.ThemeService }, { type: i0.ElementRef }, { type: i3.IntlService }, { type: i4.LocalizationService }, { type: i0.NgZone }, { type: i5.InstanceEventService }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }]; }, propDecorators: { pannable: [{ type: Input }], renderAs: [{ type: Input }], seriesColors: [{ type: Input }], subtitle: [{ type: Input }], title: [{ type: Input }], noData: [{ type: Input }], transitions: [{ type: Input }], zoomable: [{ type: Input }], axisDefaults: [{ type: Input }], categoryAxis: [{ type: Input }], chartArea: [{ type: Input }], legend: [{ type: Input }], panes: [{ type: Input }], paneDefaults: [{ type: Input }], plotArea: [{ type: Input }], series: [{ type: Input }], seriesDefaults: [{ type: Input }], tooltip: [{ type: Input }], valueAxis: [{ type: Input }], xAxis: [{ type: Input }], yAxis: [{ type: Input }], axisLabelClick: [{ type: Output }], drag: [{ type: Output }], dragEnd: [{ type: Output }], dragStart: [{ type: Output }], legendItemHover: [{ type: Output }], legendItemLeave: [{ type: Output }], noteClick: [{ type: Output }], noteHover: [{ type: Output }], noteLeave: [{ type: Output }], paneRender: [{ type: Output }], plotAreaClick: [{ type: Output }], plotAreaHover: [{ type: Output }], plotAreaLeave: [{ type: Output }], render: [{ type: Output }], select: [{ type: Output }], selectEnd: [{ type: Output }], selectStart: [{ type: Output }], seriesClick: [{ type: Output }], drilldown: [{ type: Output }], seriesHover: [{ type: Output }], seriesOver: [{ type: Output }], seriesLeave: [{ type: Output }], zoom: [{ type: Output }], zoomEnd: [{ type: Output }], zoomStart: [{ type: Output }], legendItemClick: [{ type: Output }], drilldownLevelChange: [{ type: Output }], resizeRateLimit: [{ type: Input }], popupSettings: [{ type: Input }], drilldownLevel: [{ type: Input }], seriesCollectionComponent: [{ type: ContentChildren, args: [SeriesComponent] }], seriesComponents: [{ type: ContentChildren, args: [SeriesItemComponent, { descendants: true }] }], donutCenterTemplate: [{ type: ContentChild, args: [DonutCenterTemplateDirective, { static: false }] }], noDataTemplate: [{ type: ContentChild, args: [NoDataTemplateDirective, { static: false }] }], tooltipInstance: [{ type: ViewChild, args: [TooltipPopupComponent, { static: true }] }], crossahirTooltips: [{ type: ViewChild, args: [CrosshairTooltipsContainerComponent, { static: true }] }], surfaceElement: [{ type: ViewChild, args: ['surface', { static: true }] }] } });