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
parent
c5fd1a57ca
commit
0df8d341e5
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue