@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
179 lines (176 loc) • 6.12 kB
JavaScript
import { withAlphaHex } from 'with-alpha-hex';
import { BucketOptionsSchema } from './validate.js';
/* eslint-disable prefer-destructuring */
class Buckets {
baseColour = '#1d70b8';
ragColours = ['#00703c', '#ffdd00', '#d4351c'];
buckets = [];
useRagColour = false;
bucketCount = 0;
onlyBucketColoursDefined = false;
autoBucketing = false;
hasRagScore = false;
valueKey;
options;
responseData;
constructor(responseData, definition, valueKey, autoBucketing, ragColours) {
this.responseData = responseData;
this.initFromOptions(definition);
this.valueKey = valueKey;
this.hasRagScore = responseData[0][this.valueKey].rag !== undefined;
this.autoBucketing = Boolean(autoBucketing);
if (ragColours)
this.ragColours = ragColours;
this.initBuckets();
}
initFromOptions = (definition) => {
this.options = BucketOptionsSchema.parse(definition.options);
this.baseColour = this.options?.baseColour || this.baseColour;
this.useRagColour = this.options?.useRagColour || false;
this.onlyBucketColoursDefined =
this.options && this.options.buckets
? this.options?.buckets?.every(bucket => !bucket.max && !bucket.min && bucket.hexColour !== undefined)
: false;
};
initBuckets = () => {
const { buckets } = this.options;
this.setBucketCount();
this.initBucketColours();
if (buckets && buckets.length) {
if (this.hasRagScore) {
if (this.onlyBucketColoursDefined) {
this.buckets = buckets;
}
}
else if (!this.hasRagScore && this.onlyBucketColoursDefined && this.autoBucketing) {
this.initAutomaticThresholdBucket();
}
else {
this.initCustomThresholdBuckets();
}
}
else if (!this.hasRagScore && this.autoBucketing) {
this.initAutomaticThresholdBucket();
}
};
initCustomThresholdBuckets = () => {
this.buckets = this.options.buckets
? this.options.buckets.map((bucket, i) => {
return {
...this.buckets[i],
...bucket,
};
})
: [];
};
/**
* Initialises the bucket thresholds by defining the range between the min and max
* and dividing into 3 equal parts
*/
initAutomaticThresholdBucket = () => {
const { min, max, bucketSize } = this.setAutomaticThresholdSize();
let maxValue = 0;
this.buckets = this.buckets.map((bucket, i) => {
let minValue = min;
if (i !== 0)
minValue = maxValue + 1;
maxValue = bucketSize * (i + 1) + min;
if (i === this.buckets.length - 1)
maxValue = max;
return {
hexColour: this.options?.buckets && this.options?.buckets.length ? this.options.buckets[i]?.hexColour : bucket.hexColour,
min: minValue,
max: maxValue,
};
});
};
initBucketColours = () => {
if (this.useRagColour && this.bucketCount === 3) {
this.buckets = Array.from(new Array(this.bucketCount)).map((_d, i) => {
return {
hexColour: this.ragColours[i],
};
});
}
else {
const alphaDivision = 1 / this.bucketCount;
this.buckets = Array.from(new Array(this.bucketCount)).map((_d, i) => {
const division = alphaDivision * (i + 1);
return {
hexColour: withAlphaHex(this.baseColour, division),
};
});
}
};
setAutomaticThresholdSize = () => {
const values = this.responseData.map(resData => Number(resData[this.valueKey].raw));
const min = Math.min(...values);
const max = Math.max(...values);
const bucketSize = Math.ceil((max - min) / this.bucketCount);
return {
min,
max,
bucketSize,
};
};
setBucketCount = () => {
const { buckets } = this.options;
if (this.hasRagScore) {
if (this.useRagColour) {
this.bucketCount = 3;
}
else {
const allRags = this.responseData.reduce((acc, resData) => {
if (resData[this.valueKey].rag !== undefined) {
acc.push(resData[this.valueKey].rag);
}
return acc;
}, []);
this.bucketCount = Math.max(...allRags) + 1;
}
}
else if (buckets && buckets.length) {
this.bucketCount = buckets.length;
}
else {
this.bucketCount = 3;
}
};
getBucketForValue = (value, ragScore) => {
let colour = '';
let score = 0;
if (ragScore !== undefined) {
return {
colour: this.buckets[ragScore].hexColour || colour,
score: ragScore,
};
}
this.buckets.forEach((bucket, index) => {
const { min, max } = bucket;
// First bucket
if (!min && max && value <= max) {
colour = bucket.hexColour || colour;
score = index;
}
// middle buckets
if (min && value >= min && max && value <= max) {
colour = bucket.hexColour || colour;
score = index;
}
// last bucket
if (min && !max && value >= min) {
colour = bucket.hexColour || colour;
score = index;
}
});
return {
colour,
score,
};
};
getBuckets = () => {
return this.buckets;
};
}
export { Buckets, Buckets as default };
//# sourceMappingURL=Buckets.js.map