# Autogenerated schema
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 ._chart import ChartBase
from .axis import ChartLines
from .descriptors import NestedGapAmount
from .series import Series
from .label import DataLabelList
def _bounded_int(value, lo: int, hi: int, name: str):
if value is None:
return None
try:
n = int(value)
except (TypeError, ValueError) as exc:
raise FieldValidationError(f"{name} rejected value {value!r}") from exc
if n < lo or n > hi:
raise FieldValidationError(f"{name} rejected value {value!r}")
return n
def _of_pie_type(v):
if v is None:
return None
if v not in ("pie", "bar"):
raise FieldValidationError(f"ofPieType rejected value {v!r}")
return v
def _split_type(v):
if v is None or v == "none":
return None
allowed = frozenset({"auto", "cust", "percent", "pos", "val"})
if v not in allowed:
raise FieldValidationError(f"splitType rejected value {v!r}")
return v
class _PieChartBase(ChartBase):
varyColors: bool | None = Field.nested_bool(allow_none=True, default=None)
ser: list[Series] | None = Field.sequence(expected_type=Series, allow_none=True, default=list)
dLbls: DataLabelList | None = Field.element(
expected_type=DataLabelList, allow_none=True, default=None
)
dataLabels = AliasField("dLbls", default=None)
_series_type = "pie"
xml_order = ("varyColors", "ser", "dLbls")
def __init__(self, varyColors=True, ser=(), dLbls=None, **kw):
self.varyColors = varyColors
self.ser = list(ser) if ser is not None else []
self.dLbls = dLbls
super().__init__(**kw)
[docs]
class PieChart(_PieChartBase):
tagname = "pieChart"
firstSliceAng: int | None = Field.nested_value(
expected_type=int,
allow_none=True,
converter=lambda v: _bounded_int(v, 0, 360, "firstSliceAng"), default=None,
)
extLst: ExtensionList | None = Field.element(
expected_type=ExtensionList, allow_none=True, serialize=False, default=None
)
xml_order = _PieChartBase.xml_order + ("firstSliceAng",)
def __init__(self, firstSliceAng=0, extLst=None, **kw):
self.firstSliceAng = firstSliceAng
self.extLst = extLst
super().__init__(**kw)
[docs]
class PieChart3D(_PieChartBase):
tagname = "pie3DChart"
extLst: ExtensionList | None = Field.element(
expected_type=ExtensionList, allow_none=True, serialize=False, default=None
)
xml_order = _PieChartBase.xml_order
def __init__(self, extLst=None, **kw):
self.extLst = extLst
super().__init__(**kw)
[docs]
class DoughnutChart(_PieChartBase):
tagname = "doughnutChart"
firstSliceAng: int | None = Field.nested_value(
expected_type=int,
allow_none=True,
converter=lambda v: _bounded_int(v, 0, 360, "firstSliceAng"), default=None,
)
holeSize: int | None = Field.nested_value(
expected_type=int,
allow_none=True,
converter=lambda v: _bounded_int(v, 1, 90, "holeSize"), default=None,
)
extLst: ExtensionList | None = Field.element(
expected_type=ExtensionList, allow_none=True, serialize=False, default=None
)
xml_order = _PieChartBase.xml_order + ("firstSliceAng", "holeSize")
def __init__(self, firstSliceAng=0, holeSize=10, extLst=None, **kw):
self.firstSliceAng = firstSliceAng
self.holeSize = holeSize
self.extLst = extLst
super().__init__(**kw)
[docs]
class CustomSplit(Serialisable):
tagname = "custSplit"
secondPiePt: list[int] | None = Field.sequence(
expected_type=int,
allow_none=True,
primitive_attribute="val", default=list,
)
xml_order = ("secondPiePt",)
def __init__(self, secondPiePt=()):
self.secondPiePt = list(secondPiePt) if secondPiePt is not None else []
[docs]
class ProjectedPieChart(_PieChartBase):
"""
From the spec 21.2.2.126
This element contains the pie of pie or bar of pie series on this
chart. Only the first series shall be displayed. The splitType element
shall determine whether the splitPos and custSplit elements apply.
"""
tagname = "ofPieChart"
ofPieType: str | None = Field.nested_value(
expected_type=str,
allow_none=True,
converter=_of_pie_type, default=None,
)
type = AliasField("ofPieType", default=None)
gapWidth = NestedGapAmount
splitType: str | None = Field.nested_value(
expected_type=str,
allow_none=True,
converter=_split_type, default=None,
)
splitPos: float | None = Field.nested_value(expected_type=float, allow_none=True, default=None)
custSplit: CustomSplit | None = Field.element(expected_type=CustomSplit, allow_none=True, default=None)
secondPieSize: int | None = Field.nested_value(
expected_type=int,
allow_none=True,
converter=lambda v: _bounded_int(v, 5, 200, "secondPieSize"), default=None,
)
serLines: ChartLines | None = Field.element(expected_type=ChartLines, allow_none=True, default=None)
join_lines = AliasField("serLines", default=None)
extLst: ExtensionList | None = Field.element(
expected_type=ExtensionList, allow_none=True, serialize=False, default=None
)
xml_order = _PieChartBase.xml_order + (
"ofPieType",
"gapWidth",
"splitType",
"splitPos",
"custSplit",
"secondPieSize",
"serLines",
)
def __init__(
self,
ofPieType="pie",
gapWidth=None,
splitType="auto",
splitPos=None,
custSplit=None,
secondPieSize=75,
serLines=None,
extLst=None,
**kw,
):
self.ofPieType = ofPieType
self.gapWidth = gapWidth
self.splitType = splitType
self.splitPos = splitPos
self.custSplit = custSplit
self.secondPieSize = secondPieSize
if serLines is None:
serLines = ChartLines()
self.serLines = serLines
self.extLst = extLst
super().__init__(**kw)