Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ to features in the release.
If plotly.js adds new traces or trace/layout attributes that aren't listed in `orderings.json`, `get_plotschema.py` prints a warning like `missing key in attributes: <attribute-name>` and appends the missing entry to the end of its section. To resolve:

- Add each missing attribute to the appropriate section of `/_data/orderings.json` in the position you want it to appear in the reference docs.
- When in doubt about trace-attribute placement, match plotly.js's native order: open the regenerated `_data/plotschema.json` and find where plotly.js itself places the attribute (e.g. inspect a representative trace's `attributes` keys in order). Following the native order keeps related attributes grouped (for example, `texttemplate` → `texttemplatefallback` → `texttemplatesrc`).
- When in doubt about trace-attribute placement, match plotly.js's native order: open the regenerated `_data/plotschema.json` and find where plotly.js itself places the attribute (e.g. inspect a representative trace's `attributes` keys in order). Following the native order keeps related attributes grouped (for example, `texttemplate` → `texttemplatefallback`).
- For new top-level layout attributes, group them with semantically related entries rather than appending to the end (for example, a new click-behavior attribute like `clickanywhere` belongs next to `clickmode`).
- Re-run `python get_plotschema.py <PLOTLY.JS VERSION>` after editing `orderings.json` and confirm the warnings are gone.
3. Rebuild the Algolia `schema` index with `ALGOLIA_API_KEY=<key> make update_ref_search`
Expand Down
70 changes: 29 additions & 41 deletions _plotly_utils/basevalidators.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ColorValidator will need to be updated to remove the references and regex checks for hsv since that got removed. The regex patterns will also need to be updated to match the new color specifier support.

Original file line number Diff line number Diff line change
Expand Up @@ -667,33 +667,6 @@ def validate_coerce(self, v):
return v


class SrcValidator(BaseValidator):
def __init__(self, plotly_name, parent_name, **kwargs):
super(SrcValidator, self).__init__(
plotly_name=plotly_name, parent_name=parent_name, **kwargs
)

self.chart_studio = get_module("chart_studio")

def description(self):
return """\
The '{plotly_name}' property must be specified as a string or
as a plotly.grid_objs.Column object""".format(plotly_name=self.plotly_name)

def validate_coerce(self, v):
if is_none_or_typed_array_spec(v):
pass
elif isinstance(v, str):
pass
elif self.chart_studio and isinstance(v, self.chart_studio.grid_objs.Column):
# Convert to id string
v = v.id
else:
self.raise_invalid_val(v)

return v


class NumberValidator(BaseValidator):
"""
"number": {
Expand Down Expand Up @@ -1146,11 +1119,13 @@ class ColorValidator(BaseValidator):
"""
"color": {
"description": "A string describing color. Supported formats:
- hex (e.g. '#d3d3d3')
- rgb (e.g. 'rgb(255, 0, 0)')
- rgba (e.g. 'rgb(255, 0, 0, 0.5)')
- hsl (e.g. 'hsl(0, 100%, 50%)')
- hsv (e.g. 'hsv(0, 100%, 100%)')
- hex or short hex (e.g. '#d3d3d3', '#d3d')
- hex or short hex with alpha (e.g. '#d3d3d380', '#d3d8')
- rgb (e.g. 'rgb(255, 0, 0)', 'rgb(255 0 0)')
- rgba (e.g. 'rgba(255, 0, 0, 0.5)', 'rgba(255 0 0 / 0.5)')
- hsl (e.g. 'hsl(0, 100%, 50%)', 'hsl(0deg 100% 50%)')
- hsla (e.g. 'hsla(0, 100%, 50%, 0.5)', 'hsla(0deg 100% 50% / 0.5)')
- hwb (e.g. 'hwb(0, 0%, 100%)', 'hwb(0 0% 100%)')
- named colors(full list:
http://www.w3.org/TR/css3-color/#svg-color)",
"requiredOpts": [],
Expand All @@ -1161,8 +1136,14 @@ class ColorValidator(BaseValidator):
},
"""

re_hex = re.compile(r"#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})")
re_rgb_etc = re.compile(r"(rgb|hsl|hsv)a?\([\d.]+%?(,[\d.]+%?){2,3}\)")
re_spaces_to_remove = re.compile(r"(?<!(\d|%|g)) | (?!\d)")

re_hex = re.compile(
r"#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})"
)
re_rgb_etc = re.compile(
r"((rgb|hsl)a?|hwb)\([\d.]+(%|deg)?([ ,] ?[\d.]+%?){2}([ /,] ?[\d.]+%?)?\)"
)
re_ddk = re.compile(r"var\(\-\-.*\)")

named_colors = [
Expand Down Expand Up @@ -1335,12 +1316,15 @@ def numbers_allowed(self):

def description(self):
valid_color_description = """\
The '{plotly_name}' property is a color and may be specified as:
- A hex string (e.g. '#ff0000')
- An rgb/rgba string (e.g. 'rgb(255,0,0)')
- An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
- An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
- A named CSS color: see https://plotly.com/python/css-colors/ for a list""".format(
The '{plotly_name}' property is a color and may be specified as a string in the following formats:
- hex or short hex (e.g. '#d3d3d3', '#d3d')
- hex or short hex with alpha (e.g. '#d3d3d380', '#d3d8')
- rgb (e.g. 'rgb(255, 0, 0)', 'rgb(255 0 0)')
- rgba (e.g. 'rgba(255, 0, 0, 0.5)', 'rgba(255 0 0 / 0.5)')
- hsl (e.g. 'hsl(0, 100%, 50%)', 'hsl(0deg 100% 50%)')
- hsla (e.g. 'hsla(0, 100%, 50%, 0.5)', 'hsla(0deg 100% 50% / 0.5)')
- hwb (e.g. 'hwb(0, 0%, 100%)', 'hwb(0 0% 100%)')
- a named CSS color: see https://plotly.com/python/css-colors/ for a list""".format(
plotly_name=self.plotly_name
)

