PCQRSCANER/venv/Lib/site-packages/pptx/chart/datalabel.py

293 lines
9.3 KiB
Python
Raw Normal View History

2019-12-22 21:51:47 +01:00
# encoding: utf-8
"""
Data label-related objects.
"""
from __future__ import absolute_import, division, print_function, unicode_literals
from ..text.text import Font, TextFrame
from ..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()