@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
JavaScript
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