Source code for ooodev.format.inner.direct.chart2.series.data_series.options.settings

from __future__ import annotations
from typing import Any, Tuple, cast, overload, NamedTuple
from com.sun.star.chart2 import XChartDocument
from com.sun.star.beans import XPropertySet

from ooodev.format.inner.kind.format_kind import FormatKind
from ooodev.format.inner.style_base import StyleBase
from ooodev.loader import lo as mLo
from ooodev.utils import props as mProps


class _SettingsProps(NamedTuple):
    primary_y_axis: str
    spacing: str
    overlap: str
    side_by_side: str


[docs]class Settings(StyleBase): """ Chart Data Series Settings Note: The axis that the setting are applied to is determined by the axis that the data series is plotted on. For this reason if formatting is applied to a data series axis it should be done before applying ``Settings``. .. seealso:: - :ref:`help_chart2_format_direct_series_series_options` .. versionadded:: 0.9.4 """
[docs] def __init__( self, chart_doc: XChartDocument, *, spacing: int | None = None, overlap: int | None = None, side_by_side: bool | None = None, **kwargs, ) -> None: """ Constructor Args: chart_doc (XChartDocument): Chart document. spacing (int | None, optional): Spacing between bars. Must be a positive integer value. Defaults to ``None``. overlap (int | None, optional): Overlap of bars. Defaults to ``None``. side_by_side (bool | None, optional): Specifies if bars are shown side by side. Defaults to ``None``. Returns: None: See Also: - :ref:`help_chart2_format_direct_series_series_options` """ self._chart_doc = chart_doc super().__init__() if spacing is not None: self.prop_spacing = spacing if overlap is not None: self.prop_overlap = overlap if side_by_side is not None: self.prop_side_by_side = side_by_side
# region Overrides def _supported_services(self) -> Tuple[str, ...]: try: return self._supported_services_values except AttributeError: self._supported_services_values = ("com.sun.star.chart2.DataSeries",) return self._supported_services_values # region apply() @overload def apply(self, obj: Any) -> None: ... @overload def apply(self, obj: Any, **kwargs) -> None: ...
[docs] def apply(self, obj: Any, **kwargs) -> None: """ Applies styles to object Args: obj (object): UNO Object that styles are to be applied. Returns: None: """ # obj is a data series object. if not self._is_valid_obj(obj): self._print_not_valid_srv("apply") return try: diagram = self._chart_doc.getDiagram() # type: ignore except Exception as e: mLo.Lo.print(f"{self.__class__.__name__}.apply() - Unable to apply spacing and overlap.") mLo.Lo.print(f" Error: {e}") return if self.prop_side_by_side is not None: super().apply( obj=diagram, validate=False, override_dv={self._props.side_by_side: self.prop_side_by_side}, **kwargs ) spacing = self.prop_spacing overlap = self.prop_overlap axis_props = {} axis = None if spacing is not None or overlap is not None: try: # get the axis to apply spacing and overlap. # The axis is determined by the primary_y_axis property of the data series. # if primary_y_axis is True, then the YAxis is used, otherwise the SecondaryYAxis is used. is_primary_y = int(mProps.Props.get(obj, self._props.primary_y_axis, 0)) == 0 if is_primary_y: axis = cast(XPropertySet, mProps.Props.get(diagram, "YAxis")) else: axis = cast(XPropertySet, mProps.Props.get(diagram, "SecondaryYAxis")) if spacing is not None: axis_props[self._props.spacing] = spacing if overlap is not None: axis_props[self._props.overlap] = overlap except Exception as e: mLo.Lo.print(f"{self.__class__.__name__}.apply() - Unable to apply spacing and overlap.") mLo.Lo.print(f" Error: {e}") return if axis_props and axis is not None: super().apply(obj=axis, validate=False, override_dv=axis_props, **kwargs)
# endregion apply() # region Copy() @overload def copy(self) -> Settings: ... @overload def copy(self, **kwargs) -> Settings: ...
[docs] def copy(self, **kwargs) -> Settings: """Gets a copy of instance as a new instance""" cp = super().copy(**kwargs) cp._chart_doc = self._chart_doc return cp
# endregion Copy() # endregion Overrides # region Properties @property def prop_format_kind(self) -> FormatKind: """Gets the kind of style""" try: return self._format_kind_prop except AttributeError: self._format_kind_prop = FormatKind.UNKNOWN return self._format_kind_prop @property def prop_spacing(self) -> int | None: """Gets or sets the spacing between bars.""" return self._get(self._props.spacing) @prop_spacing.setter def prop_spacing(self, value: int | None) -> None: if value is None: self._remove(self._props.spacing) return value = max(value, 0) self._set(self._props.spacing, value) @property def prop_overlap(self) -> int | None: """Gets or sets the overlap between bars.""" return self._get(self._props.overlap) @prop_overlap.setter def prop_overlap(self, value: int | None) -> None: if value is None: self._remove(self._props.overlap) return self._set(self._props.overlap, value) @property def prop_side_by_side(self) -> bool | None: """Gets or sets whether bars are side by side.""" pv = cast(bool, self._get(self._props.side_by_side)) # GroupBarsPerAxis is the opposite of SideBySide return None if pv is None else not pv @prop_side_by_side.setter def prop_side_by_side(self, value: bool | None) -> None: if value is None: self._remove(self._props.side_by_side) return # GroupBarsPerAxis is the opposite of SideBySide self._set(self._props.side_by_side, not value) @property def _props(self) -> _SettingsProps: try: return self._props_internal_attributes except AttributeError: self._props_internal_attributes = _SettingsProps( primary_y_axis="AttachedAxisIndex", spacing="GapWidth", overlap="Overlap", side_by_side="GroupBarsPerAxis", ) return self._props_internal_attributes
# endregion Properties