angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

Maak een kleurenklasse en kleurenmapper voor uw toepassing

De colors class gebruikt 147 benoemde kleuren die door de W3C worden aanbevolen en het is gemakkelijk om extra attributen aan de kleuren toe te voegen.

27 november 2021
In Overige
post main image
https://pixabay.com/users/engin_akyurt-3656355/

Ik was een aantal grafieken aan het implementeren met Chart.js en moest kleuren doorgeven van mijn Flask applicatie naar de template.
De grafiek is een lijngrafiek en het aantal lijnen kan variëren. Met de grafiek toon ik ook een tabel met de (numerieke) waarden die in de grafiek zijn gebruikt.

De lijnen hebben verschillende kleuren, ik kies ze uit een lijst van kleuren. De tabel met lijnwaarden heeft voor elke lijn een kolom. Ik wil dat de header cell van een kolom dezelfde kleur heeft als de lijnkleur.

Dit was het moment dat ik dacht om een kleurenklasse te maken.

Kleur en kleurnamen

Toen ik begon koos ik gewoon wat kleuren uit een voorbeeld dat ik vond. Maar op een gegeven moment wilde ik meer flexibiliteit. Op het internet is er de 'CSS Color Module Level 3' specificatie, zie links hieronder, die je een lijst geeft van 147 benoemde kleuren, zoals:

  • aliceblue
  • antiquewit
  • aqua
  • aquamarijn
  • azuur
  • beige
  • bisque
  • zwart
  • enz.

Mooi.

De CSSKleur klasse

Ik wilde dat mijn kleuren objecten waren zoals:

  • css_colors.red
  • css_colors.skyblue

met attributen:

  • hex_code
  • rgb_code

In de code Python wordt de kleur gebruikt zoals:

css_colors.red.hex_code
css_colors.skyblue.hex_code

De twee klassen zijn:

class CSSColor:
    
    def __init__(
        self,
        name=None,
        hex_code=None,
        rgb_code=None,
    ):
        self.name = name
        self.hex_code = hex_code
        self.rgb_code = rgb_code

    def __repr__(self):
        return 'CSSColor({}, {}, {})'.format(self.name, self.hex_code, self.rgb_code)


class CSSColors:

    def __init__(
        self,
    ):
        self.colors = [
            # we put the colors here
            CSSColor( ... ),
            CSSColor( ... ),
            # more colors
            CSSColor( ... ),
        ]

        for color in colors:
            setattr(self, color.name, color)

Verkrijg de kleuren in onze klasse

Ga naar de webpagina hierboven en kopieer alle 147 kleurlijnen, door met de muis over de lijst te slepen. Plak dit vervolgens in je favoriete editor. Dit ziet er zo uit:

        aliceblue     #f0f8ff     240,248,255
        antiquewhite     #faebd7     250,235,215
        aqua     #00ffff     0,255,255
        aquamarine     #7fffd4     127,255,212
        ...
        yellow     #ffff00     255,255,0
        yellowgreen     #9acd32     154,205,50 

Gebruik nu in je editor reguliere expressies om de kleurklassen te maken. Mijn editor is Geany en ik gebruik het volgende:

Zoek op:

^\s+(.*?)\s+(.*?)\s+(\d+),(\d+),(\d+)$

Vervangen door:

CSSColor(name='\1', hex_code='\2', rgb_code='rgb(\3, \4, \5)'),

Het resultaat:

CSSColor(name='aliceblue', hex_code='#f0f8ff', rgb_code='rgb(240, 248, 255)'),
CSSColor(name='antiquewhite', hex_code='#faebd7', rgb_code='rgb(250, 235, 215)'),
CSSColor(name='aqua', hex_code='#00ffff', rgb_code='rgb(0, 255, 255)'),
CSSColor(name='aquamarine', hex_code='#7fffd4', rgb_code='rgb(127, 255, 212)'),
...
CSSColor(name='yellow', hex_code='#ffff00', rgb_code='rgb(255, 255, 0)'),
CSSColor(name='yellowgreen', hex_code='#9acd32', rgb_code='rgb(154,205,50)'),

Nu kopiëren we dit naar de CSSColors klasse:

