Skip to content

Commit

Permalink
update Palette to allow all colors to be accessed (#1509)
Browse files Browse the repository at this point in the history
Convert the Palette to require an ArraySeq of colors. Rename the parameter
and implement colors() to avoid code changing in other places. This allows
the full set of colors to be accessed directly for use with things like heatmaps.
  • Loading branch information
manolama committed Jan 13, 2023
1 parent 4a332b3 commit 1dd6ea2
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,43 +18,39 @@ package com.netflix.atlas.chart.model
import java.awt.Color
import java.io.FileNotFoundException
import java.util.concurrent.ConcurrentHashMap

import com.netflix.atlas.chart.Colors
import com.netflix.atlas.core.util.Strings

case class Palette(name: String, colors: Int => Color) {
import scala.collection.immutable.ArraySeq

def withAlpha(alpha: Int): Palette = {
case class Palette(name: String, colorArray: ArraySeq[Color]) {

def f(i: Int): Color = {
val c = colors(i)
new Color(c.getRed, c.getGreen, c.getBlue, alpha)
}
Palette(name, f)
override def equals(obj: Any): Boolean = {
if (obj == null) return false
if (!obj.isInstanceOf[Palette]) return false
val other = obj.asInstanceOf[Palette]
if (!name.equals(other.name)) return false
colorArray.equals(other.colorArray)
}

def withVisionType(vision: VisionType): Palette = {
def withAlpha(alpha: Int): Palette =
Palette(name, colorArray.map(c => new Color(c.getRed, c.getGreen, c.getBlue, alpha)))

def f(i: Int): Color = {
val c = colors(i)
vision.convert(c)
}
Palette(s"${vision.name}_$name", f)
}
def withVisionType(vision: VisionType): Palette =
Palette(s"${vision.name}_$name", colorArray.map(vision.convert(_)))

/**
* Convert colors from another palette into grayscale. For information about the conversion
* see: http://www.johndcook.com/blog/2009/08/24/algorithms-convert-color-grayscale/.
*/
def asGrayscale: Palette = {

def f(i: Int): Color = {
val c = colors(i)
val v = (0.21 * c.getRed + 0.72 * c.getGreen + 0.07 * c.getBlue).toInt
new Color(v, v, v, c.getAlpha)
}
Palette(s"grayscale_$name", f)
}
def asGrayscale: Palette =
Palette(
s"grayscale_$name",
colorArray.map { c =>
val v = (0.21 * c.getRed + 0.72 * c.getGreen + 0.07 * c.getBlue).toInt
new Color(v, v, v, c.getAlpha)
}
)

def iterator: Iterator[Color] = new Iterator[Color] {

Expand All @@ -64,9 +60,24 @@ case class Palette(name: String, colors: Int => Color) {

override def next(): Color = {
pos += 1
colors(pos)
if (pos >= colorArray.length) pos = 0
colorArray(pos)
}
}

/**
* Rotates through the colors in the palette based on the index, returning a
* deterministic color.
*
* @param i
* A positive integer value.
* @return
* A deterministic color in the palette.
*/
def colors(i: Int): Color = {
val index = math.abs(i) % colorArray.length
colorArray(index)
}
}

object Palette {
Expand Down Expand Up @@ -121,7 +132,7 @@ object Palette {

def fromArray(name: String, colors: Array[Color]): Palette = {
require(colors.nonEmpty, "palette must contain at least one color")
Palette(name, i => colors(math.abs(i) % colors.length))
Palette(name, ArraySeq.from(colors))
}

/**
Expand All @@ -143,7 +154,7 @@ object Palette {
}

def singleColor(c: Color): Palette = {
Palette("%08X".format(c.getRGB), _ => c)
Palette("%08X".format(c.getRGB), ArraySeq(c))
}

def brighter(c: Color, n: Int): Palette = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,22 @@ class PaletteSuite extends FunSuite {
test("colors:f00") {
val p = Palette.create("colors:f00")
assertEquals(p.colors(0), Color.RED)
assertEquals(1, p.colorArray.size)
}

test("colors:f00,00ff00") {
val p = Palette.create("colors:f00,00ff00")
assertEquals(p.colors(0), Color.RED)
assertEquals(p.colors(1), Color.GREEN)
assertEquals(2, p.colorArray.size)
}

test("colors:f00,00ff00,ff0000ff") {
val p = Palette.create("colors:f00,00ff00,ff0000ff")
assertEquals(p.colors(0), Color.RED)
assertEquals(p.colors(1), Color.GREEN)
assertEquals(p.colors(2), Color.BLUE)
assertEquals(3, p.colorArray.size)
}

test("(,)") {
Expand All @@ -66,24 +69,28 @@ class PaletteSuite extends FunSuite {
test("(,f00,)") {
val p = Palette.create("(,f00,)")
assertEquals(p.colors(0), Color.RED)
assertEquals(1, p.colorArray.size)
}

test("(,f00,00ff00,)") {
val p = Palette.create("(,f00,00ff00,)")
assertEquals(p.colors(0), Color.RED)
assertEquals(p.colors(1), Color.GREEN)
assertEquals(2, p.colorArray.size)
}

test("(,f00,00ff00,ff0000ff,)") {
val p = Palette.create("(,f00,00ff00,ff0000ff,)")
assertEquals(p.colors(0), Color.RED)
assertEquals(p.colors(1), Color.GREEN)
assertEquals(p.colors(2), Color.BLUE)
assertEquals(3, p.colorArray.size)
}

test("armytage") {
val p = Palette.create("armytage")
assertEquals(p.colors(0), new Color(0, 117, 220))
assertEquals(24, p.colorArray.size)
}

test("foo") {
Expand Down

0 comments on commit 1dd6ea2

Please sign in to comment.