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.

183 lines (180 loc) 7.33 kB
import DatasetHelper from '../../../utils/Dashboards/VisualisationDatasetHelper.js'; import { Buckets } from '../../_charts/chart/buckets/Buckets.js'; import { ScorecardVisualisation } from '../scorecard/Scorecard.js'; import ScorecardGroupSchemas from './validate.js'; class ScorecardGroupVisualisation { definition; id; measures; keys; options; dataset; groupKey; groupKeyId; groupKeyDisplay; bucketsHelper; buckets = []; valueColumn; valueKey = ''; titleColumn; titleKey = ''; responseData = []; scoreCardBuilder; constructor() { this.scoreCardBuilder = new ScorecardVisualisation(); } withDefinition = (definition) => { this.definition = ScorecardGroupSchemas.ScorecardGroupSchema.parse(definition); this.init(); return this; }; withData = (responseData) => { this.responseData = responseData; this.dataset = this.scoreCardBuilder.getDataset(this.definition, this.responseData); this.initBuckets(this.responseData, this.valueKey); this.initGroupVars(); return this; }; init = () => { this.id = this.definition.id; this.measures = this.definition.columns.measures; this.keys = this.definition.columns.keys; this.options = this.definition.options; this.valueKey = this.measures[0].id; this.titleColumn = { display: this.definition.display || '', id: this.valueKey }; }; initBuckets = (responseData, valueKey) => { if (this.options?.buckets || this.options?.useRagColour) { this.bucketsHelper = new Buckets(responseData, this.definition, valueKey, false, this.scoreCardBuilder.ragColours); this.buckets = this.bucketsHelper.getBuckets(); } }; initGroupVars = () => { this.groupKey = DatasetHelper.getGroupKey(this.dataset.latest, this.keys || []); this.groupKeyId = this.groupKey?.id; this.groupKeyDisplay = this.groupKey?.display; this.valueColumn = this.measures.find(col => col.displayValue); if (this.valueColumn) { this.valueKey = this.valueColumn?.id; this.titleColumn = this.measures.find(col => { return col.display || col.display === ''; }); this.titleKey = this.titleColumn?.id || ''; } }; createScorecardGroupFromColumns = () => { const { latest, earliest, latestTs, earliestTs } = this.dataset; return latest.map((row, rowIndex) => { return { title: this.createGroupTitle(row), scorecards: Object.keys(row) .filter(colId => { return this.measures.some(m => m.id === colId); }) .map(colId => { const measure = this.measures.find(m => m.id === colId); const title = measure?.display || colId; const unit = measure?.unit; const rowCol = row[colId]; const { raw, rag } = rowCol; const value = Number(raw); const ragValue = rag !== undefined ? Number(rag) : undefined; this.initBuckets([row], colId); const valueFor = `${latestTs}`; const valueFrom = `${earliestTs}`; const comparisonRow = earliest[rowIndex]; const prevVal = comparisonRow[colId]?.raw; const ragScore = this.scoreCardBuilder.setRagScore(value, ragValue, this.buckets, this.bucketsHelper); return this.scoreCardBuilder.createScorecardData({ id: this.id, title, value, rag: ragScore, prevVal, valueFor, valueFrom, unit, }); }), }; }); }; createScorecardGroupFromList = () => { const { latest, earliest } = this.dataset; return [ { title: '', scorecards: latest.map((row, index) => { const values = this.getScorecardValues(row); const prevVal = earliest[index][this.valueKey].raw; return this.scoreCardBuilder.createScorecardData({ ...values, prevVal, }); }), }, ]; }; createScorecardGroupFromListWithGroups = () => { const { latest, earliest } = this.dataset; let earliestGroupedByKey = DatasetHelper.groupRowsByKey(earliest, this.groupKeyId); let latestGroupedByKey = DatasetHelper.groupRowsByKey(latest, this.groupKeyId); if (this.groupKeyId === this.titleKey) { latestGroupedByKey = [latestGroupedByKey.flat()]; earliestGroupedByKey = [earliestGroupedByKey.flat()]; } const scorecardGroup = latestGroupedByKey.map((group, groupIndex) => { return { title: this.groupKeyDisplay ? `By ${this.groupKeyDisplay}` : '', scorecards: group.map((row, rowIndex) => { const values = this.getScorecardValues(row); const comparisonRow = earliestGroupedByKey[groupIndex][rowIndex]; const prevVal = comparisonRow[this.valueKey]?.raw; return this.scoreCardBuilder.createScorecardData({ ...values, prevVal, }); }), }; }); return scorecardGroup; }; getScorecardValues = (row) => { const { latestTs, earliestTs } = this.dataset; const title = `${this.titleColumn?.display} ${row[this.titleKey].raw}`; const rowCol = row[this.valueKey]; const { raw, rag: ragScore } = rowCol; const value = Number(raw); const rag = ragScore !== undefined ? Number(ragScore) : undefined; this.initBuckets([row], this.valueKey); const valueFor = `${latestTs}`; const valueFrom = `${earliestTs}`; return { id: this.id, title, value, rag: this.scoreCardBuilder.setRagScore(value, rag, this.buckets, this.bucketsHelper), valueFor, valueFrom, }; }; createGroupTitle = (row) => { const title = this.groupKeyId ? `${row[this.groupKeyId]?.raw}` : ''; return this.groupKeyDisplay && this.groupKeyDisplay.length ? `${this.groupKeyDisplay}: ${title}` : title; }; build = () => { let scorecardGroup; if (!this.valueColumn) { scorecardGroup = this.createScorecardGroupFromColumns(); } else if (this.groupKey) { scorecardGroup = this.createScorecardGroupFromListWithGroups(); } else { scorecardGroup = this.createScorecardGroupFromList(); } return scorecardGroup; }; } export { ScorecardGroupVisualisation, ScorecardGroupVisualisation as default }; //# sourceMappingURL=ScorecardGroup.js.map