class CSSColors:

    def __init__(
        self,
    ):
        self.colors = [
            CSSColor(name='aliceblue', hex_code='#f0f8ff', rgb_code='rgb(240, 248, 255)'),
            CSSColor(name='antiquewhite', hex_code='#faebd7', rgb_code='rgb(250, 235, 215)'),
            CSSColor(name='aqua', hex_code='#00ffff', rgb_code='rgb(0, 255, 255)'),
            CSSColor(name='aquamarine', hex_code='#7fffd4', rgb_code='rgb(127, 255, 212)'),
            # more colors
            CSSColor(name='yellow', hex_code='#ffff00', rgb_code='rgb(255, 255, 0)'),
            CSSColor(name='yellowgreen', hex_code='#9acd32', rgb_code='rgb(154,205,50)'),
        ]
        for color in self.colors:
            # make color an attribute of this object
            setattr(self, color.name, color)

Dat is het. Om de kleuren te gebruiken instantiëren we het object:

css_colors = CSSColors()

Natuurlijk instantiëren we dit object maar één keer in onze applicatie. Nu kunnen we de kleuren gebruiken zoals:

css_colors.red
css_colors.red.hex_code

Een grafiek met lijnkleuren

Maar we moeten meer doen. Ik wil meer flexibiliteit en ook mijn eigen kleurnamen en kleur-attributen toevoegen. In plaats van rood, blauw, enz. te gebruiken, wil ik kleurnamen als:

  • lijn1
  • lijn2
  • ...
  • lijn9

En ik wil klasse-namen toevoegen waarnaar ik kan verwijzen in mijn Jinja HTML sjablonen. Hiervoor gebruik ik een basisklasse

css-class-background-<color>

en voeg daar vervolgens de kleurnaam aan toe. De klasse naam wordt in dit geval:

css-class-background-line1

De klasse AppColors

Voor onze applicatie maken we AppColor en AppColors classes aan. In de AppColors klasse maken we lijnkleuren voor de grafieken en we voegen ook het css_class_background_color attribuut toe aan de lijnkleuren.

class AppColor(CSSColor):

    def __repr__(self):
        return 'AppColor({}, {}, {}, {})'.\
        format(self.name, self.hex_code, self.rgb_code, getattr(self, 'css_class_background_color', None))


class AppColors(CSSColors):

    def __init__(
        self,
        css_class_background_color_template=None,
    ):
        CSSColors.__init__(self)

        # use specified css_class or use default
        self.css_class_background_color_template = css_class_background_color_template or 'css-class-background-'

        # here we can change / add colors
        self.chart_line_colors = [
            self.new_app_color(name='line1', color=self.aqua),
            self.new_app_color(name='line2', color=self.yellow),
            # more colors
            self.new_app_color(name='line3', color=self.antiquewhite),
        ]

        # add the new colors to object
        for color in self.chart_line_colors:
            # add css class attribute to color
            setattr(color, 'css_class_background_color', self.css_class_background_color_template + color.name)
            # make color an attribute of this object
            setattr(self, color.name, color)

    def new_app_color(
        self,
        name=None,
        color=None,
    ):
        return AppColor(
            name=name or color.name,
            hex_code=color.hex_code,
            rgb_code=color.rgb_code,
        )

Er is niet echt veel magie hier.

Gebruik van de kleuren

Voorbeelden van hoe de kleuren te gebruiken:

  • een css kleur
  • de kleuren lijst
  • een lijnkleur
  • de lijn kleuren lijst
app_colors = AppColors()

print('\nuse a css color:')
print('app_colors.aqua.hex_code = {}'.format(app_colors.aqua.hex_code))
print('app_colors.yellow.hex_code = {}'.format(app_colors.yellow.hex_code))

print('\nuse the colors list:')
for color in app_colors.colors:
    print('{}'.format(color))

print('\nuse a line color:')
print('app_colors.line2.hex_code = {}'.format(app_colors.line2.hex_code))
print('app_colors.line2.css_class_background_color = {}'.format(app_colors.line2.css_class_background_color))

print('\nuse the line colors list:')
for color in app_colors.chart_line_colors:
    print('{}'.format(color))

En het resultaat is:

