ui5_easy_use
Version:
CLI tool for SAP ui5 and SAPUI5 projects to initialize apps, generate pages, insert form and table components, manage routing, and automate i18n bindings
295 lines (253 loc) • 12.6 kB
JavaScript
sap.ui.define(
[
"${ez5.appName}/${ez5.packgName}/components/chart/ChartDataHandler",
"${ez5.appName}/${ez5.packgName}/api/DummyBackend",
"sap/ui/model/json/JSONModel",
],
function (ChartDataHandler, DummyBackend, JSONModel) {
"use strict";
return BaseController.extend("${ez5.appName}.controller.${ez5.controllerName}", {
onInit: function () {
this.initialChart();
},
initialChart: async function () {
this._initializeChartIds();
this._initializeChartServices();
this.chartSettings = this._normalizeChartSettings(this.getChartSettings());
this.currentChartType = this.chartSettings.chartType;
this._subscribeDummyBackendChanges();
await this.setChartData();
},
// Edit this config to reuse the generated chart for another dimension, measure, or aggregation.
getChartSettings: function () {
return {
chartType: "column",
dataSource: { type: "dummyBackend" },
dimensionKey: "Country",
dimensionLabel: "Country",
measureKey: "Employees",
measureLabel: "Employees",
aggregation: "count",
title: "Employees by Country",
containerTitle: "Employee Chart",
height: "420px",
width: "100%",
sortBy: "dimension",
sortDirection: "asc",
limit: 0,
chartTypes: [
{ key: "column", text: "Column" },
{ key: "bar", text: "Bar" },
{ key: "line", text: "Line" }
]
};
},
_initializeChartIds: function () {
this.chartContainerId = "${ez5.controllerName}ChartContainerId";
this.chartModel = "${ez5.controllerName}ChartModel";
},
_initializeChartServices: function () {
this.chartHandler = new ChartDataHandler(this.getView());
this.dummyBackend = this.dummyBackend || new DummyBackend();
this.dummyBackendChannel = "ez5DummyBackend";
this.dummyBackendChangedEvent = "changed";
},
renderEmployeeChart: function () {
this.renderConfiguredChart();
},
renderConfiguredChart: function () {
this._renderChart(this.currentChartType || this.chartSettings.chartType);
},
_renderChart: function (chartType) {
const container = this.getView().byId(this.chartContainerId);
if (!container) {
return;
}
this.currentChartType = chartType || this.chartSettings.chartType;
container.removeAllItems();
this.chartHandler.renderChart(
this.chartContainerId,
this._getChartConfig(this.currentChartType),
this._getChartSelectorConfig(this.currentChartType)
);
},
_rerenderChartByType: function (chartType) {
this._renderChart(chartType || this.chartSettings.chartType);
},
setChartData: async function () {
const records = await this._loadChartRecords(this.chartSettings);
this.chartData = this._buildChartData(records, this.chartSettings);
this.getView().setModel(new JSONModel(this.chartData), this.chartModel);
this.renderEmployeeChart();
},
_loadChartRecords: async function (chartSettings) {
const dataSource = chartSettings.dataSource || { type: "dummyBackend" };
if (Array.isArray(dataSource.data)) {
return dataSource.data;
}
if (typeof dataSource.load === "function") {
return await dataSource.load.call(this);
}
return await this.dummyBackend.list();
},
_buildChartData: function (records, chartSettings) {
const groups = this._groupChartRecords(records, chartSettings);
const chartData = Object.keys(groups).map(function (dimensionValue) {
const group = groups[dimensionValue];
return {
[chartSettings.dimensionKey]: dimensionValue,
[chartSettings.measureKey]: this._resolveAggregatedChartValue(group, chartSettings.aggregation)
};
}, this);
return this._sortAndLimitChartData(chartData, chartSettings);
},
_groupChartRecords: function (records, chartSettings) {
return (records || []).reduce(function (groups, record) {
const dimensionValue = record[chartSettings.dimensionKey] || "Unknown";
const measureValue = this._resolveChartMeasureValue(record, chartSettings);
const group = groups[dimensionValue] || this._createChartGroup(dimensionValue);
group.count += 1;
group.total += measureValue;
group.min = group.min === null ? measureValue : Math.min(group.min, measureValue);
group.max = group.max === null ? measureValue : Math.max(group.max, measureValue);
groups[dimensionValue] = group;
return groups;
}.bind(this), {});
},
_createChartGroup: function (dimensionValue) {
return {
dimensionValue: dimensionValue,
count: 0,
total: 0,
min: null,
max: null
};
},
_resolveChartMeasureValue: function (record, chartSettings) {
if (chartSettings.aggregation === "count") {
return 1;
}
const sourceKey = chartSettings.measureSourceKey || chartSettings.measureKey;
const value = Number(record[sourceKey]);
return Number.isFinite(value) ? value : 0;
},
_resolveAggregatedChartValue: function (group, aggregation) {
switch (aggregation) {
case "sum":
return group.total;
case "avg":
return group.count ? group.total / group.count : 0;
case "min":
return group.min || 0;
case "max":
return group.max || 0;
case "count":
default:
return group.count;
}
},
_sortAndLimitChartData: function (chartData, chartSettings) {
const sortedData = this._sortChartData(chartData, chartSettings);
return chartSettings.limit > 0 ? sortedData.slice(0, chartSettings.limit) : sortedData;
},
_sortChartData: function (chartData, chartSettings) {
const sortDirection = chartSettings.sortDirection === "desc" ? -1 : 1;
const dimensionKey = chartSettings.dimensionKey;
const measureKey = chartSettings.measureKey;
if (chartSettings.sortBy === "dimension") {
return chartData.sort(function (a, b) {
return String(a[dimensionKey]).localeCompare(String(b[dimensionKey])) * sortDirection;
});
}
if (chartSettings.sortBy === "measure") {
return chartData.sort(function (a, b) {
return (Number(a[measureKey]) - Number(b[measureKey])) * sortDirection;
});
}
return chartData;
},
_getChartConfig: function (chartType) {
const chartSettings = this.chartSettings;
return {
chartType: chartType || chartSettings.chartType,
dataset: { path: `${this.chartModel}>/` },
dimensions: [{ name: chartSettings.dimensionLabel, value: `${this.chartModel}>${chartSettings.dimensionKey}` }],
measures: [{ name: chartSettings.measureLabel, value: `${this.chartModel}>${chartSettings.measureKey}` }],
title: chartSettings.title,
containerTitle: chartSettings.containerTitle,
height: chartSettings.height,
width: chartSettings.width,
vizProperties: chartSettings.vizProperties
};
},
_getChartSelectorConfig: function (selectedKey) {
return {
labelText: "Chart Type",
items: this.chartSettings.chartTypes,
selectedKey: selectedKey || this.chartSettings.chartType,
changeHandler: function (oEvent) {
const selectedItem = oEvent.getParameter("selectedItem");
const chartType = selectedItem?.getKey?.() || oEvent.getSource().getSelectedKey();
this._rerenderChartByType(chartType);
}.bind(this)
};
},
_normalizeChartSettings: function (settings) {
const chartSettings = settings || {};
return {
chartType: chartSettings.chartType || "column",
dataSource: chartSettings.dataSource || { type: "dummyBackend" },
dimensionKey: chartSettings.dimensionKey || "Country",
dimensionLabel: chartSettings.dimensionLabel || chartSettings.dimensionKey || "Country",
measureKey: chartSettings.measureKey || "Employees",
measureLabel: chartSettings.measureLabel || chartSettings.measureKey || "Employees",
measureSourceKey: chartSettings.measureSourceKey,
aggregation: chartSettings.aggregation || "count",
title: chartSettings.title || "Employees by Country",
containerTitle: chartSettings.containerTitle || "Employee Chart",
height: chartSettings.height || "420px",
width: chartSettings.width || "100%",
sortBy: chartSettings.sortBy || "dimension",
sortDirection: chartSettings.sortDirection || "asc",
limit: Number(chartSettings.limit) || 0,
chartTypes: chartSettings.chartTypes || [
{ key: "column", text: "Column" },
{ key: "bar", text: "Bar" },
{ key: "line", text: "Line" }
],
vizProperties: chartSettings.vizProperties
};
},
_subscribeDummyBackendChanges: function () {
if (this._dummyBackendSubscribed) {
return;
}
sap.ui.getCore().getEventBus().subscribe(
this.dummyBackendChannel,
this.dummyBackendChangedEvent,
this._onDummyBackendChanged,
this
);
this._dummyBackendSubscribed = true;
},
_onDummyBackendChanged: async function () {
await this.setChartData();
},
onExit: function () {
if (!this._dummyBackendSubscribed) {
return;
}
sap.ui.getCore().getEventBus().unsubscribe(
this.dummyBackendChannel,
this.dummyBackendChangedEvent,
this._onDummyBackendChanged,
this
);
this._dummyBackendSubscribed = false;
},
setBusy: function (id, status) {
this.getView()?.byId(id)?.setBusy(status);
},
});
}
);