@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
194 lines (189 loc) • 6.12 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var dayjs = require('dayjs');
var logger = require('../../../../utils/logger.js');
var VisualisationDatasetHelper = require('../../../../utils/Dashboards/VisualisationDatasetHelper.js');
var types = require('../../../_dashboards/dashboard-visualisation/types.js');
var Buckets = require('../buckets/Buckets.js');
var chartConfig = require('../chart-config.js');
var validate = require('./validate.js');
/* eslint-disable prefer-destructuring */
class HeatmapChart {
definition;
measures;
responseData = [];
granularity;
data = [];
dayDateFormat = 'YYYY-MM-DD';
valueKey = '';
label = '';
unit;
bucketsHelper;
datasets = [];
config = chartConfig;
xLabels = [];
yLabels = [];
withDefinition = (definition) => {
this.definition = validate.parse(definition);
this.init();
return this;
};
withData = (responseData) => {
this.responseData = responseData;
this.bucketsHelper = new Buckets.Buckets(this.responseData, this.definition, this.valueKey, true);
return this;
};
withGranularity = (granularity) => {
this.granularity = granularity;
return this;
};
init = () => {
this.measures = this.definition.columns.measures;
this.setLabel();
this.initUnit();
};
initUnit = () => {
this.unit = this.measures[0].unit ? this.measures[0].unit : undefined;
};
setLabel = () => {
const { id, display } = this.measures[1];
this.valueKey = id;
this.label = display || '';
};
initTimeseriesData = () => {
const dateMeasure = VisualisationDatasetHelper.getTimestampMeasure(this.measures);
if (!dateMeasure) {
throw new Error('No timestamp field in definition');
}
const timeBlockData = VisualisationDatasetHelper.default.groupRowsByTimestamp(this.responseData, dateMeasure);
this.data = timeBlockData
.map(tsData => {
const { raw, rag } = tsData[0][this.valueKey];
const dateColumn = VisualisationDatasetHelper.getTimestampColumn(this.definition.columns);
const dateData = VisualisationDatasetHelper.getDateValue(tsData, dateColumn);
if (!dateData?.value) {
logger.default.warn('Data point dropped due to no date value');
return undefined;
}
const tsRaw = dateData.value;
const v = Number(raw);
const r = rag !== undefined ? Number(tsData[0][this.valueKey].rag) : undefined;
let x = 0;
let y = 0;
switch (this.granularity) {
case 'hourly':
break;
case 'weekly':
x = dayjs(tsRaw, this.dayDateFormat).format('ddd');
y = dayjs(tsRaw, this.dayDateFormat).week();
break;
case 'daily':
x = dayjs(tsRaw, this.dayDateFormat).format('MMM YY');
y = dayjs(tsRaw, this.dayDateFormat).format('D');
break;
case 'monthly':
{
const ts = tsRaw.split(' ');
x = ts[1];
y = ts[0];
}
break;
case 'annually':
x = 'year';
y = tsRaw;
break;
default:
x = dayjs(tsRaw, this.dayDateFormat).format('MMM YY');
y = dayjs(tsRaw, this.dayDateFormat).format('D');
break;
}
return { y, x, v, r };
})
.filter((v) => v !== undefined);
this.bucketData();
this.datasets = [
{
label: this.label,
data: this.data,
},
];
};
bucketData = () => {
this.data = this.data.map(d => {
const { v, r } = d;
const bucketData = this.bucketsHelper.getBucketForValue(v, r);
return { ...d, c: bucketData.colour };
});
};
setBespokeOptions = () => {
this.config = {
...this.config,
scales: this.setScales(),
};
};
setScales() {
this.xLabels = [
...new Set(this.datasets[0].data.map(d => {
return d.x;
})),
];
this.yLabels = [
...new Set(this.datasets[0].data.map(d => {
return d.y;
})),
];
const grid = {
display: false,
drawBorder: false,
};
const ticks = {
padding: 1,
maxRotation: 0,
stepSize: 1,
};
const offset = true;
const common = {
offset,
ticks,
grid,
};
return {
y: {
position: 'left',
type: 'category',
...(this.yLabels && { labels: this.yLabels }),
...common,
},
x: {
position: 'top',
type: 'category',
...(this.xLabels && { labels: this.xLabels }),
...common,
},
};
}
getCanvasHeight = () => {
return this.yLabels.length / 2;
};
build = () => {
this.initTimeseriesData();
this.bucketData();
this.setBespokeOptions();
const height = this.getCanvasHeight();
return {
type: types.DashboardVisualisationType.MATRIX,
options: {
unit: this.unit,
timeseries: true,
height,
},
data: {
datasets: this.datasets,
config: this.config,
},
};
};
}
exports.HeatmapChart = HeatmapChart;
exports.default = HeatmapChart;
//# sourceMappingURL=HeatmapChart.js.map