@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
236 lines • 11.1 kB
JavaScript
"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.StatusBarChartComponent = 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 timeseries_helpers_1 = require("../../timeseries-helpers");
const timeseries_scales_service_1 = require("../../timeseries-scales.service");
const types_3 = require("../../types");
const timeseries_chart_component_1 = require("../timeseries-chart.component");
let StatusBarChartComponent = class StatusBarChartComponent extends timeseries_chart_component_1.TimeseriesChartComponent {
static { this.lateLoadKey = "StatusChartComponent"; }
constructor(iconService, dataSource, timeseriesScalesService, changeDetector, eventBus) {
super(eventBus, timeseriesScalesService, dataSource);
this.iconService = iconService;
this.timeseriesScalesService = timeseriesScalesService;
this.changeDetector = changeDetector;
this.eventBus = eventBus;
this.collectionId = (0, bits_1.uuid)("timeseries-status-charts");
this.chartUpdate$ = new rxjs_1.Subject();
this.timeseriesChartTypes = types_3.TimeseriesChartTypes;
this.summaryLegendBcgColor = timeseries_helpers_1.SUMMARY_LEGEND_BCG_COLOR;
this.summaryLegendColor = timeseries_helpers_1.SUMMARY_LEGEND_COLOR;
}
ngOnInit() { }
getDataPointData(series, key) {
const data = this.chartAssist.highlightedDataPoints[series.id]?.data;
if (data) {
return data[key];
}
return series.data.length > 0
? series.data[series.data.length - 1][key]
: undefined;
}
buildChart() {
this.buildChart$.next();
this.chartAssist = new charts_1.SparkChartAssist();
this.accessors = (0, charts_1.statusAccessors)(this.chartAssist.palette.standardColors);
this.accessors.data.color = (d, i, series, dataSeries) => typeof d.color === "undefined"
? "var(--nui-color-semantic-unknown)"
: d.color;
this.accessors.data.thickness = (data) => typeof data.thick === "undefined" || data.thick
? charts_1.BarRenderer.THICK
: charts_1.BarRenderer.THIN;
const iconSize = 8;
this.accessors.data.marker = (data) => data.icon
? this.iconService.getIconResized(this.iconService.getIconData(data.icon).code, iconSize)
: undefined;
this.accessors.data.y = (d) => d.value;
// disable pointer events on bars to ensure the zoom drag target is the mouse interactive area rather than the bars
this.renderer = new charts_1.BarRenderer({
highlightStrategy: this.configuration?.projectType ===
types_3.TimeseriesWidgetProjectType.PerfstackApp
? new charts_1.BarHighlightStrategyOutline("x")
: new charts_1.BarHighlightStrategy("x"),
pointerEvents: false,
});
this.setGridConfigFromConfiguration(this.chartAssist.gridConfig);
this.setGridConfigFromConfiguration(this.chartAssist.lastGridConfig);
this.scales.y = new charts_1.BandScale();
this.scales.y.fixDomain(charts_1.StatusAccessors.STATUS_DOMAIN);
this.scales.y.isTimeseriesScale = true;
if (this.scales.yRight) {
this.scales.yRight = this.scales.y;
}
}
updateChartData() {
const { gridConfig, lastGridConfig } = this.chartAssist;
// hides botom axis if it's not last chart in the group
gridConfig.axis.bottom.visible = !this.configuration?.hasAdjacentChart;
lastGridConfig.axis.bottom.visible =
!this.configuration?.hasAdjacentChart;
gridConfig.borders.bottom.className = this.configuration
?.hasAdjacentChart
? "nui-chart-border"
: "nui-chart-border nui-chart-border--thick";
lastGridConfig.borders.bottom.className = this.configuration
?.hasAdjacentChart
? "nui-chart-border"
: "nui-chart-border nui-chart-border--thick";
this.chartUpdate$.next();
// Assemble the series set
let series = this.widgetData.series;
const summarySerie = this.widgetData.summarySerie
? [this.widgetData.summarySerie]
: [];
if (series.length === 1 &&
series[0].id === this.widgetData.summarySerie?.id) {
// if the series contains only one item and its the same as the summary serie,
// there is no submetric and only the summary serie should be displayed
series = [];
}
const seriesSet = [
...summarySerie,
...series,
].map((d) => ({
...d,
data: this.transformData(d.data, this.scales.x instanceof charts_1.TimeIntervalScale),
accessors: this.accessors,
renderer: this.renderer,
scales: this.scales,
}));
// Update the chart
this.chartAssist.update(seriesSet);
if (this.configuration.enableZoom) {
this.chartAssist.sparks.forEach((spark, i) => {
if (this.configuration?.projectType ===
types_3.TimeseriesWidgetProjectType.PerfstackApp) {
if (!spark?.chart?.hasPlugin(charts_1.TimeseriesZoomPlugin)) {
spark?.chart?.addPlugin(this.zoomPlugins[i]);
}
}
else {
if (!spark?.chart?.hasPlugin(charts_1.ZoomPlugin)) {
spark?.chart?.addPlugin(new charts_1.ZoomPlugin({ enableExternalEvents: true }));
}
}
});
// only need to subscribe to one chart's SET_DOMAIN_EVENT
this.chartAssist.sparks[0].chart
?.getEventBus()
.getStream(charts_1.SET_DOMAIN_EVENT)
.pipe((0, operators_1.takeUntil)(
// eslint-disable-next-line import/no-deprecated
(0, rxjs_1.merge)(this.chartUpdate$, this.chartAssist.sparks[0].chart?.eventBus.getStream(charts_1.DESTROY_EVENT), 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,
},
});
});
}
}
/**
* Transforms standard timeseries x/y data so that it can be understood by a status chart
*
* @param data The data to transform
* @param isIntervalProgression Whether the data should be treated as continuous or occurring at a regular interval
*
* @returns The transformed data
*/
transformData(data, isIntervalProgression) {
const statusDataArray = [];
data.forEach((d, i) => {
if (isIntervalProgression || data.length - 1 !== i) {
statusDataArray.push({
start: d.x,
end: isIntervalProgression ? d.x : data[i + 1].x,
status: d.y,
color: d.color,
thick: d.thick,
icon: d.icon,
value: d.y,
});
}
});
return statusDataArray;
}
setGridConfigFromConfiguration(gridConfig) {
const configuration = this.configuration;
if (configuration.gridConfig?.xAxisTicksCount) {
gridConfig.axis.bottom.approximateTicks =
configuration.gridConfig.xAxisTicksCount;
}
if (gridConfig.dimension.marginLocked &&
configuration.gridConfig?.sideMarginLocked) {
gridConfig.dimension.marginLocked.left = true;
gridConfig.dimension.marginLocked.right = true;
}
if (configuration.gridConfig?.sideMargin) {
gridConfig.dimension.margin.left =
configuration.gridConfig.sideMargin;
gridConfig.dimension.margin.right =
configuration.gridConfig.sideMargin;
}
}
displayDeleteButton() {
return (!!this.configuration.allowLegendMenu &&
this.configuration.projectType ===
types_3.TimeseriesWidgetProjectType.PerfstackApp);
}
isStatusChart() {
return this.configuration?.type !== types_3.TimeseriesChartTypes.alert;
}
getDescriptionSecondary(series, index) {
if (this.isStatusChart()) {
return series.legendDescriptionSecondary;
}
return index === 0 ? series.legendDescriptionSecondary : "";
}
};
exports.StatusBarChartComponent = StatusBarChartComponent;
exports.StatusBarChartComponent = StatusBarChartComponent = tslib_1.__decorate([
(0, core_1.Component)({
selector: "nui-status-bar-chart",
templateUrl: "./status-bar-chart.component.html",
styleUrls: ["./status-bar-chart.component.less"],
}),
tslib_1.__param(1, (0, core_1.Optional)()),
tslib_1.__param(1, (0, core_1.Inject)(types_2.DATA_SOURCE)),
tslib_1.__param(4, (0, core_1.Inject)(types_2.PIZZAGNA_EVENT_BUS)),
tslib_1.__metadata("design:paramtypes", [bits_1.IconService, Object, timeseries_scales_service_1.TimeseriesScalesService,
core_1.ChangeDetectorRef,
bits_1.EventBus])
], StatusBarChartComponent);
//# sourceMappingURL=status-bar-chart.component.js.map