Class: ColorPalette

Inherits:
Object
  • Object
show all
Defined in:
lib/jirametrics/color_palette.rb

Overview

Hands out colours for things that need to be told apart but where no specific colour is wanted. If a specific colour matters it should be configured, not obtained from here.

Two properties matter and neither is obvious from the call site:

  1. The colours have to stay distinguishable to people with colour vision deficiency. This started life as a genuinely random picker, which regularly produced pairs nobody could tell apart, so it is a curated set and must stay one. Do not "improve" it back into a generator.
  2. It returns CssVariable rather than a literal, so the colours follow the light and dark themes and can be overridden by a user's own stylesheet. Baked in hex can do neither.

The number of slots is read from the CSS rather than declared here, so adding a colour is a CSS edit and the count never becomes something the Ruby and the CSS have to agree on separately.

Constant Summary collapse

PALETTE_VARIABLE =
/--palette-color-(\d+)\s*:/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(css:) ⇒ ColorPalette

Returns a new instance of ColorPalette.



35
36
37
38
# File 'lib/jirametrics/color_palette.rb', line 35

def initialize css:
  @size = count_slots css
  @index = -1
end

Instance Attribute Details

#sizeObject (readonly)

Returns the value of attribute size.



19
20
21
# File 'lib/jirametrics/color_palette.rb', line 19

def size
  @size
end

Class Method Details

.defaultObject

For anything holding a chart on its own, outside a report run: tests, and any future standalone use. A report injects a shared instance so the whole page draws from one rotation, but nothing depends on that, because a caller who needs a SPECIFIC colour is supposed to configure it. A FRESH palette each call, not a shared singleton. The rotation is mutable state, so a memoised instance would leak position between charts and, worse, between test examples. Only the parsed stylesheet is cached, since that is the expensive part and it does not change.



27
28
29
# File 'lib/jirametrics/color_palette.rb', line 27

def self.default
  new css: shipped_css
end

.shipped_cssObject



31
32
33
# File 'lib/jirametrics/color_palette.rb', line 31

def self.shipped_css
  @shipped_css ||= File.read File.join(__dir__, 'html', 'index.css')
end

Instance Method Details

#next_colorObject

The next slot, cycling back to the first once they have all been used.



41
42
43
44
# File 'lib/jirametrics/color_palette.rb', line 41

def next_color
  @index += 1
  CssVariable["--palette-color-#{(@index % @size) + 1}"]
end