UNPKG

@nova-ui/dashboards

Version:

Nova Dashboards is a framework designed to provide feature developers with a common solution for presenting data coming from various sources within a single view, as well as a set of predefined widget visualizations that are 100% configuration-driven and

344 lines 14.7 kB
"use strict"; // © 2022 SolarWinds Worldwide, LLC. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. Object.defineProperty(exports, "__esModule", { value: true }); exports.XYChartComponent = void 0; const tslib_1 = require("tslib"); const core_1 = require("@angular/core"); // eslint-disable-next-line import/no-deprecated const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const bits_1 = require("@nova-ui/bits"); const charts_1 = require("@nova-ui/charts"); const types_1 = require("../../../../services/types"); const types_2 = require("../../../../types"); const legend_1 = require("../../../../widget-types/common/widget/legend"); const timeseries_helpers_1 = require("../../timeseries-helpers"); const timeseries_scales_service_1 = require("../../timeseries-scales.service"); const public_api_1 = require("../../transformer/public-api"); const types_3 = require("../../types"); const timeseries_chart_component_1 = require("../timeseries-chart.component"); let XYChartComponent = class XYChartComponent extends timeseries_chart_component_1.TimeseriesChartComponent { constructor(eventBus, dataSource, timeseriesScalesService, changeDetector) { super(eventBus, timeseriesScalesService, dataSource); this.eventBus = eventBus; this.timeseriesScalesService = timeseriesScalesService; this.changeDetector = changeDetector; this.valueAccessorKey = "y"; this.collectionId = ""; this.timeseriesChartTypes = types_3.TimeseriesChartTypes; this.summaryLegendBcgColor = timeseries_helpers_1.SUMMARY_LEGEND_BCG_COLOR; this.summaryLegendColor = timeseries_helpers_1.SUMMARY_LEGEND_COLOR; this.transformers = new Map([ [ types_3.TimeseriesTransformer.None, { displayName: $localize `None`, transformer: undefined }, ], [ types_3.TimeseriesTransformer.ChangePoint, { displayName: $localize `Change Point`, transformer: public_api_1.transformChangePoint, }, ], [ types_3.TimeseriesTransformer.Difference, { displayName: $localize `Difference`, transformer: public_api_1.transformDifference, }, ], [ types_3.TimeseriesTransformer.FloatingAverage, { displayName: $localize `Floating Average`, transformer: public_api_1.transformFloatingAverage, }, ], [ types_3.TimeseriesTransformer.Linear, { displayName: $localize `Linear`, transformer: public_api_1.transformLinReg }, ], [ types_3.TimeseriesTransformer.Normalize, { displayName: $localize `Normalize`, transformer: public_api_1.transformNormalize, }, ], [ types_3.TimeseriesTransformer.PercentileStd, { displayName: $localize `Percentile Standardized`, transformer: public_api_1.transformPercentileStd, }, ], [ types_3.TimeseriesTransformer.Smoothing, { displayName: $localize `Smoothing`, transformer: public_api_1.transformLoessSmoothing, }, ], [ types_3.TimeseriesTransformer.LoessStandardize, { displayName: $localize `Smoothing Standardized`, transformer: public_api_1.transformLoessStandardize, }, ], [ types_3.TimeseriesTransformer.Standardize, { displayName: $localize `Standardize`, transformer: public_api_1.transformStandardize, }, ], ]); } mapSeriesSet(data, scales) { const yScales = [scales.y]; if (scales.yRight) { yScales.push(scales.yRight); } const dataMapped = data.map((series) => { // matches scale units to the metric unit for either left y-axis scale or right y-axis scale let yScale = yScales.find((yScale) => yScale.scaleUnits === series.metricUnits); if (!yScale) { yScale = yScales.find((yScale) => yScale.scaleUnits === "generic") ?? scales.y; } return { ...series, scales: { x: scales.x, y: yScale, }, renderer: this.renderer, accessors: this.accessors, }; }); if (this.widgetData.summarySerie) { this.summarySerie = { ...this.widgetData.summarySerie, accessors: new charts_1.XYAccessors(), renderer: new charts_1.XYRenderer({ ignoreForDomainCalculation: true, }), scales: { x: scales.x, y: scales.y, }, showInLegend: false, preprocess: false, }; dataMapped.push(this.summarySerie); } return dataMapped; } /** Checks if legend should be shown. */ hasLegend() { return (this.configuration.legendPlacement && this.configuration.legendPlacement !== legend_1.LegendPlacement.None); } /** Checks if legend should be aligned to right. */ legendShouldBeAlignedRight() { return this.configuration.legendPlacement === legend_1.LegendPlacement.Right; } onPrimaryDescClick(event, legendSeries) { if (!this.seriesInteractive) { return; } event.stopPropagation(); this.eventBus.getStream(types_1.INTERACTION).next({ payload: { data: legendSeries, interactionType: types_3.TimeseriesInteractionType.Series, }, }); } /** Updates chart data. */ updateChartData() { const grid = this.chartAssist.chart.getGrid(); if (this.scales.y?.id) { grid.leftScaleId = this.scales.y.id; } if ((this.scales.yRight && this.widgetData.series.length === 1) || (this.scales.y && this.scales.yRight && this.scales.y.scaleUnits === this.scales.yRight.scaleUnits)) { // if there is only one series to display, or if the left y-axis and right y-axis have the same units, both y-axises are same this.scales.yRight = this.scales.y; grid.rightScaleId = this.scales.y.id; } else { if (this.scales.yRight?.id) { grid.rightScaleId = this.scales.yRight.id; } } const gridConfig = grid.config(); // hides botom axis if it's not last chart in the group gridConfig.axis.bottom.visible = !this.configuration?.hasAdjacentChart; gridConfig.borders.bottom.visible = !this.configuration?.hasAdjacentChart; this.chartAssist.update(this.mapSeriesSet(this.widgetData.series, this.scales)); } /** * Initialize chart */ buildChart() { this.buildChart$.next(); const colorProvider = this.configuration.chartColors && this.configuration.chartColors?.length > 0 ? new charts_1.SequentialColorProvider(this.configuration.chartColors) : (0, charts_1.defaultColorProvider)(); const palette = new charts_1.ChartPalette(colorProvider); this.accessors = this.createAccessors(palette.standardColors); this.chartAssist = this.createChartAssist(palette); const chart = this.chartAssist.chart; const gridConfig = chart.getGrid().config(); if (this.configuration.gridConfig?.xAxisTicksCount) { gridConfig.axis.bottom.approximateTicks = this.configuration.gridConfig.xAxisTicksCount; } if (gridConfig.dimension.marginLocked && this.configuration.gridConfig?.sideMarginLocked) { gridConfig.dimension.marginLocked.left = true; gridConfig.dimension.marginLocked.right = true; } if (this.configuration.gridConfig?.sideMargin) { gridConfig.dimension.margin.left = this.configuration.gridConfig.sideMargin; gridConfig.dimension.margin.right = this.configuration.gridConfig.sideMargin; } if (this.configuration.enableZoom && this.zoomPlugins.length) { chart.addPlugin(this.zoomPlugins[0]); } chart .getEventBus() .getStream(charts_1.SET_DOMAIN_EVENT) // eslint-disable-next-line import/no-deprecated .pipe((0, operators_1.takeUntil)((0, rxjs_1.merge)(this.destroy$, this.buildChart$))) .subscribe((event) => { const payload = event.data; const newDomain = payload[Object.keys(payload)[0]]; this.eventBus.getStream(types_1.SET_TIMEFRAME).next({ payload: { startDatetime: newDomain[0], endDatetime: newDomain[1], selectedPresetId: undefined, }, }); }); this.setupInteraction(); } /** * Subscribe to chart events and emit */ setupInteraction() { // interaction with chart data points this.chartAssist.chart .getEventBus() .getStream(charts_1.INTERACTION_DATA_POINTS_EVENT) // eslint-disable-next-line import/no-deprecated .pipe((0, operators_1.takeUntil)((0, rxjs_1.merge)(this.destroy$, this.buildChart$))) .subscribe((values) => { const payload = values.data; if (payload.interactionType === charts_1.InteractionType.Click) { this.eventBus.getStream(types_1.INTERACTION).next({ payload: { data: payload.dataPoints, interactionType: types_3.TimeseriesInteractionType.DataPoints, }, }); } }); // interaction with values this.chartAssist.chart .getEventBus() .getStream(charts_1.INTERACTION_VALUES_EVENT) // eslint-disable-next-line import/no-deprecated .pipe((0, operators_1.takeUntil)((0, rxjs_1.merge)(this.destroy$, this.buildChart$))) .subscribe((values) => { const payload = values.data; if (payload.interactionType === charts_1.InteractionType.Click) { this.eventBus.getStream(types_1.INTERACTION).next({ payload: { data: payload.values, interactionType: types_3.TimeseriesInteractionType.Values, }, }); } }); } displayLegendMenu() { return (this.configuration.preset === types_3.TimeseriesChartPreset.Line && !!this.configuration.allowLegendMenu && this.configuration.projectType === types_3.TimeseriesWidgetProjectType.PerfstackApp); } displayDeleteButton() { return (this.configuration.preset !== types_3.TimeseriesChartPreset.Line && !!this.configuration.allowLegendMenu && this.configuration.projectType === types_3.TimeseriesWidgetProjectType.PerfstackApp); } transformData(metricId, trId) { const serie = this.widgetData.series.find((s) => s.id === metricId); if (!serie) { return; } serie.transformer = this.transformers.get(trId)?.transformer; if (serie.rawData) { if (serie.transformer === undefined) { // revert transformed data serie.data = serie.rawData; this.updateYAxisDomain(); } else { this.transformSeriesData(serie); } } this.updateChartData(); } getLegendValue(legendSeries, valueAccessorKey) { const val = this.chartAssist.getHighlightedValue(legendSeries, "y", "tick", valueAccessorKey); if (this.configuration.projectType === types_3.TimeseriesWidgetProjectType.PerfstackApp && this.configuration.preset === types_3.TimeseriesChartPreset.StackedArea && this.configuration.units === "percent") { const submetricsCount = this.chartAssist.legendSeriesSet.length; const strVal = `${val ?? 0}`; return `${parseFloat(strVal ?? "0") * submetricsCount} %`; } return val; } }; exports.XYChartComponent = XYChartComponent; exports.XYChartComponent = XYChartComponent = tslib_1.__decorate([ (0, core_1.Injectable)(), tslib_1.__param(0, (0, core_1.Inject)(types_2.PIZZAGNA_EVENT_BUS)), tslib_1.__param(1, (0, core_1.Optional)()), tslib_1.__param(1, (0, core_1.Inject)(types_2.DATA_SOURCE)), tslib_1.__metadata("design:paramtypes", [bits_1.EventBus, Object, timeseries_scales_service_1.TimeseriesScalesService, core_1.ChangeDetectorRef]) ], XYChartComponent); //# sourceMappingURL=xy-chart.component.js.map