Skip to content

feat(charts): add specialized annotation subclasses for X/Y lines and ranges#487

Merged
palewire merged 1 commit intochekos:mainfrom
palewire:main
Oct 28, 2025
Merged

feat(charts): add specialized annotation subclasses for X/Y lines and ranges#487
palewire merged 1 commit intochekos:mainfrom
palewire:main

Conversation

@palewire
Copy link
Copy Markdown
Collaborator

Add four new annotation classes that extend RangeAnnotation with more specific interfaces:

  • XRangeAnnotation: horizontal range between two x positions
  • YRangeAnnotation: vertical range between two y positions
  • XLineAnnotation: vertical line at a specific x position
  • YLineAnnotation: horizontal line at a specific y position

These subclasses automatically set appropriate type and display values, and include validation to ensure required position parameters are provided. Also adds field validators to RangeAnnotation for type, display, and opacity values.

This improves the API ergonomics by providing clearer, more intuitive classes for common annotation patterns while maintaining backward compatibility with the base RangeAnnotation class.

… ranges

Add four new annotation classes that extend RangeAnnotation with more specific interfaces:
- XRangeAnnotation: horizontal range between two x positions
- YRangeAnnotation: vertical range between two y positions
- XLineAnnotation: vertical line at a specific x position
- YLineAnnotation: horizontal line at a specific y position

These subclasses automatically set appropriate type and display values, and include validation to ensure required position parameters are provided. Also adds field validators to RangeAnnotation for type, display, and opacity values.

This improves the API ergonomics by providing clearer, more intuitive classes for common annotation patterns while maintaining backward compatibility with the base RangeAnnotation class.
@palewire palewire requested a review from Copilot October 28, 2025 23:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds specialized annotation subclasses to simplify the creation of range and line annotations in the Datawrapper API. Instead of manually specifying type and display parameters, users can now use purpose-built classes like XRangeAnnotation, YRangeAnnotation, XLineAnnotation, and YLineAnnotation.

  • Adds four new subclasses of RangeAnnotation with automatic field configuration
  • Adds validators to the base RangeAnnotation class for type, display, opacity, stroke_type, and stroke_width
  • Exports new classes through the package hierarchy for public API access

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
datawrapper/charts/annos.py Adds validators to RangeAnnotation base class and implements four new annotation subclasses with automatic field setting and position validation
tests/unit/test_range_annotation_subclasses.py Comprehensive test suite covering validators, subclass behavior, serialization, and inheritance
datawrapper/charts/init.py Exports new annotation subclasses from charts module
datawrapper/init.py Exports new annotation subclasses from main package
docs/user-guide/api/models.rst Adds documentation entries for new annotation classes
Comments suppressed due to low confidence (2)

datawrapper/charts/annos.py:520

  • The stroke_type validator returns the enum value as a string when a StrokeType enum is passed, but this inconsistency is not explicit. When v is a StrokeType enum instance, it should be converted to its string value for consistency. Consider adding return v.value if isinstance(v, StrokeType) else v or handling enum instances explicitly.
    @field_validator("stroke_type")
    @classmethod
    def validate_stroke_type(cls, v: StrokeType | str) -> StrokeType | str:
        """Validate that stroke_type is a valid StrokeType value."""
        if isinstance(v, str):
            valid_values = [e.value for e in StrokeType]
            if v not in valid_values:
                raise ValueError(
                    f"Invalid stroke type: {v}. Must be one of {valid_values}"
                )
        return v

datawrapper/charts/annos.py:539

  • The stroke_width validator returns the enum value as an int when a StrokeWidth enum is passed, but this inconsistency is not explicit. When v is a StrokeWidth enum instance, it should be converted to its integer value for consistency. Consider adding return v.value if isinstance(v, StrokeWidth) else v or handling enum instances explicitly.
    @field_validator("stroke_width")
    @classmethod
    def validate_stroke_width(cls, v: StrokeWidth | int) -> StrokeWidth | int:
        """Validate that stroke_width is a valid StrokeWidth value."""
        if isinstance(v, int):
            valid_values = [e.value for e in StrokeWidth]
            if v not in valid_values:
                raise ValueError(
                    f"Invalid stroke width: {v}. Must be one of {valid_values}"
                )
        return v

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@palewire palewire merged commit a62e4ad into chekos:main Oct 28, 2025
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants