Создайте класс цветов и устройство сопоставления цветов для вашего приложения
Класс colors использует 147 именованных цветов, рекомендованных W3C, и к цветам легко добавить дополнительные атрибуты.
Я реализовывал некоторые графики с помощью Chart.js и мне нужно было передать цвета из моего приложения Flask в шаблон.
График является линейным, и количество линий может меняться. Вместе с графиком я также показываю таблицу с (числовыми) значениями, используемыми в графике.
Линии имеют разные цвета, я выбираю их из списка цветов. В таблице значений линий есть столбец для каждой линии. Я хочу, чтобы ячейка заголовка столбца была того же цвета, что и цвет линии.
В этот момент мне пришла в голову мысль создать класс цветов.
Цвет и названия цветов
Когда я начинал, я просто выбрал несколько цветов из найденного примера. Но в какой-то момент мне захотелось большей гибкости. В интернете есть спецификация 'CSS Color Module Level 3', см. ссылки ниже, которая дает список из 147 названий цветов, например:
- aliceblue
- антично-белый
- аква
- аквамарин
- лазурный
- бежевый
- биск
- чёрный
- и т.д.
Красиво.
Класс CSSColor
Я хотел, чтобы мои цвета были объектами типа
- css_colors.red
- css_colors.skyblue
с атрибутами:
- hex_code
- rgb_code
В коде Python цвет используется как:
css_colors.red.hex_code
css_colors.skyblue.hex_code
Два класса:
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)
Получите цвета в нашем классе
Перейдите на вышеупомянутую веб-страницу и скопируйте все 147 линий цветов, перетащив мышь по списку. Затем вставьте это в ваш любимый редактор. Это выглядит следующим образом:
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
Теперь в вашем редакторе используйте регулярные выражения для создания классов цветов. Мой редактор - Geany, и я использую следующее:
Искать:
^\s+(.*?)\s+(.*?)\s+(\d+),(\d+),(\d+)$
Заменить на:
CSSColor(name='\1', hex_code='\2', rgb_code='rgb(\3, \4, \5)'),
Результат:
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)'),
Теперь мы копируем это в класс 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)
Вот и все. Чтобы использовать цвета, мы инстанцируем объект:
css_colors = CSSColors()
Конечно, мы инстанцируем этот объект только один раз в нашем приложении. Теперь мы можем использовать цвета следующим образом:
css_colors.red
css_colors.red.hex_code
График с цветами линий
Но мы должны сделать больше. Я хочу большей гибкости и также добавить свои собственные имена цветов и атрибуты цветов. Вместо того чтобы использовать красный, синий и т.д., я хочу использовать такие имена цветов, как:
- линия1
- линия2
- ...
- линия9
И я хочу добавить имена классов, на которые я могу ссылаться в своих шаблонах Jinja HTML . Для этого я использую базовый класс:
css-class-background-<color>
, а затем добавляю к нему название цвета. В этом случае имя класса становится:
css-class-background-line1
Класс AppColors
Для нашего приложения мы создаем классы AppColor и AppColors. В классе AppColors мы создаем цвета линий для графиков, а также добавляем атрибут css_class_background_color к цветам линий.
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,
)
На самом деле здесь нет особой магии.
Использование цветов
Примеры использования цветов:
- цвет css
- список цветов
- цвет линии
- список цветов линии
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))
И вот результат:
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)
Обратите внимание, что цвета линий имеют дополнительный атрибут.
Для генерации классов стилей CSS в шаблоне Jinja HTML мы должны передать app_colors.chart_line_colors в шаблон:
return = render_template(
...
chart_line_colors=app_colors.chart_line_colors
)
В шаблоне мы итерируем цвета:
<style>
{%- for color in chart_line_colors -%}
.{{ color.css_class_background_color }} {
background-color: {{ color.hex_code }};
{%- endfor -%}
</style>
Результат:
.css-class-background-line1 {
background-color: #00ffff;
}
.css-class-background-line2 {
background-color: #ffff00;
}
.css-class-background-line3 {
background-color: #faebd7;
}
И, наконец, в нашем коде при генерации данных таблицы диаграмм для наборов данных линий мы добавляем CSS-классы цветов линий к заголовкам столбцов.
Использование класса цвета в Flask
При использовании этого в Flask мы изменяем наш класс AppColors и добавляем метод 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,
):
...
Затем в factory.py мы делаем что-то вроде:
app_colors = AppColors()
def create_app():
app = Flask()
...
app_colors.init_app(app)
Теперь мы можем использовать объект app_colors в нашем приложении (возможно, вы захотите сделать объект app_colors атрибутом объекта app).
Синий - не синий
Возможно, вы захотите использовать класс AppColors для других вещей, например, для всех ваших меню. Тогда у вас будет цвет фона, цвет текста, цвет границы и т.д. Обычно это задается в CSS, но вы также можете сделать это с помощью класса AppColor.
Вместо использования жестко закодированных значений вы определяете цвета, как указано выше, например:
- menu_text_color
- цвет_фона_меню
- цвет границы меню
Вы можете начать с черного цвета текста и позже изменить его на красный. В классе AppColor мы сопоставим цвета по своему вкусу.
Резюме
Для моего приложения с графиками мне нужны были цвета линий, которые можно легко изменить, а также экспортировать в шаблон Jinja HTML . Сначала я взял 147 цветов с веб-страницы 'CSS Color Module Level 3' и создал класс CCSColors. Следующим шагом было создание класса AppColors для моего приложения. Здесь я добавил новые именованные цвета, основанные на цветах CSSClass . Я также добавил атрибут (css_class) к новым цветам.
Ссылки / кредиты
CSS Color Module Level 3
https://www.w3.org/TR/css-color-3
Подробнее
Colors
Недавний
- Скрытие первичных ключей базы данных UUID вашего веб-приложения
- Don't Repeat Yourself (DRY) с Jinja2
- SQLAlchemy, PostgreSQL, максимальное количество строк для user
- Показать значения в динамических фильтрах SQLAlchemy
- Безопасная передача данных с помощью шифрования Public Key и pyNaCl
- rqlite: альтернатива dist с высокой степенью готовности и SQLite
Большинство просмотренных
- Используя Python pyOpenSSL для проверки SSL-сертификатов, загруженных с хоста
- Использование UUID вместо Integer Autoincrement Primary Keys с SQLAlchemy и MariaDb
- Подключение к службе на хосте Docker из контейнера Docker
- Использование PyInstaller и Cython для создания исполняемого файла Python
- SQLAlchemy: Использование Cascade Deletes для удаления связанных объектов
- Flask Удовлетворительный запрос API проверка параметров запроса с помощью схем Маршмэллоу