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.
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
Recientes
- Cómo ocultar las claves primarias de la base de datos UUID de su aplicación web
- Don't Repeat Yourself (DRY) con Jinja2
- SQLAlchemy, PostgreSQL, número máximo de filas por user
- Mostrar los valores en filtros dinámicos SQLAlchemy
- Transferencia de datos segura con cifrado de Public Key y pyNaCl
- rqlite: una alternativa de alta disponibilidad y dist distribuida SQLite
Más vistos
- Usando Python's pyOpenSSL para verificar los certificados SSL descargados de un host
- Usando UUIDs en lugar de Integer Autoincrement Primary Keys con SQLAlchemy y MariaDb
- Conectarse a un servicio en un host Docker desde un contenedor Docker
- Usando PyInstaller y Cython para crear un ejecutable de Python
- SQLAlchemy: Uso de Cascade Deletes para eliminar objetos relacionados
- Flask RESTful API validación de parámetros de solicitud con esquemas Marshmallow