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}
}