UNPKG

@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
"use strict"; 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, }; };