@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
149 lines (144 loc) • 5.5 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var ChartColours = require('./ChartColours.js');
var ChartLabels = require('./ChartLabels.js');
var chartConfig = require('./chart-config.js');
var VisualisationDatasetHelper = require('../../../utils/Dashboards/VisualisationDatasetHelper.js');
var VisualisationUnitHelper = require('../../../utils/Dashboards/VisualisationUnitHelper.js');
class Chart {
labels = [];
datasets = [];
unit;
responseData = [];
backgroundColor = [];
borderWidth = [0, 0];
borderColor = [];
hexColours = [];
config = chartConfig;
xAxisColumn;
yAxisColumn;
groupedData = [];
chartColoursHelper;
chartLabelsHelper;
withData = (responseData) => {
this.responseData = responseData;
this.initHelpers();
return this;
};
initUnit = (measures) => {
this.unit = measures.find(m => m.unit)?.unit;
};
initHelpers = () => {
this.chartColoursHelper = new ChartColours();
this.chartLabelsHelper = new ChartLabels();
};
// -----------------------------------------------------------------------------
// Datasets
// ----------------------------------------------------------------------------
/**
* Creates chart.js datasets where:
* - where each row is a dataset
* - each column name is an x axis label
*
* @param {ChartMeasure[]} measures
* @param {VisualisationDefinitionKey[]} keys
* @memberof Chart
*/
createDatasets = (measures, keys) => {
this.datasets = this.responseData.map((row, datasetIndex) => {
const label = this.chartLabelsHelper.getDatasetLabel(keys, row);
const data = this.createDatasetValues(measures, row);
const total = data.reduce((acc, val) => acc + val, 0);
return {
label,
data,
total,
...this.setStyles(datasetIndex),
};
});
this.labels = this.chartLabelsHelper.getLabels(measures);
};
/**
* Creates chart.js datasets where:
* - ecah column is a dataset
* - each value in a column is an x axis label
*
* @param {ChartMeasure[]} measures
* @param {VisualisationDefinitionKey[]} keys
* @memberof Chart
*/
createListDatasets = (measures, keys) => {
this.xAxisColumn = measures.find((col) => col.axis === 'x');
this.yAxisColumn = measures.find((col) => col.axis === 'y');
const yId = this.yAxisColumn?.id || '';
const xId = this.xAxisColumn?.id || '';
const keyIds = keys.map(key => key.id);
this.groupedData = keyIds.length ? VisualisationDatasetHelper.default.groupRowsBy(this.responseData, keyIds) : [this.responseData];
this.labels = this.chartLabelsHelper.getListLabels(this.groupedData, xId);
this.datasets = this.groupedData.map((groupData, groupIndex) => {
const data = Array(this.labels.length);
groupData.forEach(row => {
const labelField = row[xId];
const valueField = row[yId];
const raw = valueField && valueField.raw ? Number(valueField.raw) : 0;
const dataIndex = this.labels.findIndex(l => l === labelField.raw);
if (dataIndex !== -1) {
data[dataIndex] = Number(raw);
}
});
const label = this.chartLabelsHelper.getDatasetLabel(keys, groupData[0]);
return {
label,
data,
total: data.reduce((acc, val) => acc + val, 0),
...this.setStyles(groupIndex),
};
});
const unitSymbol = VisualisationUnitHelper.mapUnitToSymbol(this.yAxisColumn?.unit);
this.labels = this.chartLabelsHelper.getListLabels(this.groupedData, xId, unitSymbol);
};
createDatasetValues = (measures, row) => {
return measures.map(column => {
const rowId = column.id;
const value = row[rowId]?.raw;
if (!rowId || !value) {
return 0;
}
const numericValue = Number(value);
return Number.isNaN(numericValue) ? 0 : numericValue;
});
};
// -----------------------------------------------------------------------------
// Styles
// ----------------------------------------------------------------------------
setStyles = (datasetIndex) => {
return this.chartColoursHelper.setColourStyles(datasetIndex);
};
// -----------------------------------------------------------------------------
// Scales
// ----------------------------------------------------------------------------
setScales = (args) => {
const labelText = args?.label || 'Total';
const unitSymbol = VisualisationUnitHelper.mapUnitToSymbol(this.unit);
const text = unitSymbol ? `${labelText} (${unitSymbol})` : labelText;
const title = {
display: true,
text,
};
const scales = {
x: {
...(args?.horizontal && { title }),
},
y: {
...(!args?.horizontal && { title }),
},
};
this.config = {
...this.config,
scales,
};
};
}
exports.Chart = Chart;
exports.default = Chart;
//# sourceMappingURL=Chart.js.map