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)
pull/10616/head
Alex P 2018-02-08 14:04:33 -08:00
parent c5fd1a57ca
commit 0df8d341e5
2 changed files with 100 additions and 37 deletions

View File

@ -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 (
<div

View File

@ -1,3 +1,9 @@
import _ from 'lodash'
import {
GAUGE_COLORS,
SINGLE_STAT_BASE,
} from 'src/dashboards/constants/gaugeColors'
const hexToRgb = hex => {
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}
}