Expand Down Expand Up @@ -1455,7 +1439,11 @@ def perform_validate_coerce(v, allow_number=None):
return None
else:
# Remove spaces so regexes don't need to bother with them.
v_normalized = v.replace(" ", "").lower()
# Don't remove spaces between two digits, though.
v_normalized = v.strip()
v_normalized = re.sub(" +", " ", v_normalized)
v_normalized = re.sub(ColorValidator.re_spaces_to_remove, "", v_normalized)
v_normalized = v_normalized.lower()

# if ColorValidator.re_hex.fullmatch(v_normalized):
if fullmatch(ColorValidator.re_hex, v_normalized):
Expand Down
1 change: 0 additions & 1 deletion codegen/compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"Marker": {"base_type": dict, "new": ["scatter", "histogram.selected", "etc."]},
"RadialAxis": {"base_type": dict, "new": ["layout", "layout.polar"]},
"Scene": {"base_type": dict, "new": ["layout"]},
"Stream": {"base_type": dict, "new": ["scatter", "area"]},
"XAxis": {"base_type": dict, "new": ["layout", "layout.scene"]},
"YAxis": {"base_type": dict, "new": ["layout", "layout.scene"]},
"ZAxis": {"base_type": dict, "new": ["layout.scene"]},
Expand Down
42 changes: 4 additions & 38 deletions codegen/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@
from codegen.utils import CAVEAT, write_source_py


deprecated_mapbox_traces = [
"scattermapbox",
"choroplethmapbox",
"densitymapbox",
]
locationmode_traces = [
"choropleth",
"scattergeo",
Expand Down Expand Up @@ -102,11 +97,7 @@ def build_datatype_py(node):
)
buffer.write("import copy as _copy\n")

if (
node.name_property in deprecated_mapbox_traces
or node.name_property in locationmode_traces
or node.name_property == "template"
):
if node.name_property in locationmode_traces or node.name_property == "template":
buffer.write("import warnings\n")

# Write class definition
Expand Down Expand Up @@ -375,22 +366,10 @@ def __init__(self"""
buffer.write("\n\n")
for subtype_node in subtype_nodes:
name_prop = subtype_node.name_property
if datatype_class == "Template" and name_prop == "data":
buffer.write(
f"""
# Template.data contains a 'scattermapbox' key, which causes a
# go.Scattermapbox trace object to be created during validation.
# In order to prevent false deprecation warnings from surfacing,
# we suppress deprecation warnings for this line only.
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=DeprecationWarning)
self._set_property("{name_prop}", arg, {name_prop})"""
)
else:
buffer.write(
f"""
buffer.write(
f"""
self._set_property("{name_prop}", arg, {name_prop})"""
)
)

# Literals
if literal_nodes:
Expand All @@ -411,19 +390,6 @@ def __init__(self"""
"""
)

if node.name_property in deprecated_mapbox_traces:
buffer.write(
f"""
warnings.warn(
"*{node.name_property}* is deprecated!"
+ " Use *{node.name_property.replace("mapbox", "map")}* instead."
+ " Learn more at: https://plotly.com/python/mapbox-to-maplibre/",
stacklevel=2,
category=DeprecationWarning,
)
"""
)

# Return source string
return buffer.getvalue()

Expand Down
Loading
Loading