2156 lines
51 KiB
TypeScript
2156 lines
51 KiB
TypeScript
import {
|
|
Component,
|
|
ViewChild,
|
|
ElementRef,
|
|
HostListener,
|
|
ChangeDetectionStrategy,
|
|
} from '@angular/core';
|
|
import {
|
|
nameof,
|
|
XMimeType,
|
|
downloadFile,
|
|
generateUuid,
|
|
getXColorValue,
|
|
downloadFileByUrl,
|
|
isNullOrUndefined,
|
|
isNullOrEmptyString,
|
|
XColorWithBrightness,
|
|
downloadArrayBufferedFile,
|
|
} from 'x-framework-core';
|
|
import {
|
|
isChartType,
|
|
XChartAction,
|
|
XChartOptions,
|
|
XChartEventOpts,
|
|
XChartTextAlign,
|
|
XChartSeriesType,
|
|
isChartTextAlign,
|
|
XChartActionBarItem,
|
|
XChartDrilldownEvent,
|
|
XChartContainerComponent,
|
|
XChartStoryboardBeatInfo,
|
|
} from './x-chart.typings';
|
|
import { fromEvent, Subject, Subscription } from 'rxjs';
|
|
import ApexCharts from 'apexcharts';
|
|
import {
|
|
XActionBarItem,
|
|
XActionBarItemSlot,
|
|
XActionBarActionFiredModel,
|
|
} from '../x-action-bar/x-action-bar.typings';
|
|
import { XIconNames } from '../x-icon/x-icon.typings';
|
|
import { XCardAction } from '../x-card/x-card.typings';
|
|
import { debounceTime, takeUntil } from 'rxjs/operators';
|
|
import { XCardComponent } from '../x-card/x-card.component';
|
|
|
|
@Component({
|
|
selector: 'x-chart',
|
|
templateUrl: './x-chart.component.html',
|
|
styleUrls: ['./x-chart.component.scss'],
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
})
|
|
export class XChartComponent extends XChartContainerComponent {
|
|
//
|
|
//#region Props ...
|
|
//
|
|
private CHART_CONTAINER: ElementRef = undefined;
|
|
|
|
@ViewChild('chartContainer', { static: false })
|
|
set chartContainer(el: ElementRef) {
|
|
//
|
|
if (isNullOrUndefined(el)) {
|
|
//
|
|
this.destroyComponent();
|
|
return;
|
|
}
|
|
|
|
//
|
|
this.CHART_CONTAINER = el;
|
|
this.initializeComponent();
|
|
}
|
|
|
|
get chartContainer() {
|
|
return this.CHART_CONTAINER;
|
|
}
|
|
|
|
//
|
|
private CHART_CARD: ElementRef<XCardComponent> = undefined;
|
|
|
|
@ViewChild('chartCard', { static: false })
|
|
set chartCard(el: ElementRef<XCardComponent>) {
|
|
this.CHART_CARD = el;
|
|
}
|
|
|
|
get chartCard() {
|
|
return this.CHART_CARD;;
|
|
}
|
|
|
|
//
|
|
private RESIZE_SUBJECT = new Subject<Event>();
|
|
|
|
//
|
|
private CHART_OPTIONS: XChartOptions = null;
|
|
|
|
//
|
|
private chartInstance: ApexCharts = null;
|
|
|
|
//
|
|
private ACTION_PROVIDER_SUBSCRIPTION: Subscription;
|
|
|
|
//
|
|
readonly IconNames = Object.assign({}, XIconNames);
|
|
readonly ActionBarItems = Object.assign({}, XChartActionBarItem);
|
|
readonly ActionBarItemSlots = Object.assign({}, XActionBarItemSlot);
|
|
//#endregion
|
|
|
|
//
|
|
//#region LifeCycles ...
|
|
async afterViewInit() {
|
|
super.afterViewInit();
|
|
|
|
//
|
|
await this.initializeComponent();
|
|
this.registerResizeHandler();
|
|
}
|
|
|
|
async onChange(changeKeys: string[]) {
|
|
super.onChange(changeKeys);
|
|
|
|
//
|
|
let isChanged = false;
|
|
|
|
//
|
|
// Action Provider Changed ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('actionProvider'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.actionProvider)) {
|
|
this.actionProvider = this.propertyProvider.actionProvider;
|
|
}
|
|
|
|
//
|
|
this.registerActionProvider();
|
|
}
|
|
|
|
//
|
|
// Available Action Bar Items Changed ...
|
|
isChanged = changeKeys.includes(
|
|
nameof<XChartComponent>('availableActionBarItems'),
|
|
);
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.availableActionBarItems)) {
|
|
this.availableActionBarItems =
|
|
this.propertyProvider.availableActionBarItems;
|
|
}
|
|
|
|
//
|
|
await this.prepareActionBar();
|
|
}
|
|
|
|
//
|
|
// Zoom Step ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('zoomStep'));
|
|
if (isChanged) {
|
|
//
|
|
let zoomStep = await this.getValueAsync(this.zoomStep);
|
|
if (isNullOrUndefined(zoomStep) || zoomStep < 0 || zoomStep > 1) {
|
|
this.zoomStep = 0.125;
|
|
}
|
|
|
|
//
|
|
zoomStep = await this.getValueAsync(this.zoomStep);
|
|
}
|
|
|
|
//
|
|
// Chart Title ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('title'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.title)) {
|
|
this.title = this.propertyProvider.title;
|
|
}
|
|
|
|
//
|
|
this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Chart Title Align ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('titleAlign'));
|
|
if (isChanged) {
|
|
//
|
|
const align = await this.getValueAsync(this.titleAlign);
|
|
if (
|
|
isNullOrUndefined(this.titleAlign) ||
|
|
isNullOrEmptyString(align) ||
|
|
!isChartTextAlign(align)
|
|
) {
|
|
this.titleAlign = this.propertyProvider.titleAlign;
|
|
}
|
|
|
|
//
|
|
this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Chart SubTitle ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('subTitle'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.subTitle)) {
|
|
this.subTitle = this.propertyProvider.subTitle;
|
|
}
|
|
|
|
//
|
|
this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Chart Sub Title Align ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('subTitleAlign'));
|
|
if (isChanged) {
|
|
//
|
|
const align = await this.getValueAsync(this.subTitleAlign);
|
|
if (
|
|
isNullOrUndefined(this.subTitleAlign) ||
|
|
isNullOrEmptyString(align) ||
|
|
!isChartTextAlign(align)
|
|
) {
|
|
this.subTitleAlign = this.propertyProvider.subTitleAlign;
|
|
}
|
|
|
|
//
|
|
this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Foreground Color Changed ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('foregroundColor'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.foregroundColor)) {
|
|
this.foregroundColor = this.propertyProvider.foregroundColor;
|
|
}
|
|
|
|
//
|
|
await this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Background Color Changed ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('backgroundColor'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.backgroundColor)) {
|
|
this.backgroundColor = this.propertyProvider.backgroundColor;
|
|
}
|
|
|
|
//
|
|
await this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Grid Color Changed ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('gridColor'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.gridColor)) {
|
|
this.gridColor = this.propertyProvider.gridColor;
|
|
}
|
|
|
|
//
|
|
await this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Chart Title Color ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('titleColor'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.titleColor)) {
|
|
this.titleColor = this.propertyProvider.titleColor;
|
|
}
|
|
|
|
//
|
|
this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Chart SubTitle Color ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('subTitleColor'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.subTitleColor)) {
|
|
this.subTitleColor = this.propertyProvider.subTitleColor;
|
|
}
|
|
|
|
//
|
|
this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Options Changed ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('options'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.options)) {
|
|
this.options = this.propertyProvider.options;
|
|
}
|
|
|
|
//
|
|
await this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Chart Type ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('type'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.type)) {
|
|
this.type = this.propertyProvider.type;
|
|
}
|
|
|
|
//
|
|
var type = await this.getValueAsync(this.type);
|
|
if (!isChartType(type)) {
|
|
//
|
|
type = await this.getValueAsync(this.propertyProvider.type);
|
|
this.type = type;
|
|
}
|
|
|
|
//
|
|
await this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
// Series Changed ...
|
|
isChanged = changeKeys.includes(nameof<XChartComponent>('series'));
|
|
if (isChanged) {
|
|
//
|
|
if (isNullOrUndefined(this.series)) {
|
|
this.series = this.propertyProvider.series;
|
|
}
|
|
|
|
//
|
|
await this.handleChartUpdate();
|
|
}
|
|
|
|
//
|
|
this.detectChanges();
|
|
}
|
|
|
|
onDestroy() {
|
|
super.onDestroy();
|
|
|
|
//
|
|
this.RESIZE_SUBJECT.next();
|
|
this.RESIZE_SUBJECT.complete();
|
|
|
|
//
|
|
this.destroyComponent();
|
|
this.unregisterActionProvider();
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region UI Handler ...
|
|
async handleActionBarActionFired(model: XActionBarActionFiredModel) {
|
|
//
|
|
if (isNullOrUndefined(model) || isNullOrEmptyString(model.action)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
switch (model.action) {
|
|
//
|
|
// Print ...
|
|
case XChartActionBarItem.Print:
|
|
await this.handlePrint();
|
|
break;
|
|
|
|
//
|
|
// Export As CSV ...
|
|
case XChartActionBarItem.ExportAsCSV:
|
|
await this.handleExportAsCSV();
|
|
break;
|
|
|
|
//
|
|
// Export As PNG ...
|
|
case XChartActionBarItem.ExportAsPNG:
|
|
await this.handleExportAsPng();
|
|
break;
|
|
|
|
//
|
|
// Export As SVG ...
|
|
case XChartActionBarItem.ExportAsSVG:
|
|
await this.handleExportAsSVG();
|
|
break;
|
|
|
|
//
|
|
// Zoom In ...
|
|
case XChartActionBarItem.ZoomIn:
|
|
await this.handleZoomIn();
|
|
break;
|
|
|
|
//
|
|
// Zoom Out ...
|
|
case XChartActionBarItem.ZoomOut:
|
|
await this.handleZoomOut();
|
|
break;
|
|
|
|
//
|
|
// Zoom Selection ...
|
|
case XChartActionBarItem.ZoomSelection:
|
|
break;
|
|
|
|
//
|
|
// X Selection ...
|
|
case XChartActionBarItem.XSelection:
|
|
break;
|
|
|
|
//
|
|
// Y Selection ...
|
|
case XChartActionBarItem.YSelection:
|
|
break;
|
|
|
|
//
|
|
// XY Selection ...
|
|
case XChartActionBarItem.XYSelection:
|
|
break;
|
|
|
|
//
|
|
// Pan ...
|
|
case XChartActionBarItem.Pan:
|
|
await this.handlePan();
|
|
break;
|
|
|
|
//
|
|
// ResetChart ...
|
|
case XChartActionBarItem.ResetChart:
|
|
await this.handleResetChart();
|
|
break;
|
|
|
|
//
|
|
// ToggleFullScreen ...
|
|
case XChartActionBarItem.ToggleFullScreen:
|
|
await this.handleToggleFullscreen();
|
|
break;
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
this.actionBarActionFired.emit(model);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region Actions ...
|
|
/**
|
|
* Export Chart Data in Specified Format ...
|
|
*
|
|
* @param format Export Format ...
|
|
* @param fileName Provided File Name without Extension ...
|
|
*/
|
|
async export(format: 'png' | 'svg' | 'csv' = 'png', fileName: string = '') {
|
|
//
|
|
// Normalize File Name ...
|
|
if (isNullOrEmptyString(fileName)) {
|
|
fileName = generateUuid('XChart');
|
|
}
|
|
|
|
//
|
|
fileName += '.' + format;
|
|
|
|
//
|
|
switch (format) {
|
|
//
|
|
case 'png':
|
|
//
|
|
const dataObject = await this.chartInstance.dataURI();
|
|
|
|
//
|
|
if ('imgURI' in dataObject) {
|
|
downloadFileByUrl(dataObject.imgURI, fileName);
|
|
} else if ('blob' in dataObject) {
|
|
downloadArrayBufferedFile(fileName, dataObject.blob);
|
|
}
|
|
break;
|
|
|
|
//
|
|
case 'svg':
|
|
//
|
|
const svgString = this.chartInstance.exports.exportToSVG();
|
|
downloadFile(svgString, XMimeType.ImageSVG, fileName);
|
|
break;
|
|
|
|
//
|
|
case 'csv':
|
|
//
|
|
this.chartInstance.exports.exportToCSV({
|
|
fileName: fileName,
|
|
columnDelimiter: ',',
|
|
lineDelimiter: '\n',
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region Toolbar Actions ...
|
|
async handleExportAsPng() {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
await this.export('png');
|
|
}
|
|
|
|
async handleExportAsSVG() {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
await this.export('svg');
|
|
}
|
|
|
|
async handleExportAsCSV() {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
await this.export('csv');
|
|
}
|
|
|
|
async handleZoomIn() {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
var zoomStep = await this.getValueAsync(this.zoomStep);
|
|
|
|
//
|
|
const state = this.chartInstance.getState();
|
|
const minX = state.minX;
|
|
const maxX = state.maxX;
|
|
const rangeIn = maxX - minX;
|
|
|
|
//
|
|
await this.chartInstance.zoomX(
|
|
minX + rangeIn * zoomStep,
|
|
maxX - rangeIn * zoomStep,
|
|
);
|
|
}
|
|
|
|
async handleZoomOut() {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
var zoomStep = await this.getValueAsync(this.zoomStep);
|
|
|
|
//
|
|
const state = this.chartInstance.getState();
|
|
const minX = state.minX;
|
|
const maxX = state.maxX;
|
|
const rangeIn = maxX - minX;
|
|
|
|
//
|
|
await this.chartInstance.zoomX(
|
|
minX - rangeIn * zoomStep,
|
|
maxX + rangeIn * zoomStep,
|
|
);
|
|
}
|
|
|
|
async handlePan() {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
await this.chartInstance.updateOptions({
|
|
chart: {
|
|
zoom: {
|
|
enabled: false,
|
|
},
|
|
selection: {
|
|
type: 'x',
|
|
enabled: true,
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
async handleResetChart() {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
this.chartInstance.resetSeries(true, true);
|
|
}
|
|
|
|
async handlePrint() {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
try {
|
|
//
|
|
const result = await this.chartInstance.dataURI();
|
|
if ('imgURI' in result) {
|
|
//
|
|
const imgURI = result.imgURI;
|
|
const printWindow = window.open('', '_blank');
|
|
if (printWindow) {
|
|
//
|
|
// Write Data Uri on a Page for Printing ...
|
|
printWindow.document.write(`
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Print Chart</title>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
padding: 20px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
min-height: 100vh;
|
|
}
|
|
img {
|
|
max-width: 100%;
|
|
height: auto;
|
|
}
|
|
@media print {
|
|
body {
|
|
margin: 0;
|
|
}
|
|
img {
|
|
max-width: 100%;
|
|
page-break-inside: avoid;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<img src="${imgURI}" alt="Chart" />
|
|
<script>
|
|
window.onload = function() {
|
|
window.print();
|
|
window.onafterprint = function() {
|
|
window.close();
|
|
};
|
|
};
|
|
</script>
|
|
</body>
|
|
</html>
|
|
`);
|
|
|
|
//
|
|
printWindow.document.close();
|
|
}
|
|
}
|
|
} catch (error) { }
|
|
}
|
|
|
|
async handleToggleFullscreen() {
|
|
//
|
|
if (
|
|
isNullOrUndefined(this.chartInstance) ||
|
|
isNullOrUndefined(this.chartContainer) ||
|
|
isNullOrUndefined(this.chartContainer.nativeElement)
|
|
) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Handle Fullscreen Toggle using Card ...
|
|
this.cardActionProvider.next({ action: XCardAction.ToggleFullScreen });
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region Private ...
|
|
private async initializeComponent() {
|
|
//
|
|
if (isNullOrUndefined(this.CHART_CONTAINER)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Reading Requirement Properties ...
|
|
const type = await this.getValueAsync(this.type);
|
|
const chartId = await this.getValueAsync(this.uuid);
|
|
const series = await this.getValueAsync(this.series);
|
|
const cOptions = await this.getValueAsync(this.options);
|
|
|
|
//
|
|
const title = await this.getResourceValueAsync(this.title);
|
|
const titleAlignProp = await this.getValueAsync(this.titleAlign);
|
|
let titleAlign: 'left' | 'center' | 'right' = 'center';
|
|
|
|
//
|
|
const subTitle = await this.getResourceValueAsync(this.subTitle);
|
|
const subTitleAlignProp = await this.getValueAsync(this.subTitleAlign);
|
|
let subTitleAlign: 'left' | 'center' | 'right' = 'center';
|
|
|
|
//
|
|
const gridColorName = await this.getValueAsync(this.gridColor);
|
|
const gridColorValue = getXColorValue(gridColorName);
|
|
|
|
//
|
|
const titleColorName = await this.getValueAsync(this.titleColor);
|
|
const titleColorValue = getXColorValue(titleColorName);
|
|
|
|
//
|
|
const subTitleColorName = await this.getValueAsync(this.subTitleColor);
|
|
const subTitleColorValue = getXColorValue(subTitleColorName);
|
|
|
|
//
|
|
const foregroundColorName = await this.getValueAsync(this.foregroundColor);
|
|
const foregroundColorValue = getXColorValue(foregroundColorName);
|
|
|
|
//
|
|
const backgroundColorName = await this.getValueAsync(this.backgroundColor);
|
|
const backgroundColorValue = getXColorValue(backgroundColorName);
|
|
|
|
//
|
|
const primaryColorValue = getXColorValue(XColorWithBrightness.Primary);
|
|
|
|
//
|
|
// Normalize Directional Properties ....
|
|
if (this.managerService.uiDirection == 'ltr') {
|
|
//
|
|
titleAlign =
|
|
titleAlignProp == XChartTextAlign.Start
|
|
? 'left'
|
|
: titleAlignProp == XChartTextAlign.End
|
|
? 'right'
|
|
: 'center';
|
|
|
|
//
|
|
subTitleAlign =
|
|
subTitleAlignProp == XChartTextAlign.Start
|
|
? 'left'
|
|
: subTitleAlignProp == XChartTextAlign.End
|
|
? 'right'
|
|
: 'center';
|
|
} else if (this.managerService.uiDirection == 'rtl') {
|
|
//
|
|
titleAlign =
|
|
titleAlignProp == XChartTextAlign.Start
|
|
? 'right'
|
|
: titleAlignProp == XChartTextAlign.End
|
|
? 'left'
|
|
: 'center';
|
|
|
|
//
|
|
subTitleAlign =
|
|
subTitleAlignProp == XChartTextAlign.Start
|
|
? 'right'
|
|
: subTitleAlignProp == XChartTextAlign.End
|
|
? 'left'
|
|
: 'center';
|
|
}
|
|
|
|
//
|
|
this.CHART_OPTIONS = {
|
|
...cOptions,
|
|
series: series || cOptions.series,
|
|
title: {
|
|
...cOptions.title,
|
|
text: title,
|
|
align: titleAlign,
|
|
style: {
|
|
...cOptions.title?.style,
|
|
color: titleColorValue,
|
|
},
|
|
},
|
|
subtitle: {
|
|
...cOptions.subtitle,
|
|
text: subTitle,
|
|
align: subTitleAlign,
|
|
style: {
|
|
...cOptions.subtitle?.style,
|
|
color: subTitleColorValue,
|
|
},
|
|
},
|
|
chart: {
|
|
...cOptions.chart,
|
|
id: chartId,
|
|
type: type as any,
|
|
foreColor: foregroundColorValue,
|
|
background: backgroundColorValue,
|
|
toolbar: {
|
|
show: false,
|
|
autoSelected: 'pan',
|
|
},
|
|
events: {
|
|
...cOptions.chart?.events,
|
|
//
|
|
//#region Attach Events ...
|
|
//
|
|
animationEnd: (chart: ApexCharts, options?: XChartEventOpts) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.animationEnd.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.animationEnd?.(chart, options);
|
|
},
|
|
|
|
//
|
|
beforeMount: (chart: ApexCharts, options?: XChartEventOpts) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.beforeMount.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.beforeMount?.(chart, options);
|
|
},
|
|
|
|
//
|
|
mounted: (chart: ApexCharts, options?: XChartEventOpts) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.mounted.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.mounted?.(chart, options);
|
|
},
|
|
|
|
//
|
|
updated: (chart: ApexCharts, options?: XChartEventOpts) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.updated.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.updated?.(chart, options);
|
|
},
|
|
|
|
//
|
|
mouseMove: (
|
|
e: MouseEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.mouseMove.emit({ e: e, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.mouseMove?.(e, chart, options);
|
|
},
|
|
|
|
//
|
|
mouseLeave: (
|
|
e: MouseEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.mouseLeave.emit({ e: e, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.mouseLeave?.(e, chart, options);
|
|
},
|
|
|
|
//
|
|
click: (
|
|
e: MouseEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.click.emit({ e: e, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.click?.(e, chart, options);
|
|
},
|
|
|
|
//
|
|
xAxisLabelClick: (
|
|
e: MouseEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.xAxisLabelClick.emit({ e: e, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.xAxisLabelClick?.(e, chart, options);
|
|
},
|
|
|
|
//
|
|
legendClick: (
|
|
chart: ApexCharts,
|
|
seriesIndex?: number,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.legendClick.emit({
|
|
seriesIndex: seriesIndex,
|
|
options: options,
|
|
});
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.legendClick?.(chart, seriesIndex, options);
|
|
},
|
|
|
|
//
|
|
markerClick: (
|
|
e: MouseEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.markerClick.emit({ e: e, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.markerClick?.(e, chart, options);
|
|
},
|
|
|
|
//
|
|
selection: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
xaxis?: { min: number; max: number };
|
|
yaxis?: { min: number; max: number };
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.selection.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.selection?.(chart, options);
|
|
},
|
|
|
|
//
|
|
dataPointSelection: (
|
|
e: MouseEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.dataPointSelection.emit({ e: e, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.dataPointSelection?.(e, chart, options);
|
|
},
|
|
|
|
//
|
|
dataPointMouseEnter: (
|
|
e: MouseEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.dataPointMouseEnter.emit({ e: e, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.dataPointMouseEnter?.(e, chart, options);
|
|
},
|
|
|
|
//
|
|
dataPointMouseLeave: (
|
|
e: MouseEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.dataPointMouseLeave.emit({ e: e, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.dataPointMouseLeave?.(e, chart, options);
|
|
},
|
|
|
|
//
|
|
beforeZoom: (
|
|
chart: ApexCharts,
|
|
options?: { xaxis: { min: number; max: number } },
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.beforeZoom.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.beforeZoom?.(chart, options);
|
|
},
|
|
|
|
//
|
|
beforeResetZoom: (chart: ApexCharts, options?: XChartEventOpts) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.beforeResetZoom.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.beforeResetZoom?.(chart, options);
|
|
},
|
|
|
|
//
|
|
zoomed: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
xaxis: { min: number; max: number };
|
|
yaxis?: { min: number; max: number }[];
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.zoomed.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.zoomed?.(chart, options);
|
|
},
|
|
|
|
//
|
|
scrolled: (
|
|
chart: ApexCharts,
|
|
options?: { xaxis: { min: number; max: number } },
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.scrolled.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.scrolled?.(chart, options);
|
|
},
|
|
|
|
//
|
|
brushScrolled: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
xaxis: { min: number; max: number };
|
|
yaxis?: { min: number; max: number }[];
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.brushScrolled.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.brushScrolled?.(chart, options);
|
|
},
|
|
|
|
//
|
|
crossFilter: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
xaxis: { min: number; max: number };
|
|
sourceChartID?: string;
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.crossFilter.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.crossFilter?.(chart, options);
|
|
},
|
|
|
|
//
|
|
filterChange: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
filters: Record<string, any>;
|
|
filteredCount: number;
|
|
total: number;
|
|
sourceChartID?: string;
|
|
key?: any;
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.filterChange.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.filterChange?.(chart, options);
|
|
},
|
|
|
|
//
|
|
annotationDragged: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
type?: 'point' | 'xaxis' | 'yaxis';
|
|
id?: string;
|
|
index: number;
|
|
x: any;
|
|
y: any;
|
|
x2?: any;
|
|
y2?: any;
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.annotationDragged.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.annotationDragged?.(chart, options);
|
|
},
|
|
|
|
//
|
|
annotationEdited: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
type?: 'point' | 'xaxis' | 'yaxis';
|
|
id?: string;
|
|
index: number;
|
|
text: string;
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.annotationEdited.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.annotationEdited?.(chart, options);
|
|
},
|
|
|
|
//
|
|
annotationCreated: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
type?: 'point' | 'xaxis' | 'yaxis';
|
|
id?: string;
|
|
index: number;
|
|
x?: any;
|
|
y?: any;
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.annotationCreated.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.annotationCreated?.(chart, options);
|
|
},
|
|
|
|
//
|
|
annotationStyled: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
type?: 'point' | 'xaxis' | 'yaxis';
|
|
id?: string;
|
|
index: number;
|
|
label?: any;
|
|
marker?: any;
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.annotationStyled.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.annotationStyled?.(chart, options);
|
|
},
|
|
|
|
//
|
|
annotationDeleted: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
type?: 'point' | 'xaxis' | 'yaxis';
|
|
id?: string;
|
|
index: number;
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.annotationDeleted.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.annotationDeleted?.(chart, options);
|
|
},
|
|
|
|
//
|
|
measured: (
|
|
chart: ApexCharts,
|
|
options?: {
|
|
from: { x: any; y: any };
|
|
to: { x: any; y: any };
|
|
dx: number;
|
|
dy: number;
|
|
percentChange: number;
|
|
slope: number;
|
|
},
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.measured.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.measured?.(chart, options);
|
|
},
|
|
|
|
//
|
|
beatChange: (
|
|
chart: ApexCharts,
|
|
options?: XChartStoryboardBeatInfo,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.beatChange.emit(options);
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.beatChange?.(chart, options);
|
|
},
|
|
|
|
//
|
|
keyDown: (
|
|
e: KeyboardEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.keyDown.emit({ e: e, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.keyDown?.(e, chart, options);
|
|
},
|
|
|
|
//
|
|
keyUp: (
|
|
e: KeyboardEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.keyUp.emit({ e: e, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.keyUp?.(e, chart, options);
|
|
},
|
|
|
|
//
|
|
drillDownStart: (
|
|
info: XChartDrilldownEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.drillDownStart.emit({ info: info, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.drillDownStart?.(info, chart, options);
|
|
},
|
|
|
|
//
|
|
drillDownEnd: (
|
|
info: XChartDrilldownEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.drillDownEnd.emit({ info: info, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.drillDownEnd?.(info, chart, options);
|
|
},
|
|
|
|
//
|
|
drillUp: (
|
|
info: XChartDrilldownEvent,
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.drillUp.emit({ info: info, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.drillUp?.(info, chart, options);
|
|
},
|
|
|
|
//
|
|
drillDownError: (
|
|
info: { id: string | number | null; error: any },
|
|
chart?: ApexCharts,
|
|
options?: XChartEventOpts,
|
|
) => {
|
|
//
|
|
if (!this.loading && !this.uiDisabled) {
|
|
this.drillDownError.emit({ info: info, options: options });
|
|
}
|
|
|
|
//
|
|
cOptions.chart?.events?.drillDownError?.(info, chart, options);
|
|
},
|
|
//#endregion
|
|
},
|
|
},
|
|
theme: {
|
|
...cOptions.theme,
|
|
palette: cOptions.theme?.palette || 'palette1',
|
|
},
|
|
colors: cOptions.colors || [primaryColorValue],
|
|
grid: {
|
|
...cOptions.grid,
|
|
borderColor: gridColorValue,
|
|
},
|
|
dataLabels: {
|
|
...cOptions.dataLabels,
|
|
},
|
|
};
|
|
|
|
//
|
|
this.chartInstance = new ApexCharts(
|
|
this.chartContainer.nativeElement,
|
|
this.CHART_OPTIONS,
|
|
);
|
|
|
|
//
|
|
await this.prepareActionBar();
|
|
|
|
//
|
|
await this.chartInstance.render();
|
|
}
|
|
|
|
private async prepareActionBar() {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
const showActionBar = await this.getValueAsync(this.showActionBar);
|
|
if (!showActionBar) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
//#region DefaultActionBarActions ...
|
|
//
|
|
// Reset ...
|
|
const defaultResetItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
disabled: this.uiDisabled,
|
|
icon: this.IconNames.refresh,
|
|
title: this.ResourceIDs.reset,
|
|
slot: this.ActionBarItemSlots.END,
|
|
id: this.ActionBarItems.ResetChart,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// Print ...
|
|
const defaultPrintItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
disabled: this.uiDisabled,
|
|
icon: this.IconNames.print,
|
|
title: this.ResourceIDs.print,
|
|
id: this.ActionBarItems.Print,
|
|
slot: this.ActionBarItemSlots.END,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// Export As PNG ...
|
|
const defaultExportPNGItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
icon: this.IconNames.png,
|
|
disabled: this.uiDisabled,
|
|
slot: this.ActionBarItemSlots.END,
|
|
title: this.ResourceIDs.export_png,
|
|
id: this.ActionBarItems.ExportAsPNG,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// Export as SVG ...
|
|
const defaultExportSVGItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
icon: this.IconNames.image,
|
|
disabled: this.uiDisabled,
|
|
slot: this.ActionBarItemSlots.END,
|
|
title: this.ResourceIDs.export_svg,
|
|
id: this.ActionBarItems.ExportAsSVG,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// Export as CSV ...
|
|
const defaultExportCSVItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
icon: this.IconNames.csv,
|
|
disabled: this.uiDisabled,
|
|
slot: this.ActionBarItemSlots.END,
|
|
title: this.ResourceIDs.export_csv,
|
|
id: this.ActionBarItems.ExportAsCSV,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// Zoom In ...
|
|
const defaultZoomInItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
disabled: this.uiDisabled,
|
|
icon: this.IconNames.zoom_in,
|
|
id: this.ActionBarItems.ZoomIn,
|
|
title: this.ResourceIDs.zoom_in,
|
|
slot: this.ActionBarItemSlots.START,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// Zoom Out ...
|
|
const defaultZoomOutItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
disabled: this.uiDisabled,
|
|
icon: this.IconNames.zoom_out,
|
|
id: this.ActionBarItems.ZoomOut,
|
|
title: this.ResourceIDs.zoom_out,
|
|
slot: this.ActionBarItemSlots.START,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// Zoom Selection ...
|
|
const defaultZoomSelectionItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
disabled: this.uiDisabled,
|
|
slot: this.ActionBarItemSlots.START,
|
|
icon: this.IconNames.range_selection,
|
|
id: this.ActionBarItems.ZoomSelection,
|
|
title: this.ResourceIDs.zoom_selection,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// X Axis Selection ...
|
|
const defaultXAxisSelectionItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
disabled: this.uiDisabled,
|
|
icon: this.IconNames.x_axis,
|
|
title: this.ResourceIDs.x_axis,
|
|
id: this.ActionBarItems.XSelection,
|
|
slot: this.ActionBarItemSlots.START,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// Y Axis Selection ...
|
|
const defaultYAxisSelectionItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
disabled: this.uiDisabled,
|
|
icon: this.IconNames.y_axis,
|
|
title: this.ResourceIDs.y_axis,
|
|
id: this.ActionBarItems.YSelection,
|
|
slot: this.ActionBarItemSlots.START,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// XY Axis Selection ...
|
|
const defaultXYAxisSelectionItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
disabled: this.uiDisabled,
|
|
icon: this.IconNames.xy_axis,
|
|
title: this.ResourceIDs.xy_axis,
|
|
id: this.ActionBarItems.XYSelection,
|
|
slot: this.ActionBarItemSlots.START,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// Pan ...
|
|
const defaultPanItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
disabled: this.uiDisabled,
|
|
icon: this.IconNames.touch,
|
|
title: this.ResourceIDs.pan,
|
|
id: this.ActionBarItems.Pan,
|
|
slot: this.ActionBarItemSlots.START,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
|
|
//
|
|
// Toggle Full Screen ...
|
|
const defaultFullscreenItem: XActionBarItem = {
|
|
onlyIcon: true,
|
|
disabled: this.uiDisabled,
|
|
icon: this.IconNames.fullscreen,
|
|
title: this.ResourceIDs.full_screen,
|
|
slot: this.ActionBarItemSlots.START,
|
|
id: this.ActionBarItems.ToggleFullScreen,
|
|
iconColor: this.defaultActionBarItemColor,
|
|
};
|
|
//#endregion
|
|
|
|
//
|
|
this.actionBarActions = [];
|
|
this.detectChanges();
|
|
|
|
//
|
|
const availableItems = await this.getArrayValueAsync(
|
|
this.availableActionBarItems,
|
|
);
|
|
if (!this.hasChild(availableItems)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
let hasItem = false;
|
|
const actionBarItems: XActionBarItem[] = [];
|
|
|
|
//
|
|
//#region Print ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.Print);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.Print,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultPrintItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region ExportAsPNG ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.ExportAsPNG);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.ExportAsPNG,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultExportPNGItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region ExportAsSVG ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.ExportAsSVG);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.ExportAsSVG,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultExportSVGItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region ExportAsCSV ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.ExportAsCSV);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.ExportAsCSV,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultExportCSVItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region ZoomIn ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.ZoomIn);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.ZoomIn,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultZoomInItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region ZoomOut ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.ZoomOut);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.ZoomOut,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultZoomOutItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region ZoomSelection ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.ZoomSelection);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.ZoomSelection,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultZoomSelectionItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region XSelection ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.XSelection);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.XSelection,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultXAxisSelectionItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region YSelection ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.YSelection);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.YSelection,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultYAxisSelectionItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region XYSelection ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.XYSelection);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.XYSelection,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultXYAxisSelectionItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region Pan ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.Pan);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.Pan,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultPanItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region Reset ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.ResetChart);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.ResetChart,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultResetItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region FullScreen ...
|
|
hasItem = availableItems
|
|
.map((ai) => ai.actionId)
|
|
.includes(this.ActionBarItems.ToggleFullScreen);
|
|
|
|
//
|
|
if (hasItem) {
|
|
//
|
|
const selectedItem = availableItems.find(
|
|
(ai) => ai.actionId === this.ActionBarItems.ToggleFullScreen,
|
|
);
|
|
const providedItem = selectedItem.descriptor;
|
|
let item = {
|
|
...defaultFullscreenItem,
|
|
};
|
|
if (!isNullOrUndefined(providedItem)) {
|
|
item = {
|
|
...item,
|
|
...providedItem,
|
|
};
|
|
}
|
|
|
|
//
|
|
item = {
|
|
...item,
|
|
disabled: this.uiDisabled,
|
|
};
|
|
|
|
//
|
|
actionBarItems.push(item);
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
this.actionBarActions = [...actionBarItems];
|
|
this.detectChanges();
|
|
}
|
|
|
|
private async handleChartUpdate() {
|
|
//
|
|
if (
|
|
isNullOrUndefined(this.chartInstance) ||
|
|
isNullOrUndefined(this.CHART_OPTIONS) ||
|
|
isNullOrUndefined(this.chartContainer) ||
|
|
isNullOrUndefined(this.chartContainer.nativeElement)
|
|
) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Reading Requirement Properties ...
|
|
const type = await this.getValueAsync(this.type);
|
|
const series = await this.getValueAsync(this.series);
|
|
|
|
//
|
|
const options = await this.getValueAsync(this.options);
|
|
this.CHART_OPTIONS = {
|
|
...options,
|
|
...this.CHART_OPTIONS,
|
|
chart: {
|
|
...this.CHART_OPTIONS.chart,
|
|
type: type as any,
|
|
},
|
|
};
|
|
|
|
//
|
|
await this.chartInstance.updateOptions(this.CHART_OPTIONS);
|
|
await this.chartInstance.updateSeries(series);
|
|
}
|
|
|
|
private destroyComponent() {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
this.chartInstance.destroy();
|
|
this.chartInstance = null;
|
|
}
|
|
|
|
private registerResizeHandler() {
|
|
//
|
|
fromEvent(window, 'resize')
|
|
.pipe(
|
|
debounceTime(200),
|
|
takeUntil(this.RESIZE_SUBJECT)
|
|
)
|
|
.subscribe(() => {
|
|
//
|
|
if (isNullOrUndefined(this.chartInstance) || isNullOrUndefined(this.chartCard) || isNullOrUndefined(this.chartCard.nativeElement) || !this.chartCard.nativeElement.isFullscreen) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
var height = this.chartCard.nativeElement.calculateContentSize();
|
|
|
|
//
|
|
// Reading Height ...
|
|
this.CHART_OPTIONS = {
|
|
...this.CHART_OPTIONS,
|
|
chart: {
|
|
height: `${height}px`
|
|
}
|
|
};
|
|
|
|
//
|
|
// TODO:
|
|
// Only Apply when Full Screen Mode ...
|
|
// Add FullScreen Event Handler in XCard Component ...
|
|
console.log('chart resize: ', height);
|
|
|
|
//
|
|
this.chartInstance.updateOptions(this.CHART_OPTIONS, false, false);
|
|
});
|
|
}
|
|
|
|
private registerActionProvider() {
|
|
//
|
|
this.unregisterActionProvider();
|
|
|
|
//
|
|
if (!this.actionProvider) {
|
|
this.actionProvider = this.propertyProvider.actionProvider;
|
|
}
|
|
|
|
//
|
|
this.ACTION_PROVIDER_SUBSCRIPTION = this.actionProvider
|
|
.asObservable()
|
|
.subscribe(async (model) => {
|
|
//
|
|
switch (model.action) {
|
|
//
|
|
case XChartAction.Refresh:
|
|
this.detectChanges();
|
|
break;
|
|
|
|
//
|
|
case XChartAction.Destroy:
|
|
this.onDestroy();
|
|
break;
|
|
|
|
//
|
|
case XChartAction.UpdateSeries:
|
|
//
|
|
if (
|
|
!isNullOrUndefined(model.payload) ||
|
|
!isNullOrUndefined(this.chartInstance)
|
|
) {
|
|
//
|
|
this.series = await this.getValueAsync(
|
|
model.payload as XChartSeriesType,
|
|
);
|
|
await this.chartInstance.updateSeries(this.series);
|
|
this.detectChanges();
|
|
}
|
|
break;
|
|
|
|
//
|
|
case XChartAction.UpdateOptions:
|
|
//
|
|
if (
|
|
!isNullOrUndefined(model.payload) ||
|
|
!isNullOrUndefined(this.chartInstance)
|
|
) {
|
|
//
|
|
this.options = await this.getValueAsync(
|
|
model.payload as XChartOptions,
|
|
);
|
|
await this.chartInstance.updateOptions(this.options);
|
|
this.detectChanges();
|
|
}
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
private unregisterActionProvider() {
|
|
//
|
|
if (!this.ACTION_PROVIDER_SUBSCRIPTION) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
this.ACTION_PROVIDER_SUBSCRIPTION.unsubscribe();
|
|
this.ACTION_PROVIDER_SUBSCRIPTION = null;
|
|
}
|
|
//#endregion
|
|
}
|