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.

248 lines (242 loc) 11.6 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2024 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Injectable, NgZone } from '@angular/core'; import { ConfigurationService } from './configuration.service'; import { chartBaseTheme } from '@progress/kendo-charts'; import { chartDefaultTheme } from './chart-default-theme'; import { isDocumentAvailable } from '@progress/kendo-angular-common'; import * as i0 from "@angular/core"; const font = (style) => `${style.fontWeight} ${style.fontSize} ${style.fontFamily}`; const computedBackgroundColor = (element) => window.getComputedStyle(element).backgroundColor; const letterPos = (letter) => letter.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0); const seriesPos = (name) => { const alpha = name.match(/series-([a-z])$/); if (alpha !== null) { return letterPos(alpha[1]); } const num = name.split('--series-')[1]; return parseInt(num, 10) - 1; }; const SERIES_COLORS = 30; const seriesTemplate = () => { let template = ` <div class="k-var--series-a"></div> <div class="k-var--series-b"></div> <div class="k-var--series-c"></div> <div class="k-var--series-d"></div> <div class="k-var--series-e"></div> <div class="k-var--series-f"></div> `; for (let i = 0; i < SERIES_COLORS; i++) { template += ` <div class="k-var--series-${i + 1}"></div>`; } return template; }; const template = () => ` <div class="k-var--primary"></div> <div class="k-var--primary-contrast"></div> <div class="k-var--base"></div> <div class="k-var--background"></div> <div class="k-var--kendo-color-subtle"></div> <div class="k-var--normal-background"></div> <div class="k-var--normal-text-color"></div> <div class="k-var--hover-background"></div> <div class="k-var--hover-text-color"></div> <div class="k-var--selected-background"></div> <div class="k-var--selected-text-color"></div> <div class="k-var--chart-error-bars-background"></div> <div class="k-var--chart-notes-background"></div> <div class="k-var--chart-notes-border"></div> <div class="k-var--chart-notes-lines"></div> <div class="k-var--chart-crosshair-background"></div> <div class="k-var--chart-inactive"></div> <div class="k-var--chart-major-lines"></div> <div class="k-var--chart-minor-lines"></div> <div class="k-var--chart-area-opacity"></div> <div class="k-var--chart-area-inactive-opacity"></div> <div class="k-var--chart-line-inactive-opacity"></div> <div class="k-widget k-chart"> <div class="k-var--chart-font"></div> <div class="k-var--chart-title-font"></div> <div class="k-var--chart-pane-title-font"></div> <div class="k-var--chart-label-font"></div> </div> <div class="k-var--series-unset"></div> <div class="k-var--series"> ${seriesTemplate()} </div> `; /** * @hidden */ export class ThemeService extends ConfigurationService { loaded = false; element; constructor(ngZone) { super(ngZone); } loadTheme() { if (this.loaded || !isDocumentAvailable()) { return; } if (!this.readTheme()) { this.readDefaultTheme(); } this.loaded = true; this.next(); } reset() { this.store = {}; this.loaded = false; this.loadTheme(); } readTheme() { this.createElement(); const available = this.queryColor('primary') !== this.queryColor('primary-contrast'); try { if (available) { this.push(chartBaseTheme()); this.setColors(); this.setFonts(); this.setSeriesColors(); } } finally { this.destroyElement(); } return available; } readDefaultTheme() { this.push(chartDefaultTheme()); } createElement() { const container = this.element = document.createElement('div'); container.style.display = 'none'; container.innerHTML = template(); document.body.appendChild(container); } destroyElement() { if (this.element) { document.body.removeChild(this.element); this.element = undefined; } } setStyle(key, value) { this.set(key, value); } setColors() { this.mapColor('axisDefaults.crosshair.color', 'chart-crosshair-background'); this.mapColor('axisDefaults.labels.color', 'normal-text-color'); this.mapColor('axisDefaults.line.color', 'chart-major-lines'); this.mapColor('axisDefaults.majorGridLines.color', 'chart-major-lines'); this.mapColor('axisDefaults.minorGridLines.color', 'chart-minor-lines'); this.mapColor('axisDefaults.notes.icon.background', 'chart-notes-background'); this.mapColor('axisDefaults.notes.icon.border.color', 'chart-notes-border'); this.mapColor('axisDefaults.notes.line.color', 'chart-notes-lines'); this.mapColor('axisDefaults.title.color', 'normal-text-color'); this.mapColor('chartArea.background', 'background'); this.mapColor('legend.inactiveItems.labels.color', 'chart-inactive'); this.mapColor('legend.inactiveItems.markers.color', 'chart-inactive'); this.mapColor('legend.labels.color', 'normal-text-color'); this.mapColor('legend.title.color', 'normal-text-color'); this.mapColor('seriesDefaults.boxPlot.downColor', 'chart-major-lines'); this.mapColor('seriesDefaults.boxPlot.mean.color', 'base'); this.mapColor('seriesDefaults.boxPlot.median.color', 'base'); this.mapColor('seriesDefaults.boxPlot.whiskers.color', 'primary'); this.mapColor('seriesDefaults.bullet.target.color', 'normal-text-color'); this.mapColor('seriesDefaults.candlestick.downColor', 'normal-text-color'); this.mapColor('seriesDefaults.candlestick.line.color', 'normal-text-color'); this.mapColor('seriesDefaults.errorBars.color', 'chart-error-bars-background'); this.mapColor('seriesDefaults.horizontalWaterfall.line.color', 'chart-major-lines'); this.mapColor('seriesDefaults.icon.border.color', 'chart-major-lines'); this.mapColor('seriesDefaults.labels.background', 'background'); this.mapColor('seriesDefaults.labels.color', 'normal-text-color'); this.mapColor('seriesDefaults.notes.icon.background', 'chart-notes-background'); this.mapColor('seriesDefaults.notes.icon.border.color', 'chart-notes-border'); this.mapColor('seriesDefaults.notes.line.color', 'chart-notes-lines'); this.mapColor('seriesDefaults.verticalBoxPlot.downColor', 'chart-major-lines'); this.mapColor('seriesDefaults.verticalBoxPlot.mean.color', 'base'); this.mapColor('seriesDefaults.verticalBoxPlot.median.color', 'base'); this.mapColor('seriesDefaults.verticalBoxPlot.whiskers.color', 'primary'); this.mapColor('seriesDefaults.verticalBullet.target.color', 'normal-text-color'); this.mapColor('seriesDefaults.waterfall.line.color', 'chart-major-lines'); this.mapColor('title.color', 'normal-text-color'); this.mapColor('subtitle.color', 'normal-text-color'); // Sankey diagram this.mapColor('labels.color', 'normal-text-color'); this.mapColor('labels.stroke.color', 'background'); // 'k-var--kendo-color-subtle' class does not contain the --kendo-color-subtle variable style const element = this.element.querySelector('.k-var--kendo-color-subtle'); element.style.color = 'var(--kendo-color-subtle)'; this.mapColor('links.color', 'kendo-color-subtle', 'color'); const opacity = parseFloat(this.queryStyle('chart-area-opacity').opacity); if (!isNaN(opacity)) { this.setStyle('seriesDefaults.area.opacity', opacity); this.setStyle('seriesDefaults.radarArea.opacity', opacity); this.setStyle('seriesDefaults.verticalArea.opacity', opacity); this.setStyle('seriesDefaults.labels.opacity', opacity); } this.setInactiveOpacity(['area', 'verticalArea'], 'chart-area-inactive-opacity'); this.setInactiveOpacity(['line', 'verticalLine'], 'chart-line-inactive-opacity'); } setInactiveOpacity(seriesTypes, selector) { const inactiveOpacity = parseFloat(this.queryStyle(selector).opacity); if (!isNaN(inactiveOpacity) && inactiveOpacity < 1) { seriesTypes.forEach(type => this.setStyle(`seriesDefaults.${type}.highlight.inactiveOpacity`, inactiveOpacity)); } } setFonts() { const defaultFont = font(this.queryStyle('chart-font')); const titleFont = font(this.queryStyle('chart-title-font')); const paneTitleFont = font(this.queryStyle('chart-pane-title-font')); const labelFont = font(this.queryStyle('chart-label-font')); this.setStyle('axisDefaults.labels.font', labelFont); this.setStyle('axisDefaults.notes.label.font', defaultFont); this.setStyle('axisDefaults.title.font', defaultFont); this.setStyle('legend.labels.font', defaultFont); this.setStyle('seriesDefaults.labels.font', labelFont); this.setStyle('seriesDefaults.notes.label.font', defaultFont); this.setStyle('title.font', titleFont); this.setStyle('subtitle.font', paneTitleFont); this.setStyle('paneDefaults.title.font', paneTitleFont); // Sankey diagram this.setStyle('labels.font', defaultFont); } setSeriesColors() { const element = this.element; const series = [].slice.call(element.querySelectorAll('.k-var--series div')); const unsetColor = computedBackgroundColor(element.querySelector('.k-var--series-unset')); const seriesColors = series.reduce((arr, el) => { const pos = seriesPos(el.className); const color = computedBackgroundColor(el); if (color !== unsetColor) { arr[pos] = color; } return arr; }, [] // Will populate the series colors in this array ); this.setStyle('seriesColors', seriesColors); } mapColor(key, varName, styleKey = 'backgroundColor') { this.setStyle(key, this.queryStyle(varName)[styleKey]); } queryColor(varName) { return this.queryStyle(varName).backgroundColor; } queryStyle(varName) { const element = this.element.querySelector(`.k-var--${varName}`); return window.getComputedStyle(element); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ThemeService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ThemeService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ThemeService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });