-
Notifications
You must be signed in to change notification settings - Fork 174
/
colors.go
109 lines (96 loc) · 2.96 KB
/
colors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package transform
import (
"crypto/sha1"
"io"
"math/rand"
"github.com/prymitive/karma/internal/config"
"github.com/prymitive/karma/internal/models"
"github.com/prymitive/karma/internal/slices"
"github.com/hansrodtang/randomcolor"
plcolors "gopkg.in/go-playground/colors.v1"
log "github.com/sirupsen/logrus"
)
func labelToSeed(key string, val string) int64 {
h := sha1.New()
_, err := io.WriteString(h, key)
if err != nil {
log.Errorf("Failed to write label key '%s' to the seed sha1: %s", key, err)
}
_, err = io.WriteString(h, val)
if err != nil {
log.Errorf("Failed to write label value '%s' to the seed sha1: %s", val, err)
}
var seed int64
for _, i := range h.Sum(nil) {
seed += int64(i)
}
return seed
}
func rgbToBrightness(r, g, b uint8) int32 {
return ((int32(r) * 299) + (int32(g) * 587) + (int32(b) * 114)) / 1000
}
func parseCustomColor(colorStore models.LabelsColorMap, key, val, customColor string) {
color, err := plcolors.Parse(customColor)
if err != nil {
log.Warningf("Failed to parse custom color for %s=%s: %s", key, val, err)
return
}
rgb := color.ToRGB()
bc := models.Color{
Red: rgb.R,
Green: rgb.G,
Blue: rgb.B,
Alpha: 255,
}
brightness := rgbToBrightness(bc.Red, bc.Green, bc.Blue)
if _, found := colorStore[key]; !found {
colorStore[key] = make(map[string]models.LabelColors)
}
colorStore[key][val] = models.LabelColors{
Brightness: brightness,
Background: bc,
}
}
// ColorLabel update karmaColorMap object with a color object generated
// from label key and value passed here
// It's used to generate unique colors for configured labels
func ColorLabel(colorStore models.LabelsColorMap, key string, val string) {
// first handle custom colors
_, ok := config.Config.Labels.Color.Custom[key]
if ok {
for _, colorRule := range config.Config.Labels.Color.Custom[key] {
if colorRule.Value == val {
parseCustomColor(colorStore, key, val, colorRule.Color)
return
}
if colorRule.CompiledRegex != nil && colorRule.CompiledRegex.MatchString(val) {
parseCustomColor(colorStore, key, val, colorRule.Color)
return
}
}
}
// if no custom color is found then generate unique colors if needed
if slices.StringInSlice(config.Config.Labels.Color.Unique, key) {
if _, found := colorStore[key]; !found {
colorStore[key] = make(map[string]models.LabelColors)
}
if _, found := colorStore[key][val]; !found {
rand.Seed(labelToSeed(key, val))
color := randomcolor.New(randomcolor.Random, randomcolor.LIGHT)
red, green, blue, alpha := color.RGBA()
bc := models.Color{
Red: uint8(red >> 8),
Green: uint8(green >> 8),
Blue: uint8(blue >> 8),
Alpha: uint8(alpha >> 8),
}
// check if color is bright or dark and pick the right background
// uses https://www.w3.org/WAI/ER/WD-AERT/#color-contrast method
brightness := rgbToBrightness(bc.Red, bc.Green, bc.Blue)
colorStore[key][val] = models.LabelColors{
Brightness: brightness,
Background: bc,
}
}
}
}