about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/pptx/chart/datalabel.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/pptx/chart/datalabel.py')
-rw-r--r--.venv/lib/python3.12/site-packages/pptx/chart/datalabel.py288
1 files changed, 288 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/pptx/chart/datalabel.py b/.venv/lib/python3.12/site-packages/pptx/chart/datalabel.py
new file mode 100644
index 00000000..af7cdf5c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/pptx/chart/datalabel.py
@@ -0,0 +1,288 @@
+"""Data label-related objects."""
+
+from __future__ import annotations
+
+from pptx.text.text import Font, TextFrame
+from pptx.util import lazyproperty
+
+
+class DataLabels(object):
+    """Provides access to properties of data labels for a plot or a series.
+
+    This is not a collection and does not provide access to individual data
+    labels. Access to individual labels is via the |Point| object. The
+    properties this object provides control formatting of *all* the data
+    labels in its scope.
+    """
+
+    def __init__(self, dLbls):
+        super(DataLabels, self).__init__()
+        self._element = dLbls
+
+    @lazyproperty
+    def font(self):
+        """
+        The |Font| object that provides access to the text properties for
+        these data labels, such as bold, italic, etc.
+        """
+        defRPr = self._element.defRPr
+        font = Font(defRPr)
+        return font
+
+    @property
+    def number_format(self):
+        """
+        Read/write string specifying the format for the numbers on this set
+        of data labels. Returns 'General' if no number format has been set.
+        Note that this format string has no effect on rendered data labels
+        when :meth:`number_format_is_linked` is |True|. Assigning a format
+        string to this property automatically sets
+        :meth:`number_format_is_linked` to |False|.
+        """
+        numFmt = self._element.numFmt
+        if numFmt is None:
+            return "General"
+        return numFmt.formatCode
+
+    @number_format.setter
+    def number_format(self, value):
+        self._element.get_or_add_numFmt().formatCode = value
+        self.number_format_is_linked = False
+
+    @property
+    def number_format_is_linked(self):
+        """
+        Read/write boolean specifying whether number formatting should be
+        taken from the source spreadsheet rather than the value of
+        :meth:`number_format`.
+        """
+        numFmt = self._element.numFmt
+        if numFmt is None:
+            return True
+        souceLinked = numFmt.sourceLinked
+        if souceLinked is None:
+            return True
+        return numFmt.sourceLinked
+
+    @number_format_is_linked.setter
+    def number_format_is_linked(self, value):
+        numFmt = self._element.get_or_add_numFmt()
+        numFmt.sourceLinked = value
+
+    @property
+    def position(self):
+        """
+        Read/write :ref:`XlDataLabelPosition` enumeration value specifying
+        the position of the data labels with respect to their data point, or
+        |None| if no position is specified. Assigning |None| causes
+        PowerPoint to choose the default position, which varies by chart
+        type.
+        """
+        dLblPos = self._element.dLblPos
+        if dLblPos is None:
+            return None
+        return dLblPos.val
+
+    @position.setter
+    def position(self, value):
+        if value is None:
+            self._element._remove_dLblPos()
+            return
+        self._element.get_or_add_dLblPos().val = value
+
+    @property
+    def show_category_name(self):
+        """Read/write. True when name of category should appear in label."""
+        return self._element.get_or_add_showCatName().val
+
+    @show_category_name.setter
+    def show_category_name(self, value):
+        self._element.get_or_add_showCatName().val = bool(value)
+
+    @property
+    def show_legend_key(self):
+        """Read/write. True when data label displays legend-color swatch."""
+        return self._element.get_or_add_showLegendKey().val
+
+    @show_legend_key.setter
+    def show_legend_key(self, value):
+        self._element.get_or_add_showLegendKey().val = bool(value)
+
+    @property
+    def show_percentage(self):
+        """Read/write. True when data label displays percentage.
+
+        This option is not operative on all chart types. Percentage appears
+        on polar charts such as pie and donut.
+        """
+        return self._element.get_or_add_showPercent().val
+
+    @show_percentage.setter
+    def show_percentage(self, value):
+        self._element.get_or_add_showPercent().val = bool(value)
+
+    @property
+    def show_series_name(self):
+        """Read/write. True when data label displays series name."""
+        return self._element.get_or_add_showSerName().val
+
+    @show_series_name.setter
+    def show_series_name(self, value):
+        self._element.get_or_add_showSerName().val = bool(value)
+
+    @property
+    def show_value(self):
+        """Read/write. True when label displays numeric value of datapoint."""
+        return self._element.get_or_add_showVal().val
+
+    @show_value.setter
+    def show_value(self, value):
+        self._element.get_or_add_showVal().val = bool(value)
+
+
+class DataLabel(object):
+    """
+    The data label associated with an individual data point.
+    """
+
+    def __init__(self, ser, idx):
+        super(DataLabel, self).__init__()
+        self._ser = self._element = ser
+        self._idx = idx
+
+    @lazyproperty
+    def font(self):
+        """The |Font| object providing text formatting for this data label.
+
+        This font object is used to customize the appearance of automatically
+        inserted text, such as the data point value. The font applies to the
+        entire data label. More granular control of the appearance of custom
+        data label text is controlled by a font object on runs in the text
+        frame.
+        """
+        txPr = self._get_or_add_txPr()
+        text_frame = TextFrame(txPr, self)
+        paragraph = text_frame.paragraphs[0]
+        return paragraph.font
+
+    @property
+    def has_text_frame(self):
+        """
+        Return |True| if this data label has a text frame (implying it has
+        custom data label text), and |False| otherwise. Assigning |True|
+        causes a text frame to be added if not already present. Assigning
+        |False| causes any existing text frame to be removed along with any
+        text contained in the text frame.
+        """
+        dLbl = self._dLbl
+        if dLbl is None:
+            return False
+        if dLbl.xpath("c:tx/c:rich"):
+            return True
+        return False
+
+    @has_text_frame.setter
+    def has_text_frame(self, value):
+        if bool(value) is True:
+            self._get_or_add_tx_rich()
+        else:
+            self._remove_tx_rich()
+
+    @property
+    def position(self):
+        """
+        Read/write :ref:`XlDataLabelPosition` member specifying the position
+        of this data label with respect to its data point, or |None| if no
+        position is specified. Assigning |None| causes PowerPoint to choose
+        the default position, which varies by chart type.
+        """
+        dLbl = self._dLbl
+        if dLbl is None:
+            return None
+        dLblPos = dLbl.dLblPos
+        if dLblPos is None:
+            return None
+        return dLblPos.val
+
+    @position.setter
+    def position(self, value):
+        if value is None:
+            dLbl = self._dLbl
+            if dLbl is None:
+                return
+            dLbl._remove_dLblPos()
+            return
+        dLbl = self._get_or_add_dLbl()
+        dLbl.get_or_add_dLblPos().val = value
+
+    @property
+    def text_frame(self):
+        """
+        |TextFrame| instance for this data label, containing the text of the
+        data label and providing access to its text formatting properties.
+        """
+        rich = self._get_or_add_rich()
+        return TextFrame(rich, self)
+
+    @property
+    def _dLbl(self):
+        """
+        Return the |CT_DLbl| instance referring specifically to this
+        individual data label (having the same index value), or |None| if not
+        present.
+        """
+        return self._ser.get_dLbl(self._idx)
+
+    def _get_or_add_dLbl(self):
+        """
+        The ``CT_DLbl`` instance referring specifically to this individual
+        data label, newly created if not yet present in the XML.
+        """
+        return self._ser.get_or_add_dLbl(self._idx)
+
+    def _get_or_add_rich(self):
+        """
+        Return the `c:rich` element representing the text frame for this data
+        label, newly created with its ancestors if not present.
+        """
+        dLbl = self._get_or_add_dLbl()
+
+        # having a c:spPr or c:txPr when a c:tx is present causes the "can't
+        # save" bug on bubble charts. Remove c:spPr and c:txPr when present.
+        dLbl._remove_spPr()
+        dLbl._remove_txPr()
+
+        return dLbl.get_or_add_rich()
+
+    def _get_or_add_tx_rich(self):
+        """
+        Return the `c:tx` element for this data label, with its `c:rich`
+        child and descendants, newly created if not yet present.
+        """
+        dLbl = self._get_or_add_dLbl()
+
+        # having a c:spPr or c:txPr when a c:tx is present causes the "can't
+        # save" bug on bubble charts. Remove c:spPr and c:txPr when present.
+        dLbl._remove_spPr()
+        dLbl._remove_txPr()
+
+        return dLbl.get_or_add_tx_rich()
+
+    def _get_or_add_txPr(self):
+        """Return the `c:txPr` element for this data label.
+
+        The `c:txPr` element and its parent `c:dLbl` element are created if
+        not yet present.
+        """
+        dLbl = self._get_or_add_dLbl()
+        return dLbl.get_or_add_txPr()
+
+    def _remove_tx_rich(self):
+        """
+        Remove any `c:tx/c:rich` child of the `c:dLbl` element for this data
+        label. Do nothing if that element is not present.
+        """
+        dLbl = self._dLbl
+        if dLbl is None:
+            return
+        dLbl.remove_tx_rich()