Skip to content

Commit

Permalink
Change lightness of annotation color if it's not readable on pie/bar (#…
Browse files Browse the repository at this point in the history
…971)

* Change lightness of annotation color if it's not readable on pie/bar.

* Update notebook.
  • Loading branch information
OLarionova-HORIS committed Dec 20, 2023
1 parent 810360e commit 8a93611
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ object Colors {
return (luminance(color) + .05) / (luminance(other) + .05)
}

fun contrastRatio(color: Color, other: Color): Double {
val l1 = luminance(color)
val l2 = luminance(other)
return (max(l1, l2) + .05) / (min(l1, l2) + .05)
}

fun luminance(color: Color): Double {
return .2126 * colorLuminance(color.red) + .7152 * colorLuminance(color.green) + .0722 * colorLuminance(color.blue)
}
Expand Down
14 changes: 7 additions & 7 deletions docs/f-23f/theme_label_text.ipynb

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ open class BarGeom : GeomBase() {
val labelColor = when {
barRect.contains(textRect) -> {
alpha = 0.0
AnnotationsUtil.chooseColor(p.fill()!!)
AnnotationsUtil.chooseColor(annotations.textStyle.color, p.fill()!!)
}
else -> {
alpha = 0.75
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ class PieGeom : GeomBase(), WithWidth, WithHeight {
)
}
val textColor = when (side) {
Side.INSIDE -> AnnotationsUtil.chooseColor(sector.p.fill()!!)
Side.INSIDE -> AnnotationsUtil.chooseColor(annotations.textStyle.color, sector.p.fill()!!)
else -> annotations.textStyle.color
}
return AnnotationLabel(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

package org.jetbrains.letsPlot.core.plot.base.geom.util

import org.jetbrains.letsPlot.commons.colorspace.HSL
import org.jetbrains.letsPlot.commons.colorspace.hslFromRgb
import org.jetbrains.letsPlot.commons.colorspace.rgbFromHsl
import org.jetbrains.letsPlot.commons.geometry.DoubleVector
import org.jetbrains.letsPlot.commons.values.Color
import org.jetbrains.letsPlot.commons.values.Colors
Expand All @@ -25,9 +28,24 @@ object AnnotationsUtil {
)
}

fun chooseColor(background: Color) = when {
Colors.luminance(background) < 0.5 -> Color.WHITE // if fill is dark
else -> Color.BLACK
private const val LIGHTER_LUMINANCE = 0.85
private const val DARKER_LUMINANCE = 0.15
// WCAG recommend a minimum contrast ratio of 4.5:1 for normal text and 3:1 for large text
private const val CONTRAST_RATIO = 3.0

fun chooseColor(textColor: Color, background: Color): Color {
val contrastRatio = Colors.contrastRatio(background, textColor)
if (contrastRatio >= CONTRAST_RATIO) {
return textColor
}
val newLightness = when {
Colors.luminance(background) < 0.5 -> LIGHTER_LUMINANCE
else -> DARKER_LUMINANCE
}
val hsl = hslFromRgb(textColor)
return rgbFromHsl(
HSL(hsl.h, hsl.s, newLightness)
)
}

data class TextParams(
Expand Down

0 comments on commit 8a93611

Please sign in to comment.