@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
252 lines (251 loc) • 9.17 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const types_1 = require("../_dashboards/dashboard/types");
const datasetHelper_1 = __importDefault(require("../../utils/datasetHelper"));
const utils_1 = __importDefault(require("../_dashboards/dashboard-list/utils"));
const createChart = (chartDefinition, rawData) => {
const timeseriesChartTypes = [types_1.DashboardVisualisationType.BAR_TIMESERIES, types_1.DashboardVisualisationType.LINE_TIMESERIES];
const { type } = chartDefinition;
let table;
let chart;
let details;
if (timeseriesChartTypes.includes(type)) {
const { latestData, dataSetRows, timeseriesData } = getDataForTimeseriesCharts(chartDefinition, rawData);
if (dataSetRows.length) {
chart = createTimeseriesChart(chartDefinition, timeseriesData);
table = createTimeseriesTable(chartDefinition, timeseriesData);
details = getChartDetails(chartDefinition, latestData, true);
}
}
else {
const { dataSetRows, snapshotData } = getDataForSnapshotCharts(chartDefinition, rawData);
if (dataSetRows.length) {
chart = createSnapshotChart(chartDefinition, snapshotData);
table = createSnapshotTable(chartDefinition, dataSetRows);
details = getChartDetails(chartDefinition, dataSetRows);
}
}
return {
details,
table,
chart,
};
};
exports.default = {
createChart,
};
const getDataForSnapshotCharts = (chartDefinition, rawData) => {
const data = datasetHelper_1.default.getLastestDataset(rawData);
const dataSetRows = datasetHelper_1.default.getDatasetRows(chartDefinition, data);
const snapshotData = datasetHelper_1.default.filterRowsByDisplayColumns(chartDefinition, dataSetRows, true);
return {
dataSetRows,
snapshotData,
};
};
const getDataForTimeseriesCharts = (chartDefinition, rawData) => {
const latestData = datasetHelper_1.default.getLastestDataset(rawData);
const dataSetRows = datasetHelper_1.default.getDatasetRows(chartDefinition, rawData);
const timeseriesData = datasetHelper_1.default.filterRowsByDisplayColumns(chartDefinition, dataSetRows, true);
return {
latestData,
dataSetRows,
timeseriesData,
};
};
const getChartDetails = (chartDefinition, data, timeseries = false) => {
var _a, _b;
const meta = [];
const headlines = createHeadlines(chartDefinition, data, timeseries);
if ((_a = data[0]) === null || _a === void 0 ? void 0 : _a.ts) {
meta.push({
label: 'Values for:',
value: (_b = data[0]) === null || _b === void 0 ? void 0 : _b.ts.raw,
});
}
return {
meta,
headlines,
};
};
const createHeadlines = (chartDefinition, data, timeseries = false) => {
const headlines = [];
const { columns } = chartDefinition;
const { measures } = columns;
const isListChart = !!measures.find((col) => col.axis);
let headline;
let headlineColumn;
let value;
let label;
if (timeseries) {
headlineColumn = measures.find((col) => col.id !== 'ts');
if (headlineColumn) {
label = `${data[0].ts.raw}`;
value = +data[0][headlineColumn.id].raw;
headline = {
label,
value,
};
}
}
else {
headlineColumn = !isListChart
? measures[0]
: measures.find((col) => col.axis && col.axis === 'y');
if (headlineColumn) {
label = `Total ${headlineColumn.display.toLowerCase()}`;
value = data.reduce((acc, d) => acc + +d[headlineColumn.id].raw, 0);
headline = {
label,
value,
};
}
}
headlines.push(headline);
return headlines;
};
const createSnapshotChart = (chartDefinition, snapshotData) => {
const { type, columns } = chartDefinition;
const { measures } = columns;
const isListChart = !!measures.find((col) => col.axis);
let labels;
let unit;
let datasets;
if (!isListChart) {
;
({ labels, unit, datasets } = buildChart(columns, snapshotData));
}
else {
;
({ labels, unit, datasets } = buildChartFromListData(columns, snapshotData));
}
return {
type: type,
unit,
data: {
labels,
datasets,
},
};
};
const buildChart = (columns, rawData) => {
var _a;
const { keys, measures } = columns;
const labels = measures.map((col) => col.display);
const labelId = (_a = keys[keys.length - 1]) === null || _a === void 0 ? void 0 : _a.id;
const unit = measures[0].unit ? measures[0].unit : undefined;
const datasets = rawData.map((row) => {
const label = row[labelId] ? `${row[labelId].raw}` : 'All';
const data = measures.map((c) => {
const rowId = c.id;
return row[rowId] ? +row[rowId].raw : 0;
});
const total = data.reduce((acc, val) => acc + val, 0);
return { label, data, total };
});
return {
labels,
unit,
datasets,
};
};
const buildChartFromListData = (columns, rawData) => {
var _a;
const { measures, keys } = columns;
const xAxisColumn = measures.find((col) => col.axis === 'x');
const yAxisColumn = measures.find((col) => col.axis === 'y');
const unit = (yAxisColumn === null || yAxisColumn === void 0 ? void 0 : yAxisColumn.unit) || undefined;
const groupKey = datasetHelper_1.default.getGroupKey(keys, rawData);
const groupsData = groupKey ? datasetHelper_1.default.groupRowsByKey(rawData, groupKey.id) : [rawData];
const labels = (_a = groupsData[0]) === null || _a === void 0 ? void 0 : _a.map((row) => {
return `${row[xAxisColumn.id].raw}`;
});
const datasets = groupsData.map((groupData) => {
const data = groupData.map((row) => +row[yAxisColumn.id].raw);
return {
label: groupKey ? `${groupData[0][groupKey.id].raw}` : yAxisColumn.display,
data,
total: data.reduce((acc, val) => acc + val, 0),
};
});
return {
labels,
unit,
datasets,
};
};
const createSnapshotTable = (chartDefinition, data) => {
const { columns } = chartDefinition;
const { keys, measures } = columns;
const headerColumns = [...keys, ...measures];
const head = headerColumns.map((column) => {
return { text: column.display };
});
const filteredRowData = datasetHelper_1.default.filterRowsByDisplayColumns(chartDefinition, data, true);
const rows = utils_1.default.createTableRows(filteredRowData);
return {
head,
rows,
};
};
const createTimeseriesChart = (chartDefinition, timeseriesData) => {
const { columns } = chartDefinition;
const { keys, measures } = columns;
const unit = measures[0].unit ? measures[0].unit : undefined;
const type = chartDefinition.type === types_1.DashboardVisualisationType.BAR_TIMESERIES ? 'bar' : 'line';
const groupKey = datasetHelper_1.default.getGroupKey(keys, timeseriesData);
const labelId = groupKey.id;
const timeBlockData = datasetHelper_1.default.groupRowsByTimestamp(timeseriesData);
const labels = timeBlockData.map((d) => d[0].ts.raw);
const datasetCount = timeBlockData[0].length;
const datasets = [];
for (let index = 0; index < datasetCount; index += 1) {
const data = timeBlockData.map((timeperiod) => {
return +timeperiod[index][measures[1].id].raw;
});
const total = data.reduce((a, c) => a + c, 0);
const label = timeBlockData[0][index][labelId].raw;
datasets.push({
data,
label,
total,
});
}
return {
type: type,
unit,
timeseries: true,
data: {
labels,
datasets,
},
};
};
const createTimeseriesTable = (chartDefinition, timeseriesData) => {
const { columns } = chartDefinition;
const { keys, measures } = columns;
let flatTimeseriesData = timeseriesData.flat();
const hasMultipleRowsPerTimePeriod = timeseriesData.length > 1;
let headerColumns = [...measures];
if (hasMultipleRowsPerTimePeriod) {
const timestampIndex = headerColumns.findIndex((m) => m.id === 'ts');
const timestampCol = headerColumns[timestampIndex];
headerColumns.splice(timestampIndex, 1);
headerColumns = [...keys, ...headerColumns];
headerColumns.unshift(timestampCol);
}
else {
flatTimeseriesData = datasetHelper_1.default.filterRowsByDisplayColumns(chartDefinition, flatTimeseriesData);
}
const head = headerColumns.map((column) => {
return { text: column.display };
});
const rows = utils_1.default.createTableRows(flatTimeseriesData);
return {
head,
rows,
};
};