"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.workoutColorForValue = workoutColorForValue; var _coloring = require("@kbn/coloring"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ function findColorSegment(value, comparison, colors, rangeMin, rangeMax) { var _colors$index; // assume uniform distribution within the provided range, can ignore stops const step = (rangeMax - rangeMin) / colors.length; // what about values in range const index = colors.findIndex((c, i) => comparison(value, rangeMin + (1 + i) * step) <= 0); // see comment below in function 'findColorsByStops' return (_colors$index = colors[index]) !== null && _colors$index !== void 0 ? _colors$index : value >= rangeMin + colors.length * step ? colors[colors.length - 1] : colors[0]; } function findColorsByStops(value, comparison, colors, stops) { var _colors$index2; const index = stops.findIndex(s => comparison(value, s) < 0); // as we now we can provide 'rangeMax' as end for last interval (iterval [lastStop, rangeMax]), // value can be more that last stop but will be valid // because of this we should provide for that value the last color. // (For example, value = 100, last stop = 80, rangeMax = 120, before we was return the first color, // but now we will return the last one) return (_colors$index2 = colors[index]) !== null && _colors$index2 !== void 0 ? _colors$index2 : value >= stops[stops.length - 1] ? colors[colors.length - 1] : colors[0]; } function getNormalizedValueByRange(value, { range, rangeMin }, minMax) { let result = value; if (range === 'percent') { result = 100 * (value - minMax.min) / (minMax.max - minMax.min); // a division by zero safeguard is required if the range above has equal boundaries if (!Number.isFinite(result)) { return rangeMin; } } return result; } const getNormalizedMaxRange = ({ stops, colors, rangeMax }, isMaxContinuity, [min, max]) => { if (isMaxContinuity) { return Number.POSITIVE_INFINITY; } return stops.length ? rangeMax : max - (max - min) / colors.length; }; const getNormalizedMinRange = ({ stops, rangeMin }, isMinContinuity, min) => { if (isMinContinuity) { return Number.NEGATIVE_INFINITY; } return stops.length ? rangeMin : min; }; /** * When stops are empty, it is assumed a predefined palette, so colors are distributed uniformly in the whole data range * When stops are passed, then rangeMin/rangeMax are used as reference for user defined limits: * continuity is defined over rangeMin/rangeMax, not these stops values (rangeMin/rangeMax are computed from user's stop inputs) */ function workoutColorForValue(value, params, minMax) { if (value == null) { return; } const { colors, stops, range = 'percent', continuity = 'above', rangeMax, rangeMin } = params; const isMinContinuity = (0, _coloring.checkIsMinContinuity)(continuity); const isMaxContinuity = (0, _coloring.checkIsMaxContinuity)(continuity); // ranges can be absolute numbers or percentages // normalized the incoming value to the same format as range to make easier comparisons const normalizedValue = getNormalizedValueByRange(value, params, minMax); const [min, max] = range === 'percent' ? [0, 100] : [minMax.min, minMax.max]; const minRange = getNormalizedMinRange({ stops, rangeMin }, isMinContinuity, min); const maxRange = getNormalizedMaxRange({ stops, colors, rangeMax }, isMaxContinuity, [min, max]); const comparisonFn = (v, threshold) => v - threshold; if (comparisonFn(normalizedValue, minRange) < 0) { if (isMinContinuity) { return colors[0]; } return; } if (comparisonFn(normalizedValue, maxRange) > 0) { if (isMaxContinuity) { return colors[colors.length - 1]; } return; } if (stops.length) { return findColorsByStops(normalizedValue, comparisonFn, colors, stops); } return findColorSegment(normalizedValue, comparisonFn, colors, min, max); }