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

Cree una clase de colores y un mapeador de colores para su aplicación

La clase colors utiliza 147 colores con nombre recomendados por el W3C y es fácil añadir atributos adicionales a los colores.

27 noviembre 2021
En Otros
post main image
https://pixabay.com/users/engin_akyurt-3656355/

Estaba implementando unos gráficos con Chart.js y necesitaba pasar los colores de mi aplicación Flask a la plantilla.
El gráfico es de líneas y el número de líneas puede variar. Con el gráfico también muestro una tabla con los valores (numéricos) utilizados en el gráfico.

Las líneas tienen diferentes colores, los elijo de una lista de colores. La tabla de valores de las líneas tiene una columna para cada línea. Quiero que la celda de cabecera de una columna sea del mismo color que el color de la línea.

Este fue el momento en que pensé en crear una clase de color.

Color y nombres de colores

Cuando empecé sólo elegí algunos colores de un ejemplo que encontré. Pero en cierto momento quise más flexibilidad. En internet existe la especificación 'CSS Color Module Level 3', ver enlaces más abajo, que te da una lista de 147 colores con nombre, como

  • aliceblue
  • antiquewhite
  • aqua
  • aguamarina
  • azul
  • beige
  • bisque
  • negro
  • etc.

Muy bien.

La clase CSSColor

Quería que mis colores fueran objetos como

  • css_colors.red
  • css_colors.skyblue

con atributos:

  • hex_code
  • rgb_code

En el código Python el color se utiliza como:

css_colors.red.hex_code
css_colors.skyblue.hex_code

Las dos clases son:

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)

Obtener los colores de nuestra clase

Ve a la página web mencionada anteriormente y copia las 147 líneas de color, arrastrando el ratón sobre la lista. Luego pegue esto en su editor favorito. Esto se ve así:

        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 

Ahora en tu editor, utiliza expresiones regulares para crear las clases de color. Mi editor es Geany y uso lo siguiente:

Buscar:

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

Reemplazar con:

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

El resultado:

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)'),

Ahora copiamos esto en la clase CSSColors:

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)

Eso es todo. Para usar los colores instanciamos el objeto:

css_colors = CSSColors()

Por supuesto, instanciamos este objeto sólo una vez en nuestra aplicación. Ahora podemos usar los colores como:

css_colors.red
css_colors.red.hex_code

Un gráfico con colores de líneas

Pero debemos hacer más. Quiero más flexibilidad y también añadir mis propios nombres de color y atributos de color. En lugar de usar rojo, azul, etc., quiero nombres de colores como

  • línea1
  • línea2
  • ...
  • línea9

Y quiero añadir nombres de clase a los que pueda referirme en mis plantillas Jinja HTML . Para ello utilizo una clase base

css-class-background-<color>

y luego le añado el nombre del color. El nombre de la clase se convierte en este caso:

css-class-background-line1

La clase AppColors

Para nuestra aplicación creamos las clases AppColor y AppColors. En la clase AppColors creamos colores de línea para los gráficos y también añadimos el atributo css_class_background_color a los colores de línea.

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,
        )

Realmente no hay mucha magia aquí.

Uso de los colores

Ejemplos de cómo utilizar los colores:

  • un color css
  • la lista de colores
  • un color de línea
  • la lista de colores de la línea
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))

Y el resultado es:

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)

Nótese que los colores de línea tienen un atributo extra.

Para generar las clases de estilo CSS en la plantilla Jinja HTML debemos pasar app_colors.chart_line_colors a la plantilla:

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

En la plantilla iteramos los colores:

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

El resultado:

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

Y finalmente en nuestro código al generar los datos de la tabla del gráfico para los conjuntos de datos de líneas añadimos las clases CSS de los colores de las líneas a las cabeceras de las columnas.

Usando la clase de color en Flask

Al usar esto en Flask modificamos nuestra clase AppColors y añadimos un método init_app().

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,
    ):
    ...

Luego en factory.py hacemos algo así:

app_colors = AppColors()

def create_app():

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

Ahora podemos usar el objeto app_colors en nuestra aplicación (quizás quieras hacer del objeto app_colors un atributo del objeto app).

El azul no es azul

Es posible que quieras usar la clase AppColors para otras cosas como todos tus menús. Entonces tienes un color de fondo, un color de texto, un color de borde, etc. Por lo general, usted arregla esto en CSS, pero también puede hacerlo con la clase AppColor.

En lugar de utilizar valores codificados, se definen los colores como en el caso anterior:

  • menu_text_color
  • menu_background_color
  • menu_border_color

Usted puede comenzar con el color del texto es negro y más tarde cambiar esto a rojo. En la clase AppColor asignamos los colores a nuestro gusto.

Resumen

Para mi aplicación con gráficos quería colores de línea que se pueden cambiar fácilmente y también se puede exportar a la plantilla Jinja HTML . En primer lugar, extraje 147 colores de la página web 'CSS Color Module Level 3' y creé una clase CCSColors. El siguiente paso fue crear una clase AppColors para mi aplicación. Aquí añadí nuevos colores con nombre basados en los colores CSSClass . También añadí un atributo (css_class) a los nuevos colores.

Enlaces / créditos

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

Leer más

Colors

Deje un comentario

Comente de forma anónima o inicie sesión para comentar.

Comentarios

Deje una respuesta.

Responda de forma anónima o inicie sesión para responder.