topologicpy 0.5.9__py3-none-any.whl → 6.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- topologicpy/Aperture.py +72 -72
- topologicpy/Cell.py +2169 -2169
- topologicpy/CellComplex.py +1137 -1137
- topologicpy/Cluster.py +1288 -1280
- topologicpy/Color.py +423 -423
- topologicpy/Context.py +79 -79
- topologicpy/DGL.py +3213 -3240
- topologicpy/Dictionary.py +698 -698
- topologicpy/Edge.py +1187 -1187
- topologicpy/EnergyModel.py +1180 -1152
- topologicpy/Face.py +2141 -2141
- topologicpy/Graph.py +7768 -7768
- topologicpy/Grid.py +353 -353
- topologicpy/Helper.py +507 -507
- topologicpy/Honeybee.py +461 -461
- topologicpy/Matrix.py +271 -271
- topologicpy/Neo4j.py +521 -521
- topologicpy/Plotly.py +2 -2
- topologicpy/Polyskel.py +541 -541
- topologicpy/Shell.py +1768 -1768
- topologicpy/Speckle.py +508 -508
- topologicpy/Topology.py +7060 -7002
- topologicpy/Vector.py +905 -905
- topologicpy/Vertex.py +1585 -1585
- topologicpy/Wire.py +3050 -3050
- topologicpy/__init__.py +22 -38
- topologicpy/version.py +1 -0
- {topologicpy-0.5.9.dist-info → topologicpy-6.0.0.dist-info}/LICENSE +661 -704
- topologicpy-6.0.0.dist-info/METADATA +751 -0
- topologicpy-6.0.0.dist-info/RECORD +32 -0
- topologicpy/bin/linux/topologic/__init__.py +0 -2
- topologicpy/bin/linux/topologic/libTKBO-6bdf205d.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKBRep-2960a069.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKBool-c44b74bd.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKFillet-9a670ba0.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKG2d-8f31849e.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKG3d-4c6bce57.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKGeomAlgo-26066fd9.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKGeomBase-2116cabe.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKMath-72572fa8.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKMesh-2a060427.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKOffset-6cab68ff.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKPrim-eb1262b3.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKShHealing-e67e5cc7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKTopAlgo-e4c96c33.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKernel-fb7fe3b7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libgcc_s-32c1665e.so.1 +0 -0
- topologicpy/bin/linux/topologic/libstdc++-672d7b41.so.6.0.30 +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-310-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-311-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-38-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-39-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBO-6bdf205d.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBRep-2960a069.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBool-c44b74bd.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKFillet-9a670ba0.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKG2d-8f31849e.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKG3d-4c6bce57.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKGeomAlgo-26066fd9.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKGeomBase-2116cabe.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKMath-72572fa8.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKMesh-2a060427.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKOffset-6cab68ff.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKPrim-eb1262b3.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKShHealing-e67e5cc7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKTopAlgo-e4c96c33.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKernel-fb7fe3b7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libgcc_s-32c1665e.so.1 +0 -0
- topologicpy/bin/linux/topologic.libs/libstdc++-672d7b41.so.6.0.30 +0 -0
- topologicpy/bin/macos/topologic/__init__.py +0 -2
- topologicpy/bin/windows/topologic/TKBO-f6b191de.dll +0 -0
- topologicpy/bin/windows/topologic/TKBRep-e56a600e.dll +0 -0
- topologicpy/bin/windows/topologic/TKBool-7b8d47ae.dll +0 -0
- topologicpy/bin/windows/topologic/TKFillet-0ddbf0a8.dll +0 -0
- topologicpy/bin/windows/topologic/TKG2d-2e2dee3d.dll +0 -0
- topologicpy/bin/windows/topologic/TKG3d-6674513d.dll +0 -0
- topologicpy/bin/windows/topologic/TKGeomAlgo-d240e370.dll +0 -0
- topologicpy/bin/windows/topologic/TKGeomBase-df87aba5.dll +0 -0
- topologicpy/bin/windows/topologic/TKMath-45bd625a.dll +0 -0
- topologicpy/bin/windows/topologic/TKMesh-d6e826b1.dll +0 -0
- topologicpy/bin/windows/topologic/TKOffset-79b9cc94.dll +0 -0
- topologicpy/bin/windows/topologic/TKPrim-aa430a86.dll +0 -0
- topologicpy/bin/windows/topologic/TKShHealing-bb48be89.dll +0 -0
- topologicpy/bin/windows/topologic/TKTopAlgo-7d0d1e22.dll +0 -0
- topologicpy/bin/windows/topologic/TKernel-08c8cfbb.dll +0 -0
- topologicpy/bin/windows/topologic/__init__.py +0 -2
- topologicpy/bin/windows/topologic/topologic.cp310-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp311-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp38-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp39-win_amd64.pyd +0 -0
- topologicpy-0.5.9.dist-info/METADATA +0 -86
- topologicpy-0.5.9.dist-info/RECORD +0 -91
- {topologicpy-0.5.9.dist-info → topologicpy-6.0.0.dist-info}/WHEEL +0 -0
- {topologicpy-0.5.9.dist-info → topologicpy-6.0.0.dist-info}/top_level.txt +0 -0
topologicpy/Color.py
CHANGED
@@ -1,423 +1,423 @@
|
|
1
|
-
# Copyright (C) 2024
|
2
|
-
# Wassim Jabi <wassim.jabi@gmail.com>
|
3
|
-
#
|
4
|
-
# This program is free software: you can redistribute it and/or modify it under
|
5
|
-
# the terms of the GNU Affero General Public License as published by the Free Software
|
6
|
-
# Foundation, either version 3 of the License, or (at your option) any later
|
7
|
-
# version.
|
8
|
-
#
|
9
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
10
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
11
|
-
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
12
|
-
# details.
|
13
|
-
#
|
14
|
-
# You should have received a copy of the GNU Affero General Public License along with
|
15
|
-
# this program. If not, see <https://www.gnu.org/licenses/>.
|
16
|
-
|
17
|
-
import plotly.colors
|
18
|
-
import math
|
19
|
-
|
20
|
-
class Color:
|
21
|
-
@staticmethod
|
22
|
-
def ByCSSNamedColor(color, alpha: float = None):
|
23
|
-
"""
|
24
|
-
Creates a Color from a CSS named color string. See https://developer.mozilla.org/en-US/docs/Web/CSS/named-color
|
25
|
-
|
26
|
-
Parameters
|
27
|
-
----------
|
28
|
-
color : str
|
29
|
-
A CSS named color.
|
30
|
-
alpha : float , optional
|
31
|
-
THe desired alpha (transparency value). The default is None which means no alpha value will be included in the returned list.
|
32
|
-
|
33
|
-
Returns
|
34
|
-
-------
|
35
|
-
list
|
36
|
-
The color expressed as an [r, g, b] or an [r, g, b, a] list.
|
37
|
-
"""
|
38
|
-
import warnings
|
39
|
-
import os
|
40
|
-
try:
|
41
|
-
import webcolors
|
42
|
-
except:
|
43
|
-
print("Color.ByCSSNamedColor - Information: Installing required webcolors library.")
|
44
|
-
try:
|
45
|
-
os.system("pip install webcolors")
|
46
|
-
except:
|
47
|
-
os.system("pip install webcolors --user")
|
48
|
-
try:
|
49
|
-
import webcolors
|
50
|
-
print("Color.ByCSSNamedColor - Information: webcolors library installed correctly.")
|
51
|
-
except:
|
52
|
-
warnings.warn("Color.ByCSSNamedColor - Error: Could not import webcolors library. Please manually install webcolors. Returning None.")
|
53
|
-
return None
|
54
|
-
|
55
|
-
if not alpha == None:
|
56
|
-
if not 0.0 <= alpha <= 1.0:
|
57
|
-
print("Color.ByCSSNamedColor - Error: alpha is not within the valid range of 0 to 1. Returning None.")
|
58
|
-
return None
|
59
|
-
try:
|
60
|
-
# Get RGB values from the named CSS color
|
61
|
-
rgbList = list(webcolors.name_to_rgb(color))
|
62
|
-
if not alpha == None:
|
63
|
-
rgbList.append(alpha)
|
64
|
-
return rgbList
|
65
|
-
|
66
|
-
except ValueError:
|
67
|
-
print(f"Color.ByCSSNamedColor - Error: '{color}' is not a valid named CSS color. Returning None.")
|
68
|
-
return None
|
69
|
-
|
70
|
-
@staticmethod
|
71
|
-
def ByHEX(hex: str, alpha: float = None):
|
72
|
-
"""
|
73
|
-
Converts a hexadecimal color string to RGB color values.
|
74
|
-
|
75
|
-
Parameters
|
76
|
-
----------
|
77
|
-
hex : str
|
78
|
-
A hexadecimal color string in the format '#RRGGBB'.
|
79
|
-
alpha : float , optional
|
80
|
-
The transparency value. 0.0 means the color is fully transparent, 1.0 means the color is fully opaque. The default is None
|
81
|
-
which means no transparency value will be included in the returned color.
|
82
|
-
Returns
|
83
|
-
-------
|
84
|
-
list
|
85
|
-
The color expressed as an [r, g, b] or an [r, g, b, a] list.
|
86
|
-
|
87
|
-
"""
|
88
|
-
if not isinstance(hex, str):
|
89
|
-
print("Color.HEXtoRGB - Error: The input hex parameter is not a valid string. Returning None.")
|
90
|
-
return None
|
91
|
-
if not alpha == None:
|
92
|
-
if not 0.0 <= alpha <= 1.0:
|
93
|
-
print("Color.ByHEX - Error: alpha is not within the valid range of 0 to 1. Returning None.")
|
94
|
-
return None
|
95
|
-
hex = hex.lstrip('#')
|
96
|
-
if len(hex) != 6:
|
97
|
-
print("Color.HEXtoRGB - Error: Invalid hexadecimal color format. It should be a 6-digit hex value. Returning None.")
|
98
|
-
return None
|
99
|
-
r = int(hex[0:2], 16)
|
100
|
-
g = int(hex[2:4], 16)
|
101
|
-
b = int(hex[4:6], 16)
|
102
|
-
rgbList = [r, g, b]
|
103
|
-
if not alpha == None:
|
104
|
-
rgbList.append(alpha)
|
105
|
-
return rgbList
|
106
|
-
|
107
|
-
@staticmethod
|
108
|
-
def ByValueInRange(value: float = 0.5, minValue: float = 0.0, maxValue: float = 1.0, alpha: float = None, colorScale="viridis"):
|
109
|
-
"""
|
110
|
-
Returns the r, g, b, (and optionally) a list of numbers representing the red, green, blue and alpha color elements.
|
111
|
-
|
112
|
-
Parameters
|
113
|
-
----------
|
114
|
-
value : float , optional
|
115
|
-
The input value. The default is 0.5.
|
116
|
-
minValue : float , optional
|
117
|
-
the input minimum value. The default is 0.0.
|
118
|
-
maxValue : float , optional
|
119
|
-
The input maximum value. The default is 1.0.
|
120
|
-
alpha : float , optional
|
121
|
-
The alpha (transparency) value. 0.0 means the color is fully transparent, 1.0 means the color is fully opaque. The default is 1.0.
|
122
|
-
useAlpha : bool , optional
|
123
|
-
If set to True, the returns list includes the alpha value as a fourth element in the list.
|
124
|
-
colorScale : str , optional
|
125
|
-
The desired type of plotly color scales to use (e.g. "Viridis", "Plasma"). The default is "Viridis". For a full list of names, see https://plotly.com/python/builtin-colorscales/.
|
126
|
-
|
127
|
-
Returns
|
128
|
-
-------
|
129
|
-
list
|
130
|
-
The color expressed as an [r, g, b] or an [r, g, b, a] list.
|
131
|
-
|
132
|
-
"""
|
133
|
-
if not alpha == None:
|
134
|
-
if not 0.0 <= alpha <= 1.0:
|
135
|
-
print("Color.ByValueInRange - Error: alpha is not within the valid range of 0 to 1. Returning None.")
|
136
|
-
return None
|
137
|
-
# Code based on: https://stackoverflow.com/questions/62710057/access-color-from-plotly-color-scale
|
138
|
-
|
139
|
-
def hex_to_rgb(value):
|
140
|
-
value = str(value)
|
141
|
-
value = value.lstrip('#')
|
142
|
-
lv = len(value)
|
143
|
-
returnValue = tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))
|
144
|
-
return str(returnValue)
|
145
|
-
|
146
|
-
def get_color(colorscale_name, loc):
|
147
|
-
from _plotly_utils.basevalidators import ColorscaleValidator
|
148
|
-
# first parameter: Name of the property being validated
|
149
|
-
# second parameter: a string, doesn't really matter in our use case
|
150
|
-
cv = ColorscaleValidator("colorscale", "")
|
151
|
-
# colorscale will be a list of lists: [[loc1, "rgb1"], [loc2, "rgb2"], ...]
|
152
|
-
colorscale = cv.validate_coerce(colorscale_name)
|
153
|
-
if hasattr(loc, "__iter__"):
|
154
|
-
return [get_continuous_color(colorscale, x) for x in loc]
|
155
|
-
color = get_continuous_color(colorscale, loc)
|
156
|
-
color = color.replace("rgb", "")
|
157
|
-
color = color.replace("(", "")
|
158
|
-
color = color.replace(")", "")
|
159
|
-
color = color.split(",")
|
160
|
-
final_colors = []
|
161
|
-
for c in color:
|
162
|
-
final_colors.append(math.floor(float(c)))
|
163
|
-
return final_colors
|
164
|
-
|
165
|
-
def get_continuous_color(colorscale, intermed):
|
166
|
-
"""
|
167
|
-
Plotly continuous colorscales assign colors to the range [0, 1]. This function computes the intermediate
|
168
|
-
color for any value in that range.
|
169
|
-
|
170
|
-
Plotly doesn't make the colorscales directly accessible in a common format.
|
171
|
-
Some are ready to use:
|
172
|
-
|
173
|
-
colorscale = plotly.colors.PLOTLY_SCALES["Greens"]
|
174
|
-
|
175
|
-
Others are just swatches that need to be constructed into a colorscale:
|
176
|
-
|
177
|
-
viridis_colors, scale = plotly.colors.convert_colors_to_same_type(plotly.colors.sequential.Viridis)
|
178
|
-
colorscale = plotly.colors.make_colorscale(viridis_colors, scale=scale)
|
179
|
-
|
180
|
-
:param colorscale: A plotly continuous colorscale defined with RGB string colors.
|
181
|
-
:param intermed: value in the range [0, 1]
|
182
|
-
:return: color in rgb string format
|
183
|
-
:rtype: str
|
184
|
-
"""
|
185
|
-
|
186
|
-
if len(colorscale) < 1:
|
187
|
-
raise ValueError("colorscale must have at least one color")
|
188
|
-
if intermed <= 0 or len(colorscale) == 1:
|
189
|
-
c = colorscale[0][1]
|
190
|
-
return c if c[0] != "#" else hex_to_rgb(c)
|
191
|
-
if intermed >= 1:
|
192
|
-
c = colorscale[-1][1]
|
193
|
-
return c if c[0] != "#" else hex_to_rgb(c)
|
194
|
-
for cutoff, color in colorscale:
|
195
|
-
if intermed > cutoff:
|
196
|
-
low_cutoff, low_color = cutoff, color
|
197
|
-
else:
|
198
|
-
high_cutoff, high_color = cutoff, color
|
199
|
-
break
|
200
|
-
if (low_color[0] == "#") or (high_color[0] == "#"):
|
201
|
-
# some color scale names (such as cividis) returns:
|
202
|
-
# [[loc1, "hex1"], [loc2, "hex2"], ...]
|
203
|
-
low_color = hex_to_rgb(low_color)
|
204
|
-
high_color = hex_to_rgb(high_color)
|
205
|
-
return plotly.colors.find_intermediate_color(
|
206
|
-
lowcolor=low_color,
|
207
|
-
highcolor=high_color,
|
208
|
-
intermed=((intermed - low_cutoff) / (high_cutoff - low_cutoff)),
|
209
|
-
colortype="rgb",
|
210
|
-
)
|
211
|
-
|
212
|
-
def get_color_default(ratio):
|
213
|
-
r = 0.0
|
214
|
-
g = 0.0
|
215
|
-
b = 0.0
|
216
|
-
|
217
|
-
finalRatio = ratio;
|
218
|
-
if (finalRatio < 0.0):
|
219
|
-
finalRatio = 0.0
|
220
|
-
elif(finalRatio > 1.0):
|
221
|
-
finalRatio = 1.0
|
222
|
-
|
223
|
-
if (finalRatio >= 0.0 and finalRatio <= 0.25):
|
224
|
-
r = 0.0
|
225
|
-
g = 4.0 * finalRatio
|
226
|
-
b = 1.0
|
227
|
-
elif (finalRatio > 0.25 and finalRatio <= 0.5):
|
228
|
-
r = 0.0
|
229
|
-
g = 1.0
|
230
|
-
b = 1.0 - 4.0 * (finalRatio - 0.25)
|
231
|
-
elif (finalRatio > 0.5 and finalRatio <= 0.75):
|
232
|
-
r = 4.0*(finalRatio - 0.5);
|
233
|
-
g = 1.0
|
234
|
-
b = 0.0
|
235
|
-
else:
|
236
|
-
r = 1.0
|
237
|
-
g = 1.0 - 4.0 * (finalRatio - 0.75)
|
238
|
-
b = 0.0
|
239
|
-
|
240
|
-
rcom = (max(min(r, 1.0), 0.0))
|
241
|
-
gcom = (max(min(g, 1.0), 0.0))
|
242
|
-
bcom = (max(min(b, 1.0), 0.0))
|
243
|
-
|
244
|
-
return [rcom,gcom,bcom]
|
245
|
-
|
246
|
-
if minValue > maxValue:
|
247
|
-
temp = minValue;
|
248
|
-
maxValue = minValue
|
249
|
-
maxValue = temp
|
250
|
-
|
251
|
-
val = value
|
252
|
-
val = max(min(val,maxValue), minValue) # bracket value to the min and max values
|
253
|
-
if (maxValue - minValue) != 0:
|
254
|
-
val = (val - minValue)/(maxValue - minValue)
|
255
|
-
else:
|
256
|
-
val = 0
|
257
|
-
if not colorScale or colorScale.lower() == "default":
|
258
|
-
rgbList = get_color_default(val)
|
259
|
-
else:
|
260
|
-
rgbList = get_color(colorScale, val)
|
261
|
-
if not alpha == None:
|
262
|
-
rgbList.append(alpha)
|
263
|
-
return rgbList
|
264
|
-
|
265
|
-
@staticmethod
|
266
|
-
def CSSNamedColor(color):
|
267
|
-
"""
|
268
|
-
Returns the CSS Named color that most closely matches the input color. The input color is assumed to be
|
269
|
-
in the format [r, g, b]. See https://developer.mozilla.org/en-US/docs/Web/CSS/named-color
|
270
|
-
|
271
|
-
Parameters
|
272
|
-
----------
|
273
|
-
color : list
|
274
|
-
The input color. This is assumed to be in the format [r, g, b]
|
275
|
-
|
276
|
-
Returns
|
277
|
-
-------
|
278
|
-
str
|
279
|
-
The CSS named color that most closely matches the input color.
|
280
|
-
"""
|
281
|
-
import numbers
|
282
|
-
import warnings
|
283
|
-
import os
|
284
|
-
try:
|
285
|
-
import webcolors
|
286
|
-
except:
|
287
|
-
print("Color.CSSNamedColor - Information: Installing required webcolors library.")
|
288
|
-
try:
|
289
|
-
os.system("pip install webcolors")
|
290
|
-
except:
|
291
|
-
os.system("pip install webcolors --user")
|
292
|
-
try:
|
293
|
-
import webcolors
|
294
|
-
print("Color.CSSNamedColor - Information: webcolors library installed correctly.")
|
295
|
-
except:
|
296
|
-
warnings.warn("Color.CSSNamedColor - Error: Could not import webcolors library. Please manually install webcolors. Returning None.")
|
297
|
-
return None
|
298
|
-
|
299
|
-
if not isinstance(color, list):
|
300
|
-
print("Color.CSSNamedColor - Error: The input color parameter is not a valid list. Returning None.")
|
301
|
-
return None
|
302
|
-
color = [int(x) for x in color if isinstance(x, numbers.Real)]
|
303
|
-
if len(color) < 3:
|
304
|
-
print("Color.CSSNamedColor - Error: The input color parameter does not contain valid r, g, b values. Returning None.")
|
305
|
-
return None
|
306
|
-
color = color[0:3]
|
307
|
-
for x in color:
|
308
|
-
if not (0 <= x <= 255):
|
309
|
-
print("Color.CSSNamedColor - Error: The input color parameter does not contain valid r, g, b values. Returning None.")
|
310
|
-
return None
|
311
|
-
|
312
|
-
def est_color(requested_color):
|
313
|
-
min_colors = {}
|
314
|
-
for key, name in webcolors.CSS3_HEX_TO_NAMES.items():
|
315
|
-
r_c, g_c, b_c = webcolors.hex_to_rgb(key)
|
316
|
-
rd = (r_c - requested_color[0]) ** 2
|
317
|
-
gd = (g_c - requested_color[1]) ** 2
|
318
|
-
bd = (b_c - requested_color[2]) ** 2
|
319
|
-
min_colors[(rd + gd + bd)] = name
|
320
|
-
return min_colors[min(min_colors.keys())]
|
321
|
-
|
322
|
-
try:
|
323
|
-
closest_color_name = webcolors.rgb_to_name(color)
|
324
|
-
except ValueError:
|
325
|
-
closest_color_name = est_color(color)
|
326
|
-
return closest_color_name
|
327
|
-
|
328
|
-
@staticmethod
|
329
|
-
def CSSNamedColors():
|
330
|
-
"""
|
331
|
-
Returns a list of all CSS named colors. See https://developer.mozilla.org/en-US/docs/Web/CSS/named-color
|
332
|
-
|
333
|
-
Parameters
|
334
|
-
----------
|
335
|
-
|
336
|
-
Returns
|
337
|
-
-------
|
338
|
-
list
|
339
|
-
The list of all CSS named colors.
|
340
|
-
|
341
|
-
"""
|
342
|
-
# List of CSS named colors
|
343
|
-
css_named_colors = [
|
344
|
-
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond",
|
345
|
-
"blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
|
346
|
-
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey",
|
347
|
-
"darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon",
|
348
|
-
"darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink",
|
349
|
-
"deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia",
|
350
|
-
"gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "green", "greenyellow", "grey", "honeydew", "hotpink",
|
351
|
-
"indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue",
|
352
|
-
"lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
|
353
|
-
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue",
|
354
|
-
"lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue",
|
355
|
-
"mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
|
356
|
-
"mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace",
|
357
|
-
"olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise",
|
358
|
-
"palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple",
|
359
|
-
"red", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna",
|
360
|
-
"silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan",
|
361
|
-
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen"
|
362
|
-
]
|
363
|
-
|
364
|
-
return css_named_colors
|
365
|
-
|
366
|
-
@staticmethod
|
367
|
-
def PlotlyColor(color, alpha=1.0, useAlpha=False):
|
368
|
-
"""
|
369
|
-
Returns a plotly color string based on the input list of [r, g, b] or [r, g, b, a]. If your list is [r, g, b], you can optionally specify an alpha value
|
370
|
-
|
371
|
-
Parameters
|
372
|
-
----------
|
373
|
-
color : list
|
374
|
-
The input color list. This is assumed to be in the format [r, g, b] or [r, g, b, a]
|
375
|
-
alpha : float , optional
|
376
|
-
The transparency value. 0.0 means the color is fully transparent, 1.0 means the color is fully opaque. The default is 1.0.
|
377
|
-
useAlpha : bool , optional
|
378
|
-
If set to True, the returns list includes the alpha value as a fourth element in the list.
|
379
|
-
|
380
|
-
Returns
|
381
|
-
-------
|
382
|
-
str
|
383
|
-
The plotly color string.
|
384
|
-
|
385
|
-
"""
|
386
|
-
if not isinstance(color, list):
|
387
|
-
print("Color.PlotlyColor - Error: The input color parameter is not a valid list. Returning None.")
|
388
|
-
return None
|
389
|
-
if len(color) < 3:
|
390
|
-
print("Color.PlotlyColor - Error: The input color parameter contains less than the minimum three elements. Returning None.")
|
391
|
-
return None
|
392
|
-
if len(color) == 4:
|
393
|
-
alpha = color[3]
|
394
|
-
alpha = min(max(alpha, 0), 1)
|
395
|
-
if alpha < 1:
|
396
|
-
useAlpha = True
|
397
|
-
if useAlpha:
|
398
|
-
return "rgba("+str(color[0])+","+str(color[1])+","+str(color[2])+","+str(alpha)+")"
|
399
|
-
return "rgb("+str(color[0])+","+str(color[1])+","+str(color[2])+")"
|
400
|
-
|
401
|
-
@staticmethod
|
402
|
-
def RGBToHex(rgb):
|
403
|
-
"""
|
404
|
-
Converts RGB color values to a hexadecimal color string.
|
405
|
-
|
406
|
-
Parameters
|
407
|
-
----------
|
408
|
-
rgb : tuple
|
409
|
-
A tuple containing three integers representing the RGB values.
|
410
|
-
|
411
|
-
Returns
|
412
|
-
-------
|
413
|
-
str
|
414
|
-
A hexadecimal color string in the format '#RRGGBB'.
|
415
|
-
"""
|
416
|
-
if not isinstance(rgb, list):
|
417
|
-
print("Color.RGBToHex - Error: The input rgb parameter is not a valid list. Returning None.")
|
418
|
-
return None
|
419
|
-
r, g, b = rgb
|
420
|
-
hex_value = "#{:02x}{:02x}{:02x}".format(r, g, b)
|
421
|
-
return hex_value.upper()
|
422
|
-
|
423
|
-
|
1
|
+
# Copyright (C) 2024
|
2
|
+
# Wassim Jabi <wassim.jabi@gmail.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify it under
|
5
|
+
# the terms of the GNU Affero General Public License as published by the Free Software
|
6
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
7
|
+
# version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
10
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
11
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
12
|
+
# details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License along with
|
15
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
import plotly.colors
|
18
|
+
import math
|
19
|
+
|
20
|
+
class Color:
|
21
|
+
@staticmethod
|
22
|
+
def ByCSSNamedColor(color, alpha: float = None):
|
23
|
+
"""
|
24
|
+
Creates a Color from a CSS named color string. See https://developer.mozilla.org/en-US/docs/Web/CSS/named-color
|
25
|
+
|
26
|
+
Parameters
|
27
|
+
----------
|
28
|
+
color : str
|
29
|
+
A CSS named color.
|
30
|
+
alpha : float , optional
|
31
|
+
THe desired alpha (transparency value). The default is None which means no alpha value will be included in the returned list.
|
32
|
+
|
33
|
+
Returns
|
34
|
+
-------
|
35
|
+
list
|
36
|
+
The color expressed as an [r, g, b] or an [r, g, b, a] list.
|
37
|
+
"""
|
38
|
+
import warnings
|
39
|
+
import os
|
40
|
+
try:
|
41
|
+
import webcolors
|
42
|
+
except:
|
43
|
+
print("Color.ByCSSNamedColor - Information: Installing required webcolors library.")
|
44
|
+
try:
|
45
|
+
os.system("pip install webcolors")
|
46
|
+
except:
|
47
|
+
os.system("pip install webcolors --user")
|
48
|
+
try:
|
49
|
+
import webcolors
|
50
|
+
print("Color.ByCSSNamedColor - Information: webcolors library installed correctly.")
|
51
|
+
except:
|
52
|
+
warnings.warn("Color.ByCSSNamedColor - Error: Could not import webcolors library. Please manually install webcolors. Returning None.")
|
53
|
+
return None
|
54
|
+
|
55
|
+
if not alpha == None:
|
56
|
+
if not 0.0 <= alpha <= 1.0:
|
57
|
+
print("Color.ByCSSNamedColor - Error: alpha is not within the valid range of 0 to 1. Returning None.")
|
58
|
+
return None
|
59
|
+
try:
|
60
|
+
# Get RGB values from the named CSS color
|
61
|
+
rgbList = list(webcolors.name_to_rgb(color))
|
62
|
+
if not alpha == None:
|
63
|
+
rgbList.append(alpha)
|
64
|
+
return rgbList
|
65
|
+
|
66
|
+
except ValueError:
|
67
|
+
print(f"Color.ByCSSNamedColor - Error: '{color}' is not a valid named CSS color. Returning None.")
|
68
|
+
return None
|
69
|
+
|
70
|
+
@staticmethod
|
71
|
+
def ByHEX(hex: str, alpha: float = None):
|
72
|
+
"""
|
73
|
+
Converts a hexadecimal color string to RGB color values.
|
74
|
+
|
75
|
+
Parameters
|
76
|
+
----------
|
77
|
+
hex : str
|
78
|
+
A hexadecimal color string in the format '#RRGGBB'.
|
79
|
+
alpha : float , optional
|
80
|
+
The transparency value. 0.0 means the color is fully transparent, 1.0 means the color is fully opaque. The default is None
|
81
|
+
which means no transparency value will be included in the returned color.
|
82
|
+
Returns
|
83
|
+
-------
|
84
|
+
list
|
85
|
+
The color expressed as an [r, g, b] or an [r, g, b, a] list.
|
86
|
+
|
87
|
+
"""
|
88
|
+
if not isinstance(hex, str):
|
89
|
+
print("Color.HEXtoRGB - Error: The input hex parameter is not a valid string. Returning None.")
|
90
|
+
return None
|
91
|
+
if not alpha == None:
|
92
|
+
if not 0.0 <= alpha <= 1.0:
|
93
|
+
print("Color.ByHEX - Error: alpha is not within the valid range of 0 to 1. Returning None.")
|
94
|
+
return None
|
95
|
+
hex = hex.lstrip('#')
|
96
|
+
if len(hex) != 6:
|
97
|
+
print("Color.HEXtoRGB - Error: Invalid hexadecimal color format. It should be a 6-digit hex value. Returning None.")
|
98
|
+
return None
|
99
|
+
r = int(hex[0:2], 16)
|
100
|
+
g = int(hex[2:4], 16)
|
101
|
+
b = int(hex[4:6], 16)
|
102
|
+
rgbList = [r, g, b]
|
103
|
+
if not alpha == None:
|
104
|
+
rgbList.append(alpha)
|
105
|
+
return rgbList
|
106
|
+
|
107
|
+
@staticmethod
|
108
|
+
def ByValueInRange(value: float = 0.5, minValue: float = 0.0, maxValue: float = 1.0, alpha: float = None, colorScale="viridis"):
|
109
|
+
"""
|
110
|
+
Returns the r, g, b, (and optionally) a list of numbers representing the red, green, blue and alpha color elements.
|
111
|
+
|
112
|
+
Parameters
|
113
|
+
----------
|
114
|
+
value : float , optional
|
115
|
+
The input value. The default is 0.5.
|
116
|
+
minValue : float , optional
|
117
|
+
the input minimum value. The default is 0.0.
|
118
|
+
maxValue : float , optional
|
119
|
+
The input maximum value. The default is 1.0.
|
120
|
+
alpha : float , optional
|
121
|
+
The alpha (transparency) value. 0.0 means the color is fully transparent, 1.0 means the color is fully opaque. The default is 1.0.
|
122
|
+
useAlpha : bool , optional
|
123
|
+
If set to True, the returns list includes the alpha value as a fourth element in the list.
|
124
|
+
colorScale : str , optional
|
125
|
+
The desired type of plotly color scales to use (e.g. "Viridis", "Plasma"). The default is "Viridis". For a full list of names, see https://plotly.com/python/builtin-colorscales/.
|
126
|
+
|
127
|
+
Returns
|
128
|
+
-------
|
129
|
+
list
|
130
|
+
The color expressed as an [r, g, b] or an [r, g, b, a] list.
|
131
|
+
|
132
|
+
"""
|
133
|
+
if not alpha == None:
|
134
|
+
if not 0.0 <= alpha <= 1.0:
|
135
|
+
print("Color.ByValueInRange - Error: alpha is not within the valid range of 0 to 1. Returning None.")
|
136
|
+
return None
|
137
|
+
# Code based on: https://stackoverflow.com/questions/62710057/access-color-from-plotly-color-scale
|
138
|
+
|
139
|
+
def hex_to_rgb(value):
|
140
|
+
value = str(value)
|
141
|
+
value = value.lstrip('#')
|
142
|
+
lv = len(value)
|
143
|
+
returnValue = tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))
|
144
|
+
return str(returnValue)
|
145
|
+
|
146
|
+
def get_color(colorscale_name, loc):
|
147
|
+
from _plotly_utils.basevalidators import ColorscaleValidator
|
148
|
+
# first parameter: Name of the property being validated
|
149
|
+
# second parameter: a string, doesn't really matter in our use case
|
150
|
+
cv = ColorscaleValidator("colorscale", "")
|
151
|
+
# colorscale will be a list of lists: [[loc1, "rgb1"], [loc2, "rgb2"], ...]
|
152
|
+
colorscale = cv.validate_coerce(colorscale_name)
|
153
|
+
if hasattr(loc, "__iter__"):
|
154
|
+
return [get_continuous_color(colorscale, x) for x in loc]
|
155
|
+
color = get_continuous_color(colorscale, loc)
|
156
|
+
color = color.replace("rgb", "")
|
157
|
+
color = color.replace("(", "")
|
158
|
+
color = color.replace(")", "")
|
159
|
+
color = color.split(",")
|
160
|
+
final_colors = []
|
161
|
+
for c in color:
|
162
|
+
final_colors.append(math.floor(float(c)))
|
163
|
+
return final_colors
|
164
|
+
|
165
|
+
def get_continuous_color(colorscale, intermed):
|
166
|
+
"""
|
167
|
+
Plotly continuous colorscales assign colors to the range [0, 1]. This function computes the intermediate
|
168
|
+
color for any value in that range.
|
169
|
+
|
170
|
+
Plotly doesn't make the colorscales directly accessible in a common format.
|
171
|
+
Some are ready to use:
|
172
|
+
|
173
|
+
colorscale = plotly.colors.PLOTLY_SCALES["Greens"]
|
174
|
+
|
175
|
+
Others are just swatches that need to be constructed into a colorscale:
|
176
|
+
|
177
|
+
viridis_colors, scale = plotly.colors.convert_colors_to_same_type(plotly.colors.sequential.Viridis)
|
178
|
+
colorscale = plotly.colors.make_colorscale(viridis_colors, scale=scale)
|
179
|
+
|
180
|
+
:param colorscale: A plotly continuous colorscale defined with RGB string colors.
|
181
|
+
:param intermed: value in the range [0, 1]
|
182
|
+
:return: color in rgb string format
|
183
|
+
:rtype: str
|
184
|
+
"""
|
185
|
+
|
186
|
+
if len(colorscale) < 1:
|
187
|
+
raise ValueError("colorscale must have at least one color")
|
188
|
+
if intermed <= 0 or len(colorscale) == 1:
|
189
|
+
c = colorscale[0][1]
|
190
|
+
return c if c[0] != "#" else hex_to_rgb(c)
|
191
|
+
if intermed >= 1:
|
192
|
+
c = colorscale[-1][1]
|
193
|
+
return c if c[0] != "#" else hex_to_rgb(c)
|
194
|
+
for cutoff, color in colorscale:
|
195
|
+
if intermed > cutoff:
|
196
|
+
low_cutoff, low_color = cutoff, color
|
197
|
+
else:
|
198
|
+
high_cutoff, high_color = cutoff, color
|
199
|
+
break
|
200
|
+
if (low_color[0] == "#") or (high_color[0] == "#"):
|
201
|
+
# some color scale names (such as cividis) returns:
|
202
|
+
# [[loc1, "hex1"], [loc2, "hex2"], ...]
|
203
|
+
low_color = hex_to_rgb(low_color)
|
204
|
+
high_color = hex_to_rgb(high_color)
|
205
|
+
return plotly.colors.find_intermediate_color(
|
206
|
+
lowcolor=low_color,
|
207
|
+
highcolor=high_color,
|
208
|
+
intermed=((intermed - low_cutoff) / (high_cutoff - low_cutoff)),
|
209
|
+
colortype="rgb",
|
210
|
+
)
|
211
|
+
|
212
|
+
def get_color_default(ratio):
|
213
|
+
r = 0.0
|
214
|
+
g = 0.0
|
215
|
+
b = 0.0
|
216
|
+
|
217
|
+
finalRatio = ratio;
|
218
|
+
if (finalRatio < 0.0):
|
219
|
+
finalRatio = 0.0
|
220
|
+
elif(finalRatio > 1.0):
|
221
|
+
finalRatio = 1.0
|
222
|
+
|
223
|
+
if (finalRatio >= 0.0 and finalRatio <= 0.25):
|
224
|
+
r = 0.0
|
225
|
+
g = 4.0 * finalRatio
|
226
|
+
b = 1.0
|
227
|
+
elif (finalRatio > 0.25 and finalRatio <= 0.5):
|
228
|
+
r = 0.0
|
229
|
+
g = 1.0
|
230
|
+
b = 1.0 - 4.0 * (finalRatio - 0.25)
|
231
|
+
elif (finalRatio > 0.5 and finalRatio <= 0.75):
|
232
|
+
r = 4.0*(finalRatio - 0.5);
|
233
|
+
g = 1.0
|
234
|
+
b = 0.0
|
235
|
+
else:
|
236
|
+
r = 1.0
|
237
|
+
g = 1.0 - 4.0 * (finalRatio - 0.75)
|
238
|
+
b = 0.0
|
239
|
+
|
240
|
+
rcom = (max(min(r, 1.0), 0.0))
|
241
|
+
gcom = (max(min(g, 1.0), 0.0))
|
242
|
+
bcom = (max(min(b, 1.0), 0.0))
|
243
|
+
|
244
|
+
return [rcom,gcom,bcom]
|
245
|
+
|
246
|
+
if minValue > maxValue:
|
247
|
+
temp = minValue;
|
248
|
+
maxValue = minValue
|
249
|
+
maxValue = temp
|
250
|
+
|
251
|
+
val = value
|
252
|
+
val = max(min(val,maxValue), minValue) # bracket value to the min and max values
|
253
|
+
if (maxValue - minValue) != 0:
|
254
|
+
val = (val - minValue)/(maxValue - minValue)
|
255
|
+
else:
|
256
|
+
val = 0
|
257
|
+
if not colorScale or colorScale.lower() == "default":
|
258
|
+
rgbList = get_color_default(val)
|
259
|
+
else:
|
260
|
+
rgbList = get_color(colorScale, val)
|
261
|
+
if not alpha == None:
|
262
|
+
rgbList.append(alpha)
|
263
|
+
return rgbList
|
264
|
+
|
265
|
+
@staticmethod
|
266
|
+
def CSSNamedColor(color):
|
267
|
+
"""
|
268
|
+
Returns the CSS Named color that most closely matches the input color. The input color is assumed to be
|
269
|
+
in the format [r, g, b]. See https://developer.mozilla.org/en-US/docs/Web/CSS/named-color
|
270
|
+
|
271
|
+
Parameters
|
272
|
+
----------
|
273
|
+
color : list
|
274
|
+
The input color. This is assumed to be in the format [r, g, b]
|
275
|
+
|
276
|
+
Returns
|
277
|
+
-------
|
278
|
+
str
|
279
|
+
The CSS named color that most closely matches the input color.
|
280
|
+
"""
|
281
|
+
import numbers
|
282
|
+
import warnings
|
283
|
+
import os
|
284
|
+
try:
|
285
|
+
import webcolors
|
286
|
+
except:
|
287
|
+
print("Color.CSSNamedColor - Information: Installing required webcolors library.")
|
288
|
+
try:
|
289
|
+
os.system("pip install webcolors")
|
290
|
+
except:
|
291
|
+
os.system("pip install webcolors --user")
|
292
|
+
try:
|
293
|
+
import webcolors
|
294
|
+
print("Color.CSSNamedColor - Information: webcolors library installed correctly.")
|
295
|
+
except:
|
296
|
+
warnings.warn("Color.CSSNamedColor - Error: Could not import webcolors library. Please manually install webcolors. Returning None.")
|
297
|
+
return None
|
298
|
+
|
299
|
+
if not isinstance(color, list):
|
300
|
+
print("Color.CSSNamedColor - Error: The input color parameter is not a valid list. Returning None.")
|
301
|
+
return None
|
302
|
+
color = [int(x) for x in color if isinstance(x, numbers.Real)]
|
303
|
+
if len(color) < 3:
|
304
|
+
print("Color.CSSNamedColor - Error: The input color parameter does not contain valid r, g, b values. Returning None.")
|
305
|
+
return None
|
306
|
+
color = color[0:3]
|
307
|
+
for x in color:
|
308
|
+
if not (0 <= x <= 255):
|
309
|
+
print("Color.CSSNamedColor - Error: The input color parameter does not contain valid r, g, b values. Returning None.")
|
310
|
+
return None
|
311
|
+
|
312
|
+
def est_color(requested_color):
|
313
|
+
min_colors = {}
|
314
|
+
for key, name in webcolors.CSS3_HEX_TO_NAMES.items():
|
315
|
+
r_c, g_c, b_c = webcolors.hex_to_rgb(key)
|
316
|
+
rd = (r_c - requested_color[0]) ** 2
|
317
|
+
gd = (g_c - requested_color[1]) ** 2
|
318
|
+
bd = (b_c - requested_color[2]) ** 2
|
319
|
+
min_colors[(rd + gd + bd)] = name
|
320
|
+
return min_colors[min(min_colors.keys())]
|
321
|
+
|
322
|
+
try:
|
323
|
+
closest_color_name = webcolors.rgb_to_name(color)
|
324
|
+
except ValueError:
|
325
|
+
closest_color_name = est_color(color)
|
326
|
+
return closest_color_name
|
327
|
+
|
328
|
+
@staticmethod
|
329
|
+
def CSSNamedColors():
|
330
|
+
"""
|
331
|
+
Returns a list of all CSS named colors. See https://developer.mozilla.org/en-US/docs/Web/CSS/named-color
|
332
|
+
|
333
|
+
Parameters
|
334
|
+
----------
|
335
|
+
|
336
|
+
Returns
|
337
|
+
-------
|
338
|
+
list
|
339
|
+
The list of all CSS named colors.
|
340
|
+
|
341
|
+
"""
|
342
|
+
# List of CSS named colors
|
343
|
+
css_named_colors = [
|
344
|
+
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond",
|
345
|
+
"blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
|
346
|
+
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey",
|
347
|
+
"darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon",
|
348
|
+
"darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink",
|
349
|
+
"deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia",
|
350
|
+
"gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "green", "greenyellow", "grey", "honeydew", "hotpink",
|
351
|
+
"indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue",
|
352
|
+
"lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
|
353
|
+
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue",
|
354
|
+
"lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue",
|
355
|
+
"mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
|
356
|
+
"mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace",
|
357
|
+
"olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise",
|
358
|
+
"palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple",
|
359
|
+
"red", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna",
|
360
|
+
"silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan",
|
361
|
+
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen"
|
362
|
+
]
|
363
|
+
|
364
|
+
return css_named_colors
|
365
|
+
|
366
|
+
@staticmethod
|
367
|
+
def PlotlyColor(color, alpha=1.0, useAlpha=False):
|
368
|
+
"""
|
369
|
+
Returns a plotly color string based on the input list of [r, g, b] or [r, g, b, a]. If your list is [r, g, b], you can optionally specify an alpha value
|
370
|
+
|
371
|
+
Parameters
|
372
|
+
----------
|
373
|
+
color : list
|
374
|
+
The input color list. This is assumed to be in the format [r, g, b] or [r, g, b, a]
|
375
|
+
alpha : float , optional
|
376
|
+
The transparency value. 0.0 means the color is fully transparent, 1.0 means the color is fully opaque. The default is 1.0.
|
377
|
+
useAlpha : bool , optional
|
378
|
+
If set to True, the returns list includes the alpha value as a fourth element in the list.
|
379
|
+
|
380
|
+
Returns
|
381
|
+
-------
|
382
|
+
str
|
383
|
+
The plotly color string.
|
384
|
+
|
385
|
+
"""
|
386
|
+
if not isinstance(color, list):
|
387
|
+
print("Color.PlotlyColor - Error: The input color parameter is not a valid list. Returning None.")
|
388
|
+
return None
|
389
|
+
if len(color) < 3:
|
390
|
+
print("Color.PlotlyColor - Error: The input color parameter contains less than the minimum three elements. Returning None.")
|
391
|
+
return None
|
392
|
+
if len(color) == 4:
|
393
|
+
alpha = color[3]
|
394
|
+
alpha = min(max(alpha, 0), 1)
|
395
|
+
if alpha < 1:
|
396
|
+
useAlpha = True
|
397
|
+
if useAlpha:
|
398
|
+
return "rgba("+str(color[0])+","+str(color[1])+","+str(color[2])+","+str(alpha)+")"
|
399
|
+
return "rgb("+str(color[0])+","+str(color[1])+","+str(color[2])+")"
|
400
|
+
|
401
|
+
@staticmethod
|
402
|
+
def RGBToHex(rgb):
|
403
|
+
"""
|
404
|
+
Converts RGB color values to a hexadecimal color string.
|
405
|
+
|
406
|
+
Parameters
|
407
|
+
----------
|
408
|
+
rgb : tuple
|
409
|
+
A tuple containing three integers representing the RGB values.
|
410
|
+
|
411
|
+
Returns
|
412
|
+
-------
|
413
|
+
str
|
414
|
+
A hexadecimal color string in the format '#RRGGBB'.
|
415
|
+
"""
|
416
|
+
if not isinstance(rgb, list):
|
417
|
+
print("Color.RGBToHex - Error: The input rgb parameter is not a valid list. Returning None.")
|
418
|
+
return None
|
419
|
+
r, g, b = rgb
|
420
|
+
hex_value = "#{:02x}{:02x}{:02x}".format(r, g, b)
|
421
|
+
return hex_value.upper()
|
422
|
+
|
423
|
+
|