use a css color:
app_colors.aqua.hex_code = #00ffff
app_colors.yellow.hex_code = #ffff00

use the colors list:
CSSColor(aliceblue, #f0f8ff, rgb(240, 248, 255))
CSSColor(antiquewhite, #faebd7, rgb(250, 235, 215))
CSSColor(aqua, #00ffff, rgb(0, 255, 255))
CSSColor(aquamarine, #7fffd4, rgb(127, 255, 212))
CSSColor(yellow, #ffff00, rgb(255, 255, 0))
CSSColor(yellowgreen, #9acd32, rgb(154,205,50))

use a line color:
app_colors.line2.hex_code = #ffff00
app_colors.line2.css_class_background_color = css-class-background-line2

use the line colors list:
AppColor(line1, #00ffff, rgb(0, 255, 255), css-class-background-line1)
AppColor(line2, #ffff00, rgb(255, 255, 0), css-class-background-line2)
AppColor(line3, #faebd7, rgb(250, 235, 215), css-class-background-line3)

Merk op dat de lijnkleuren een extra attribuut hebben.

Om de CSS stijl klassen in het Jinja sjabloon te genereren moeten we app_colors.chart_line_colors aan het sjabloon doorgeven:

return = render_template(
    ...
    chart_line_colors=app_colors.chart_line_colors    
)

In het sjabloon itereren we de kleuren:

<style>
{%- for color in chart_line_colors -%}
.{{ color.css_class_background_color }} {
    background-color: {{ color.hex_code }};
{%- endfor -%}
</style>

Het resultaat:

.css-class-background-line1 {
    background-color: #00ffff;
}
.css-class-background-line2 {
    background-color: #ffff00;
}
.css-class-background-line3 {
    background-color: #faebd7;
}

En dan uiteindelijk in onze code bij het genereren van de grafiek tabel gegevens voor de lijn datasets voegen we de CSS klassen van de lijn kleuren toe aan de kolomkoppen.

Gebruik van de kleurklasse in Flask

Wanneer we deze in Flask gebruiken passen we onze AppColors klasse aan en voegen een init_app() methode toe.

class AppColors:

    def __init__(
        self,
        app=None,
    ):
        self.css_class_background_color_template = 'css-class-background-'

    def init_app(
        self,
        app=None,
        css_class_background_color_template=None,
    ):
    ...

Dan doen we in factory.py zoiets als:

app_colors = AppColors()

def create_app():

    app = Flask()
    ...
    app_colors.init_app(app)

Nu kunnen we het app_colors object gebruiken in onze applicatie (misschien wil je het app_colors object een attribuut maken van het app object).

Blauw is niet blauw

Misschien wil je de AppColors klasse ook gebruiken voor andere dingen, zoals al je menu's. Dan heb je een achtergrondkleur, tekstkleur, randkleur, enz. Meestal regel je dit in CSS maar je kunt dit ook doen met de AppColor klasse.

In plaats van hardcoded waarden te gebruiken definieer je kleuren zoals hierboven zoals:

  • menu_text_color
  • menu_achtergrond_kleur
  • menu_rand_kleur

Je kunt beginnen met tekstkleur is zwart en dit later veranderen in rood. In de AppColor klasse brengen we de kleuren in kaart naar onze smaak.

Samenvatting

Voor mijn applicatie met grafieken wilde ik lijnkleuren die gemakkelijk kunnen worden veranderd en ook kunnen worden geëxporteerd naar de Jinja HTML template. Eerst heb ik 147 kleuren geschraapt van de webpagina 'CSS Color Module Level 3' en een CCSColors klasse aangemaakt. De volgende stap was het aanmaken van een AppColors klasse voor mijn applicatie. Hier heb ik nieuwe benoemde kleuren toegevoegd gebaseerd op de CSSClass kleuren . Ik heb ook een (css_class) attribuut toegevoegd aan de nieuwe kleuren.

Links / credits

CSS Color Module Level 3
https://www.w3.org/TR/css-color-3

Lees meer

Colors

Laat een reactie achter

Reageer anoniem of log in om commentaar te geven.

Opmerkingen

Laat een antwoord achter

Antwoord anoniem of log in om te antwoorden.