Skip to content

Commit 1111ec4

Browse files
authored
Merge pull request #502 from palewire/main
feat(multiple_column): add field validators for text and range annotations conversion
2 parents f6b7c8f + b9cd199 commit 1111ec4

1 file changed

Lines changed: 51 additions & 12 deletions

File tree

datawrapper/charts/multiple_column.py

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -300,19 +300,12 @@ class MultipleColumnChart(
300300
AnnotationsMixin,
301301
BaseChart,
302302
):
303-
"""A base class for the Datawrapper API's multiple column chart."""
303+
"""A base class for the Datawrapper API's multiple column chart.
304304
305-
# Override annotation fields with MultipleColumnChart-specific types
306-
text_annotations: Sequence[MultipleColumnTextAnnotation | dict[Any, Any]] = Field(
307-
default_factory=list,
308-
alias="text-annotations",
309-
description="A list of text annotations to display on the chart",
310-
)
311-
range_annotations: Sequence[MultipleColumnRangeAnnotation | dict[Any, Any]] = Field(
312-
default_factory=list,
313-
alias="range-annotations",
314-
description="A list of range annotations to display on the chart",
315-
)
305+
Note: This chart uses MultipleColumnTextAnnotation and MultipleColumnRangeAnnotation
306+
for annotations, which extend the base annotation classes with plot-specific fields.
307+
The parent AnnotationsMixin fields accept these subclasses automatically.
308+
"""
316309

317310
model_config = ConfigDict(
318311
populate_by_name=True,
@@ -511,6 +504,52 @@ def validate_plot_height_mode(cls, v: PlotHeightMode | str) -> PlotHeightMode |
511504
raise ValueError(f"Invalid value: {v}. Must be one of {valid_values}")
512505
return v
513506

507+
@field_validator("text_annotations", mode="before")
508+
@classmethod
509+
def convert_text_annotations(
510+
cls, v: Sequence[MultipleColumnTextAnnotation | dict[Any, Any]]
511+
) -> list[MultipleColumnTextAnnotation]:
512+
"""Convert dict annotations to MultipleColumnTextAnnotation instances.
513+
514+
This ensures that when annotations are passed as dicts, they are converted
515+
to the proper annotation class so that serialize_model() includes the plot field.
516+
"""
517+
if not v:
518+
return []
519+
520+
result = []
521+
for item in v:
522+
if isinstance(item, dict):
523+
# Convert dict to MultipleColumnTextAnnotation instance
524+
result.append(MultipleColumnTextAnnotation(**item))
525+
else:
526+
# Already an instance, keep as is
527+
result.append(item)
528+
return result
529+
530+
@field_validator("range_annotations", mode="before")
531+
@classmethod
532+
def convert_range_annotations(
533+
cls, v: Sequence[MultipleColumnRangeAnnotation | dict[Any, Any]]
534+
) -> list[MultipleColumnRangeAnnotation]:
535+
"""Convert dict annotations to MultipleColumnRangeAnnotation instances.
536+
537+
This ensures that when annotations are passed as dicts, they are converted
538+
to the proper annotation class so that serialize_model() includes the plot field.
539+
"""
540+
if not v:
541+
return []
542+
543+
result = []
544+
for item in v:
545+
if isinstance(item, dict):
546+
# Convert dict to MultipleColumnRangeAnnotation instance
547+
result.append(MultipleColumnRangeAnnotation(**item))
548+
else:
549+
# Already an instance, keep as is
550+
result.append(item)
551+
return result
552+
514553
#
515554
# Tooltips
516555
#

0 commit comments

Comments
 (0)