Source code for fastpyxl.chart.series

# Copyright (c) 2010-2024 fastpyxl

from __future__ import annotations

from fastpyxl.typed_serialisable.base import Serialisable
from fastpyxl.typed_serialisable.errors import FieldValidationError
from fastpyxl.typed_serialisable.fields import AliasField, Field

from fastpyxl.descriptors.excel import ExtensionList

from .shapes import GraphicalProperties
from .data_source import (
    AxDataSource,
    NumDataSource,
    StrRef,
)
from .error_bar import ErrorBars
from .label import DataLabelList
from .marker import DataPoint, PictureOptions, Marker
from .trendline import Trendline


def _shape_converter(v):
    if v is None or v == "none":
        return None
    allowed = frozenset(
        {"cone", "coneToMax", "box", "cylinder", "pyramid", "pyramidToMax"}
    )
    if v not in allowed:
        raise FieldValidationError(f"shape rejected value {v!r}")
    return v


attribute_mapping = {
    "area": (
        "idx",
        "order",
        "tx",
        "spPr",
        "pictureOptions",
        "dPt",
        "dLbls",
        "errBars",
        "trendline",
        "cat",
        "val",
    ),
    "bar": (
        "idx",
        "order",
        "tx",
        "spPr",
        "invertIfNegative",
        "pictureOptions",
        "dPt",
        "dLbls",
        "trendline",
        "errBars",
        "cat",
        "val",
        "shape",
    ),
    "bubble": (
        "idx",
        "order",
        "tx",
        "spPr",
        "invertIfNegative",
        "dPt",
        "dLbls",
        "trendline",
        "errBars",
        "xVal",
        "yVal",
        "bubbleSize",
        "bubble3D",
    ),
    "line": (
        "idx",
        "order",
        "tx",
        "spPr",
        "marker",
        "dPt",
        "dLbls",
        "trendline",
        "errBars",
        "cat",
        "val",
        "smooth",
    ),
    "pie": (
        "idx",
        "order",
        "tx",
        "spPr",
        "explosion",
        "dPt",
        "dLbls",
        "cat",
        "val",
    ),
    "radar": (
        "idx",
        "order",
        "tx",
        "spPr",
        "marker",
        "dPt",
        "dLbls",
        "cat",
        "val",
    ),
    "scatter": (
        "idx",
        "order",
        "tx",
        "spPr",
        "marker",
        "dPt",
        "dLbls",
        "trendline",
        "errBars",
        "xVal",
        "yVal",
        "smooth",
    ),
    "surface": ("idx", "order", "tx", "spPr", "cat", "val"),
}


[docs] class SeriesLabel(Serialisable): tagname = "tx" strRef: StrRef | None = Field.element(expected_type=StrRef, allow_none=True, default=None) v: str | None = Field.nested_text(expected_type=str, allow_none=True, default=None) value = AliasField("v", default=None) xml_order = ("strRef", "v") def __init__(self, strRef=None, v=None): self.strRef = strRef self.v = v
[docs] class Series(Serialisable): """ Generic series object. Should not be instantiated directly. User the chart.Series factory instead. """ tagname = "ser" idx: int | None = Field.nested_value(expected_type=int, allow_none=True, default=None) order: int | None = Field.nested_value(expected_type=int, allow_none=True, default=None) tx: SeriesLabel | None = Field.element(expected_type=SeriesLabel, allow_none=True, default=None) title = AliasField("tx", default=None) spPr: GraphicalProperties | None = Field.element( expected_type=GraphicalProperties, allow_none=True, default=None ) graphicalProperties = AliasField("spPr", default=None) pictureOptions: PictureOptions | None = Field.element( expected_type=PictureOptions, allow_none=True, default=None ) dPt: list[DataPoint] | None = Field.sequence(expected_type=DataPoint, allow_none=True, default=list) data_points = AliasField("dPt", default=None) dLbls: DataLabelList | None = Field.element( expected_type=DataLabelList, allow_none=True, default=None ) labels = AliasField("dLbls", default=None) trendline: Trendline | None = Field.element(expected_type=Trendline, allow_none=True, default=None) errBars: ErrorBars | None = Field.element(expected_type=ErrorBars, allow_none=True, default=None) cat: AxDataSource | None = Field.element(expected_type=AxDataSource, allow_none=True, default=None) identifiers = AliasField("cat", default=None) val: NumDataSource | None = Field.element(expected_type=NumDataSource, allow_none=True, default=None) extLst: ExtensionList | None = Field.element( expected_type=ExtensionList, allow_none=True, serialize=False, default=None ) invertIfNegative: bool | None = Field.nested_bool(allow_none=True, default=None) shape: str | None = Field.nested_value( expected_type=str, allow_none=True, converter=_shape_converter, default=None, ) xVal: AxDataSource | None = Field.element(expected_type=AxDataSource, allow_none=True, default=None) yVal: NumDataSource | None = Field.element(expected_type=NumDataSource, allow_none=True, default=None) bubbleSize: NumDataSource | None = Field.element( expected_type=NumDataSource, allow_none=True, default=None ) zVal = AliasField("bubbleSize", default=None) bubble3D: bool | None = Field.nested_bool(allow_none=True, default=None) marker: Marker | None = Field.element(expected_type=Marker, allow_none=True, default=None) smooth: bool | None = Field.nested_bool(allow_none=True, default=None) explosion: int | None = Field.nested_value(expected_type=int, allow_none=True, default=None) _serialize_element_order: tuple[str, ...] | None = None def __init__( self, idx=0, order=0, tx=None, spPr=None, pictureOptions=None, dPt=(), dLbls=None, trendline=None, errBars=None, cat=None, val=None, invertIfNegative=None, shape=None, xVal=None, yVal=None, bubbleSize=None, bubble3D=None, marker=None, smooth=None, explosion=None, extLst=None, ): self.idx = idx self.order = order self.tx = tx if spPr is None: spPr = GraphicalProperties() self.spPr = spPr self.pictureOptions = pictureOptions self.dPt = list(dPt) if dPt is not None else [] self.dLbls = dLbls self.trendline = trendline self.errBars = errBars self.cat = cat self.val = val self.invertIfNegative = invertIfNegative self.shape = shape self.xVal = xVal self.yVal = yVal self.bubbleSize = bubbleSize self.bubble3D = bubble3D if marker is None: marker = Marker() self.marker = marker self.smooth = smooth self.explosion = explosion self.extLst = extLst def _element_names_for_serialize(self): order = self._serialize_element_order if order is not None: return tuple(order) return super()._element_names_for_serialize()
[docs] def to_tree(self, tagname=None, idx=None, namespace=None): del namespace if idx is not None: if self.order == self.idx: self.order = idx self.idx = idx return super().to_tree(tagname, idx)
[docs] class XYSeries(Series): pass