@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
JavaScript
/**-----------------------------------------------------------------------------------------
* 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 }]
}] } });