From 0df8d341e5d5440358db840df57b2a876434b9ce Mon Sep 17 00:00:00 2001 From: Alex P Date: Thu, 8 Feb 2018 14:04:33 -0800 Subject: [PATCH] Improve handling of single stat coloring Previously would return some undesirable defaults when certain conditions are met (eg. a user with a single stat + line graph upgrades to this new version) --- ui/src/shared/components/SingleStat.js | 41 ++------- ui/src/shared/constants/colorOperations.js | 96 +++++++++++++++++++++- 2 files changed, 100 insertions(+), 37 deletions(-) diff --git a/ui/src/shared/components/SingleStat.js b/ui/src/shared/components/SingleStat.js index cd2d0f7d9f..623a48dbd0 100644 --- a/ui/src/shared/components/SingleStat.js +++ b/ui/src/shared/components/SingleStat.js @@ -5,10 +5,7 @@ import lastValues from 'shared/parsing/lastValues' import {SMALL_CELL_HEIGHT} from 'shared/graphs/helpers' import {SINGLE_STAT_TEXT} from 'src/dashboards/constants/gaugeColors' -import {isBackgroundLight} from 'shared/constants/colorOperations' - -const darkText = '#292933' -const lightText = '#ffffff' +import {generateSingleStatHexs} from 'shared/constants/colorOperations' class SingleStat extends PureComponent { render() { @@ -32,38 +29,16 @@ class SingleStat extends PureComponent { } const lastValue = lastValues(data)[1] - const precision = 100.0 const roundedValue = Math.round(+lastValue * precision) / precision - let bgColor = null - let textColor = null + const colorizeText = _.some(colors, {type: SINGLE_STAT_TEXT}) - if (colors.length === 1) { - if (colors[0].type === SINGLE_STAT_TEXT) { - textColor = colors[0].hex - } else { - bgColor = colors[0].hex - textColor = isBackgroundLight(bgColor) ? darkText : lightText - } - } else if (colors.length > 1) { - const sortedColors = _.sortBy(colors, color => Number(color.value)) - const nearestCrossedThreshold = sortedColors - .filter(color => lastValue > color.value) - .pop() - - const colorizeText = _.some(colors, {type: SINGLE_STAT_TEXT}) - - if (colorizeText) { - textColor = nearestCrossedThreshold - ? nearestCrossedThreshold.hex - : '#292933' - } else { - bgColor = nearestCrossedThreshold - ? nearestCrossedThreshold.hex - : '#292933' - textColor = isBackgroundLight(bgColor) ? darkText : lightText - } - } + const {bgColor, textColor} = generateSingleStatHexs( + colors, + lineGraph, + colorizeText, + lastValue + ) return (
{ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) return result @@ -16,9 +22,91 @@ const averageRgbValues = valuesObject => { const trueNeutralGrey = 128 -export const isBackgroundLight = backgroundColor => { - const averageBackground = averageRgbValues(hexToRgb(backgroundColor)) - const isLight = averageBackground > trueNeutralGrey +const getLegibleTextColor = bgColorHex => { + const averageBackground = averageRgbValues(hexToRgb(bgColorHex)) + const isBackgroundLight = averageBackground > trueNeutralGrey - return isLight + const darkText = '#292933' + const lightText = '#ffffff' + + return isBackgroundLight ? darkText : lightText +} + +const findNearestCrossedThreshold = (colors, lastValue) => { + const sortedColors = _.sortBy(colors, color => Number(color.value)) + const nearestCrossedThreshold = sortedColors + .filter(color => lastValue > color.value) + .pop() + + return nearestCrossedThreshold +} + +export const generateSingleStatHexs = ( + colors, + containsLineGraph, + colorizeText, + lastValue +) => { + const defaultColoring = {bgColor: null, textColor: GAUGE_COLORS[11].hex} + + if (!colors & containsLineGraph) { + return defaultColoring + } + + // baseColor is expected in all cases + const baseColor = colors.find(color => (color.id = SINGLE_STAT_BASE)) + + // If the single stat is above a line graph never have a background color + if (containsLineGraph) { + return baseColor + ? {bgColor: null, textColor: baseColor.hex} + : defaultColoring + } + + // When there is only a base color and it's applied to the text + if (colorizeText && colors.length === 1) { + return baseColor + ? {bgColor: null, textColor: baseColor.hex} + : defaultColoring + } + + // When there's multiple colors and they're applied to the text + if (colorizeText && colors.length > 1) { + const nearestCrossedThreshold = findNearestCrossedThreshold( + colors, + lastValue + ) + const bgColor = null + const textColor = nearestCrossedThreshold.hex + + return {bgColor, textColor} + } + + // When there is only a base color and it's applued to the background + if (colors.length === 1) { + const bgColor = baseColor.hex + const textColor = getLegibleTextColor(bgColor) + + return {bgColor, textColor} + } + + // When there are multiple colors and they're applied to the background + if (colors.length > 1) { + const nearestCrossedThreshold = findNearestCrossedThreshold( + colors, + lastValue + ) + + const bgColor = nearestCrossedThreshold + ? nearestCrossedThreshold.hex + : baseColor.hex + const textColor = getLegibleTextColor(bgColor) + + return {bgColor, textColor} + } + + // If all else fails, use safe default + const bgColor = null + const textColor = baseColor.hex + return {bgColor, textColor} }