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.

179 lines (176 loc) 6.12 kB
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