Skip to content

Commit

Permalink
feat: find the closed color in ColorPalette (pinterest#1184)
Browse files Browse the repository at this point in the history
* feat: find the closed color in ColorPalette

* comments

* add back _asdict

* move color palette to yaml

* jest to load yaml

* remove hex color check

* move js-yaml to dev dependency
  • Loading branch information
jczhong84 authored and aidenprice committed Jan 3, 2024
1 parent e9db8f1 commit 9dd64ea
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 55 deletions.
2 changes: 2 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const config = {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
'.*\\.(css|less|scss)$': '<rootDir>/__mocks__/styleMock.js',
'config/color_palette.yaml': '<rootDir>/../config/color_palette.yaml',
},
moduleDirectories: [
'node_modules', // This is required
Expand All @@ -22,6 +23,7 @@ const config = {
transform: {
'^.+\\.(jsx|js|ts|tsx)$': 'babel-jest',
'\\.m?js?$': 'jest-esm-transformer',
'\\.(yaml|yml)$': '<rootDir>/jest/yaml-transformer.js',
},
};

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
"eslint-plugin-unused-imports": "^2.0.0",
"jest": "26.6.3",
"jest-esm-transformer": "^1.0.0",
"js-yaml": "^4.1.0",
"postcss-loader": "^6.1.0",
"postcss-preset-env": "6.7.0",
"prettier": "2.7.1",
Expand Down
48 changes: 48 additions & 0 deletions querybook/config/color_palette.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
- name: blue
color: '#35B5BB'
fillColor: rgba(53, 181, 187, 0.25)
- name: pink
color: '#ff3975'
fillColor: rgba(255, 57, 117, 0.25)
- name: grey
color: '#bfbfbf'
fillColor: rgba(191, 191, 191, 0.25)
- name: gold
color: '#ffca00'
fillColor: rgba(255, 202, 0, 0.25)
- name: picton blue
color: '#529dce'
fillColor: rgba(82, 157, 206, 0.25)
- name: orange
color: '#ff9f42'
fillColor: rgba(255, 159, 66, 0.25)
- name: creamy forest green
color: '#6ba097'
fillColor: rgba(107, 160, 151, 0.25)
- name: chartreuse
color: '#aee800'
fillColor: rgba(174, 232, 0, 0.25)
- name: baby pink
color: '#ff91c8'
fillColor: rgba(255, 145, 200, 0.25)
- name: icy blue
color: '#85d0ce'
fillColor: rgba(133, 208, 206, 0.25)
- name: fuscia
color: '#eb37ce'
fillColor: rgba(235, 55, 206, 0.25)
- name: light purple
color: '#C792EA'
fillColor: rgba(199, 146, 234, 0.25)
- name: salmon
color: '#ec7f77'
fillColor: rgba(236, 127, 119, 0.25)
- name: olive
color: '#989801'
fillColor: rgba(152, 152, 1, 0.25)
- name: beige
color: '#ecd1af'
fillColor: rgba(236, 209, 175, 0.25)
- name: choco
color: '#b7652b'
fillColor: rgba(183, 101, 43, 0.25)
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = 'ec2f32c25f34'
Expand Down
8 changes: 8 additions & 0 deletions querybook/server/const/color.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from typing import TypedDict


class PaletteColor(TypedDict):
name: str
# color in hex format, e.g. #4287f5
color: str
fillColor: str
1 change: 1 addition & 0 deletions querybook/server/const/metastore.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class DataTag(NamedTuple):
# below properties will be stored in tag.meta
type: str = None
description: str = None
# color in hex format, e.g. #4287f5
color: str = None


Expand Down
44 changes: 44 additions & 0 deletions querybook/server/lib/utils/color.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import math

from const.color import PaletteColor
from lib.config import get_config_value


color_palette = get_config_value("color_palette")


def convert_hex_to_rgb(hex_color: str) -> tuple[int, int, int]:
r = int(hex_color[1:3], 16)
g = int(hex_color[3:5], 16)
b = int(hex_color[5:7], 16)
return (r, g, b)


def find_nearest_palette_color(hex_color: str) -> PaletteColor:
"""Given a hex color, find the nearest color from the color palette."""
# Return the given color if it's in the color palette
exact_color = next(
(color for color in color_palette if color["color"] == "#529dce"), None
)
if exact_color:
return exact_color

# Convert the hex color to RGB
given_rgb_color = convert_hex_to_rgb(hex_color)

# Calculate the Euclidean distance between the given color and each color in the palette
min_distance = math.inf
nearest_color = None
for color in color_palette:
platte_hex_color = color["color"]
palette_rgb_color = convert_hex_to_rgb(platte_hex_color)
distance = (
(given_rgb_color[0] - palette_rgb_color[0]) ** 2
+ (given_rgb_color[1] - palette_rgb_color[1]) ** 2
+ (given_rgb_color[2] - palette_rgb_color[2]) ** 2
)
if distance < min_distance:
min_distance = distance
nearest_color = color

return nearest_color
3 changes: 3 additions & 0 deletions querybook/server/lib/utils/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ def __init__(self, *args, **kwargs):
def default(self, obj): # pylint: disable=E0202
if hasattr(obj, "to_dict"):
return obj.to_dict()
# check for NamedTuple
elif isinstance(obj, tuple) and hasattr(obj, "_fields"):
return obj._asdict()
elif isinstance(obj, datetime):
return self.datetime_formatter(obj)
elif isinstance(obj, date):
Expand Down
5 changes: 3 additions & 2 deletions querybook/server/logic/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from app.db import with_session
from const.metastore import DataTag
from lib.utils.color import find_nearest_palette_color
from logic.metastore import update_es_tables_by_id
from models.tag import Tag, TagItem

Expand Down Expand Up @@ -119,7 +120,7 @@ def create_table_tags(
meta = {
"type": tag.type,
"tooltip": tag.description,
"color": tag.color,
"color": find_nearest_palette_color(tag.color)["name"],
"admin": True,
}
# filter out properties with none values
Expand Down Expand Up @@ -157,7 +158,7 @@ def create_column_tags(
meta = {
"type": tag.type,
"tooltip": tag.description,
"color": tag.color,
"color": find_nearest_palette_color(tag.color)["name"],
"admin": True,
}
# filter out properties with none values
Expand Down
2 changes: 1 addition & 1 deletion querybook/server/models/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def to_dict(self):
"id": self.id,
"name": self.name,
"config": loader_class.loader_config.to_dict(),
"owner_types": loader_class.get_table_owner_types(),
"owner_types": [t._asdict() for t in loader_class.get_table_owner_types()],
}

def to_dict_admin(self):
Expand Down
9 changes: 9 additions & 0 deletions querybook/webapp/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,12 @@ declare module 'config/query_error.yaml' {
>;
export default data;
}

declare module 'config/color_palette.yaml' {
const data: Array<{
name: string;
color: string;
fillColor: string;
}>;
export default data;
}
54 changes: 3 additions & 51 deletions querybook/webapp/const/chartColors.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,6 @@
interface IColorPalette {
name: string;
color: string;
fillColor: string;
}
export const ColorPalette: IColorPalette[] = [
{ name: 'blue', color: '#35B5BB', fillColor: 'rgba(53, 181, 187, 0.25)' },
{ name: 'pink', color: '#ff3975', fillColor: 'rgba(255, 57, 117, 0.25)' },
{ name: 'grey', color: '#bfbfbf', fillColor: 'rgba(191, 191, 191, 0.25)' },
{ name: 'gold', color: '#ffca00', fillColor: 'rgba(255, 202, 0, 0.25)' },
{
name: 'picton blue',
color: '#529dce',
fillColor: 'rgba(82, 157, 206, 0.25)',
},
{ name: 'orange', color: '#ff9f42', fillColor: 'rgba(255, 159, 66, 0.25)' },
{
name: 'creamy forest green',
color: '#6ba097',
fillColor: 'rgba(107, 160, 151, 0.25)',
},
{
name: 'chartreuse',
color: '#aee800',
fillColor: 'rgba(174, 232, 0, 0.25)',
},
{
name: 'baby pink',
color: '#ff91c8',
fillColor: 'rgba(255, 145, 200, 0.25)',
},
{
name: 'icy blue',
color: '#85d0ce',
fillColor: 'rgba(133, 208, 206, 0.25)',
},
{ name: 'fuscia', color: '#eb37ce', fillColor: 'rgba(235, 55, 206, 0.25)' },
{
name: 'light purple',
color: '#C792EA',
fillColor: 'rgba(199, 146, 234, 0.25)',
},
{
name: 'salmon',
color: '#ec7f77',
fillColor: 'rgba(236, 127, 119, 0.25)',
},
{ name: 'olive', color: '#989801', fillColor: 'rgba(152, 152, 1, 0.25)' },
{ name: 'beige', color: '#ecd1af', fillColor: 'rgba(236, 209, 175, 0.25)' },
{ name: 'choco', color: '#b7652b', fillColor: 'rgba(183, 101, 43, 0.25)' },
];
import colorPalette from 'config/color_palette.yaml';

export const ColorPalette = colorPalette;

// rgb for css vars - font
export const fontColor = {
Expand Down
11 changes: 11 additions & 0 deletions querybook/webapp/jest/yaml-transformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const yaml = require('js-yaml');

module.exports = {
process: (src, filename) => {
if (filename.endsWith('.yaml') || filename.endsWith('.yml')) {
const data = yaml.load(src);
return `module.exports = ${JSON.stringify(data)};`;
}
return src;
},
};

0 comments on commit 9dd64ea

Please sign in to comment.