python-pptx2 2.13.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pptx2/__init__.py +152 -0
- pptx2/_color.py +75 -0
- pptx2/_slide_importer.py +597 -0
- pptx2/_svg.py +155 -0
- pptx2/_template_applier.py +292 -0
- pptx2/_textstyle.py +187 -0
- pptx2/accessibility.py +365 -0
- pptx2/action.py +270 -0
- pptx2/animation.py +2237 -0
- pptx2/api.py +49 -0
- pptx2/audit.py +258 -0
- pptx2/chart/__init__.py +0 -0
- pptx2/chart/analytics.py +381 -0
- pptx2/chart/axis.py +543 -0
- pptx2/chart/category.py +200 -0
- pptx2/chart/chart.py +670 -0
- pptx2/chart/data.py +864 -0
- pptx2/chart/datalabel.py +406 -0
- pptx2/chart/legend.py +86 -0
- pptx2/chart/marker.py +70 -0
- pptx2/chart/palettes.py +129 -0
- pptx2/chart/plot.py +462 -0
- pptx2/chart/point.py +101 -0
- pptx2/chart/quick_layouts.py +325 -0
- pptx2/chart/series.py +334 -0
- pptx2/chart/xlsx.py +272 -0
- pptx2/chart/xmlwriter.py +1845 -0
- pptx2/compose/__init__.py +28 -0
- pptx2/compose/from_spec.py +1094 -0
- pptx2/design/__init__.py +8 -0
- pptx2/design/components.py +607 -0
- pptx2/design/figures.py +389 -0
- pptx2/design/layout.py +370 -0
- pptx2/design/recipes.py +1967 -0
- pptx2/design/style.py +209 -0
- pptx2/design/tokens.py +915 -0
- pptx2/diagrams.py +754 -0
- pptx2/dml/__init__.py +0 -0
- pptx2/dml/chtfmt.py +40 -0
- pptx2/dml/color.py +496 -0
- pptx2/dml/effect.py +909 -0
- pptx2/dml/fill.py +691 -0
- pptx2/dml/line.py +287 -0
- pptx2/dml/picture.py +212 -0
- pptx2/dml/three_d.py +381 -0
- pptx2/enum/__init__.py +0 -0
- pptx2/enum/action.py +71 -0
- pptx2/enum/animation.py +31 -0
- pptx2/enum/base.py +218 -0
- pptx2/enum/chart.py +574 -0
- pptx2/enum/dml.py +740 -0
- pptx2/enum/lang.py +685 -0
- pptx2/enum/presentation.py +133 -0
- pptx2/enum/shapes.py +1029 -0
- pptx2/enum/text.py +230 -0
- pptx2/exc.py +42 -0
- pptx2/formats.py +139 -0
- pptx2/geometry.py +420 -0
- pptx2/inherit.py +109 -0
- pptx2/lint.py +2256 -0
- pptx2/math.py +177 -0
- pptx2/media.py +197 -0
- pptx2/opc/__init__.py +0 -0
- pptx2/opc/constants.py +332 -0
- pptx2/opc/oxml.py +188 -0
- pptx2/opc/package.py +762 -0
- pptx2/opc/packuri.py +109 -0
- pptx2/opc/serialized.py +296 -0
- pptx2/opc/shared.py +20 -0
- pptx2/opc/spec.py +45 -0
- pptx2/oxml/__init__.py +555 -0
- pptx2/oxml/action.py +53 -0
- pptx2/oxml/chart/__init__.py +0 -0
- pptx2/oxml/chart/axis.py +337 -0
- pptx2/oxml/chart/chart.py +481 -0
- pptx2/oxml/chart/datalabel.py +253 -0
- pptx2/oxml/chart/legend.py +72 -0
- pptx2/oxml/chart/marker.py +61 -0
- pptx2/oxml/chart/plot.py +365 -0
- pptx2/oxml/chart/series.py +425 -0
- pptx2/oxml/chart/shared.py +220 -0
- pptx2/oxml/coreprops.py +288 -0
- pptx2/oxml/dml/__init__.py +0 -0
- pptx2/oxml/dml/color.py +135 -0
- pptx2/oxml/dml/effect.py +213 -0
- pptx2/oxml/dml/fill.py +316 -0
- pptx2/oxml/dml/line.py +12 -0
- pptx2/oxml/dml/three_d.py +110 -0
- pptx2/oxml/ns.py +135 -0
- pptx2/oxml/presentation.py +313 -0
- pptx2/oxml/shapes/__init__.py +19 -0
- pptx2/oxml/shapes/autoshape.py +467 -0
- pptx2/oxml/shapes/connector.py +107 -0
- pptx2/oxml/shapes/graphfrm.py +347 -0
- pptx2/oxml/shapes/groupshape.py +329 -0
- pptx2/oxml/shapes/picture.py +270 -0
- pptx2/oxml/shapes/shared.py +577 -0
- pptx2/oxml/simpletypes.py +1027 -0
- pptx2/oxml/slide.py +563 -0
- pptx2/oxml/table.py +650 -0
- pptx2/oxml/text.py +815 -0
- pptx2/oxml/theme.py +36 -0
- pptx2/oxml/xmlchemy.py +717 -0
- pptx2/package.py +222 -0
- pptx2/parts/__init__.py +0 -0
- pptx2/parts/chart.py +95 -0
- pptx2/parts/coreprops.py +167 -0
- pptx2/parts/diagram.py +37 -0
- pptx2/parts/embeddedpackage.py +93 -0
- pptx2/parts/image.py +275 -0
- pptx2/parts/media.py +37 -0
- pptx2/parts/presentation.py +136 -0
- pptx2/parts/slide.py +371 -0
- pptx2/presentation.py +408 -0
- pptx2/py.typed +0 -0
- pptx2/render.py +586 -0
- pptx2/section.py +272 -0
- pptx2/shapes/__init__.py +26 -0
- pptx2/shapes/autoshape.py +442 -0
- pptx2/shapes/base.py +1078 -0
- pptx2/shapes/connector.py +297 -0
- pptx2/shapes/freeform.py +337 -0
- pptx2/shapes/graphfrm.py +316 -0
- pptx2/shapes/group.py +264 -0
- pptx2/shapes/picture.py +422 -0
- pptx2/shapes/placeholder.py +468 -0
- pptx2/shapes/shapetree.py +2027 -0
- pptx2/shared.py +82 -0
- pptx2/skill/SKILL.md +450 -0
- pptx2/skill/__init__.py +78 -0
- pptx2/skill/__main__.py +64 -0
- pptx2/skill/references/animations.md +189 -0
- pptx2/skill/references/basics.md +421 -0
- pptx2/skill/references/charts.md +254 -0
- pptx2/skill/references/compose.md +234 -0
- pptx2/skill/references/design.md +366 -0
- pptx2/skill/references/effects.md +249 -0
- pptx2/skill/references/end-to-end-deck.md +231 -0
- pptx2/skill/references/geometry-and-arrows.md +334 -0
- pptx2/skill/references/lint.md +275 -0
- pptx2/skill/references/math.md +86 -0
- pptx2/skill/references/picture-effects.md +129 -0
- pptx2/skill/references/render.md +151 -0
- pptx2/skill/references/smart-art.md +75 -0
- pptx2/skill/references/space-aware-authoring.md +249 -0
- pptx2/skill/references/tables.md +244 -0
- pptx2/skill/references/theme.md +127 -0
- pptx2/skill/references/three-d.md +109 -0
- pptx2/skill/references/transitions.md +100 -0
- pptx2/slide.py +1244 -0
- pptx2/smart_art.py +220 -0
- pptx2/spec.py +633 -0
- pptx2/table.py +1181 -0
- pptx2/table_styles.py +184 -0
- pptx2/templates/default.pptx +0 -0
- pptx2/templates/docx-icon.emf +0 -0
- pptx2/templates/generic-icon.emf +0 -0
- pptx2/templates/notes.xml +23 -0
- pptx2/templates/notesMaster.xml +352 -0
- pptx2/templates/pptx-icon.emf +0 -0
- pptx2/templates/theme.xml +321 -0
- pptx2/templates/xlsx-icon.emf +0 -0
- pptx2/text/__init__.py +0 -0
- pptx2/text/fonts.py +482 -0
- pptx2/text/layout.py +374 -0
- pptx2/text/text.py +1272 -0
- pptx2/theme.py +721 -0
- pptx2/types.py +36 -0
- pptx2/util.py +263 -0
- python_pptx2-2.13.0.dist-info/METADATA +351 -0
- python_pptx2-2.13.0.dist-info/RECORD +175 -0
- python_pptx2-2.13.0.dist-info/WHEEL +5 -0
- python_pptx2-2.13.0.dist-info/entry_points.txt +3 -0
- python_pptx2-2.13.0.dist-info/licenses/LICENSE +22 -0
- python_pptx2-2.13.0.dist-info/top_level.txt +1 -0
pptx2/chart/axis.py
ADDED
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
"""Axis-related chart objects."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pptx2.dml.chtfmt import ChartFormat
|
|
6
|
+
from pptx2.enum.chart import (
|
|
7
|
+
XL_AXIS_CROSSES,
|
|
8
|
+
XL_CATEGORY_TYPE,
|
|
9
|
+
XL_TICK_LABEL_POSITION,
|
|
10
|
+
XL_TICK_MARK,
|
|
11
|
+
)
|
|
12
|
+
from pptx2.oxml.ns import qn
|
|
13
|
+
from pptx2.oxml.simpletypes import ST_Orientation
|
|
14
|
+
from pptx2.shared import ElementProxy
|
|
15
|
+
from pptx2.text.text import Font, TextFrame
|
|
16
|
+
from pptx2.util import lazyproperty
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class _BaseAxis(object):
|
|
20
|
+
"""Base class for chart axis objects. All axis objects share these properties."""
|
|
21
|
+
|
|
22
|
+
def __init__(self, xAx):
|
|
23
|
+
super(_BaseAxis, self).__init__()
|
|
24
|
+
self._element = xAx # axis element, c:catAx or c:valAx
|
|
25
|
+
self._xAx = xAx
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def axis_title(self):
|
|
29
|
+
"""An |AxisTitle| object providing access to title properties.
|
|
30
|
+
|
|
31
|
+
Calling this property is destructive in the sense that it adds an
|
|
32
|
+
axis title element (`c:title`) to the axis XML if one is not already
|
|
33
|
+
present. Use :attr:`has_title` to test for presence of axis title
|
|
34
|
+
non-destructively.
|
|
35
|
+
"""
|
|
36
|
+
return AxisTitle(self._element.get_or_add_title())
|
|
37
|
+
|
|
38
|
+
@lazyproperty
|
|
39
|
+
def format(self):
|
|
40
|
+
"""
|
|
41
|
+
The |ChartFormat| object providing access to the shape formatting
|
|
42
|
+
properties of this axis, such as its line color and fill.
|
|
43
|
+
"""
|
|
44
|
+
return ChartFormat(self._element)
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def has_major_gridlines(self):
|
|
48
|
+
"""
|
|
49
|
+
Read/write boolean value specifying whether this axis has gridlines
|
|
50
|
+
at its major tick mark locations. Assigning |True| to this property
|
|
51
|
+
causes major gridlines to be displayed. Assigning |False| causes them
|
|
52
|
+
to be removed.
|
|
53
|
+
"""
|
|
54
|
+
if self._element.majorGridlines is None:
|
|
55
|
+
return False
|
|
56
|
+
return True
|
|
57
|
+
|
|
58
|
+
@has_major_gridlines.setter
|
|
59
|
+
def has_major_gridlines(self, value):
|
|
60
|
+
if bool(value) is True:
|
|
61
|
+
self._element.get_or_add_majorGridlines()
|
|
62
|
+
else:
|
|
63
|
+
self._element._remove_majorGridlines()
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def has_minor_gridlines(self):
|
|
67
|
+
"""
|
|
68
|
+
Read/write boolean value specifying whether this axis has gridlines
|
|
69
|
+
at its minor tick mark locations. Assigning |True| to this property
|
|
70
|
+
causes minor gridlines to be displayed. Assigning |False| causes them
|
|
71
|
+
to be removed.
|
|
72
|
+
"""
|
|
73
|
+
if self._element.minorGridlines is None:
|
|
74
|
+
return False
|
|
75
|
+
return True
|
|
76
|
+
|
|
77
|
+
@has_minor_gridlines.setter
|
|
78
|
+
def has_minor_gridlines(self, value):
|
|
79
|
+
if bool(value) is True:
|
|
80
|
+
self._element.get_or_add_minorGridlines()
|
|
81
|
+
else:
|
|
82
|
+
self._element._remove_minorGridlines()
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def has_title(self):
|
|
86
|
+
"""Read/write boolean specifying whether this axis has a title.
|
|
87
|
+
|
|
88
|
+
|True| if this axis has a title, |False| otherwise. Assigning |True|
|
|
89
|
+
causes an axis title to be added if not already present. Assigning
|
|
90
|
+
|False| causes any existing title to be deleted.
|
|
91
|
+
"""
|
|
92
|
+
if self._element.title is None:
|
|
93
|
+
return False
|
|
94
|
+
return True
|
|
95
|
+
|
|
96
|
+
@has_title.setter
|
|
97
|
+
def has_title(self, value):
|
|
98
|
+
if bool(value) is True:
|
|
99
|
+
self._element.get_or_add_title()
|
|
100
|
+
else:
|
|
101
|
+
self._element._remove_title()
|
|
102
|
+
|
|
103
|
+
@lazyproperty
|
|
104
|
+
def major_gridlines(self):
|
|
105
|
+
"""
|
|
106
|
+
The |MajorGridlines| object representing the major gridlines for
|
|
107
|
+
this axis.
|
|
108
|
+
"""
|
|
109
|
+
return MajorGridlines(self._element)
|
|
110
|
+
|
|
111
|
+
@property
|
|
112
|
+
def major_tick_mark(self):
|
|
113
|
+
"""
|
|
114
|
+
Read/write :ref:`XlTickMark` value specifying the type of major tick
|
|
115
|
+
mark to display on this axis.
|
|
116
|
+
"""
|
|
117
|
+
majorTickMark = self._element.majorTickMark
|
|
118
|
+
if majorTickMark is None:
|
|
119
|
+
return XL_TICK_MARK.CROSS
|
|
120
|
+
return majorTickMark.val
|
|
121
|
+
|
|
122
|
+
@major_tick_mark.setter
|
|
123
|
+
def major_tick_mark(self, value):
|
|
124
|
+
self._element._remove_majorTickMark()
|
|
125
|
+
if value is XL_TICK_MARK.CROSS:
|
|
126
|
+
return
|
|
127
|
+
self._element._add_majorTickMark(val=value)
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def maximum_scale(self):
|
|
131
|
+
"""
|
|
132
|
+
Read/write float value specifying the upper limit of the value range
|
|
133
|
+
for this axis, the number at the top or right of the vertical or
|
|
134
|
+
horizontal value scale, respectively. The value |None| indicates the
|
|
135
|
+
upper limit should be determined automatically based on the range of
|
|
136
|
+
data point values associated with the axis.
|
|
137
|
+
"""
|
|
138
|
+
return self._element.scaling.maximum
|
|
139
|
+
|
|
140
|
+
@maximum_scale.setter
|
|
141
|
+
def maximum_scale(self, value):
|
|
142
|
+
scaling = self._element.scaling
|
|
143
|
+
scaling.maximum = value
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def minimum_scale(self):
|
|
147
|
+
"""
|
|
148
|
+
Read/write float value specifying lower limit of value range, the
|
|
149
|
+
number at the bottom or left of the value scale. |None| if no minimum
|
|
150
|
+
scale has been set. The value |None| indicates the lower limit should
|
|
151
|
+
be determined automatically based on the range of data point values
|
|
152
|
+
associated with the axis.
|
|
153
|
+
"""
|
|
154
|
+
return self._element.scaling.minimum
|
|
155
|
+
|
|
156
|
+
@minimum_scale.setter
|
|
157
|
+
def minimum_scale(self, value):
|
|
158
|
+
scaling = self._element.scaling
|
|
159
|
+
scaling.minimum = value
|
|
160
|
+
|
|
161
|
+
@property
|
|
162
|
+
def minor_tick_mark(self):
|
|
163
|
+
"""
|
|
164
|
+
Read/write :ref:`XlTickMark` value specifying the type of minor tick
|
|
165
|
+
mark for this axis.
|
|
166
|
+
"""
|
|
167
|
+
minorTickMark = self._element.minorTickMark
|
|
168
|
+
if minorTickMark is None:
|
|
169
|
+
return XL_TICK_MARK.CROSS
|
|
170
|
+
return minorTickMark.val
|
|
171
|
+
|
|
172
|
+
@minor_tick_mark.setter
|
|
173
|
+
def minor_tick_mark(self, value):
|
|
174
|
+
self._element._remove_minorTickMark()
|
|
175
|
+
if value is XL_TICK_MARK.CROSS:
|
|
176
|
+
return
|
|
177
|
+
self._element._add_minorTickMark(val=value)
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def reverse_order(self):
|
|
181
|
+
"""Read/write bool value specifying whether to reverse plotting order for axis.
|
|
182
|
+
|
|
183
|
+
For a category axis, this reverses the order in which the categories are
|
|
184
|
+
displayed. This may be desired, for example, on a (horizontal) bar-chart where
|
|
185
|
+
by default the first category appears at the bottom. Since we read from
|
|
186
|
+
top-to-bottom, many viewers may find it most natural for the first category to
|
|
187
|
+
appear on top.
|
|
188
|
+
|
|
189
|
+
For a value axis, it reverses the direction of increasing value from
|
|
190
|
+
bottom-to-top to top-to-bottom.
|
|
191
|
+
"""
|
|
192
|
+
return self._element.orientation == ST_Orientation.MAX_MIN
|
|
193
|
+
|
|
194
|
+
@reverse_order.setter
|
|
195
|
+
def reverse_order(self, value):
|
|
196
|
+
self._element.orientation = (
|
|
197
|
+
ST_Orientation.MAX_MIN if bool(value) is True else ST_Orientation.MIN_MAX
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
@lazyproperty
|
|
201
|
+
def tick_labels(self):
|
|
202
|
+
"""
|
|
203
|
+
The |TickLabels| instance providing access to axis tick label
|
|
204
|
+
formatting properties. Tick labels are the numbers appearing on
|
|
205
|
+
a value axis or the category names appearing on a category axis.
|
|
206
|
+
"""
|
|
207
|
+
return TickLabels(self._element)
|
|
208
|
+
|
|
209
|
+
@property
|
|
210
|
+
def tick_label_position(self):
|
|
211
|
+
"""
|
|
212
|
+
Read/write :ref:`XlTickLabelPosition` value specifying where the tick
|
|
213
|
+
labels for this axis should appear.
|
|
214
|
+
"""
|
|
215
|
+
tickLblPos = self._element.tickLblPos
|
|
216
|
+
if tickLblPos is None:
|
|
217
|
+
return XL_TICK_LABEL_POSITION.NEXT_TO_AXIS
|
|
218
|
+
if tickLblPos.val is None:
|
|
219
|
+
return XL_TICK_LABEL_POSITION.NEXT_TO_AXIS
|
|
220
|
+
return tickLblPos.val
|
|
221
|
+
|
|
222
|
+
@tick_label_position.setter
|
|
223
|
+
def tick_label_position(self, value):
|
|
224
|
+
tickLblPos = self._element.get_or_add_tickLblPos()
|
|
225
|
+
tickLblPos.val = value
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
def visible(self):
|
|
229
|
+
"""
|
|
230
|
+
Read/write. |True| if axis is visible, |False| otherwise.
|
|
231
|
+
"""
|
|
232
|
+
delete = self._element.delete_
|
|
233
|
+
if delete is None:
|
|
234
|
+
return False
|
|
235
|
+
return False if delete.val else True
|
|
236
|
+
|
|
237
|
+
@visible.setter
|
|
238
|
+
def visible(self, value):
|
|
239
|
+
if value not in (True, False):
|
|
240
|
+
raise ValueError("assigned value must be True or False, got: %s" % value)
|
|
241
|
+
delete = self._element.get_or_add_delete_()
|
|
242
|
+
delete.val = not value
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class AxisTitle(ElementProxy):
|
|
246
|
+
"""Provides properties for manipulating axis title."""
|
|
247
|
+
|
|
248
|
+
def __init__(self, title):
|
|
249
|
+
super(AxisTitle, self).__init__(title)
|
|
250
|
+
self._title = title
|
|
251
|
+
|
|
252
|
+
@lazyproperty
|
|
253
|
+
def format(self):
|
|
254
|
+
"""|ChartFormat| object providing access to shape formatting.
|
|
255
|
+
|
|
256
|
+
Return the |ChartFormat| object providing shape formatting properties
|
|
257
|
+
for this axis title, such as its line color and fill.
|
|
258
|
+
"""
|
|
259
|
+
return ChartFormat(self._element)
|
|
260
|
+
|
|
261
|
+
@property
|
|
262
|
+
def has_text_frame(self):
|
|
263
|
+
"""Read/write Boolean specifying presence of a text frame.
|
|
264
|
+
|
|
265
|
+
Return |True| if this axis title has a text frame, and |False|
|
|
266
|
+
otherwise. Assigning |True| causes a text frame to be added if not
|
|
267
|
+
already present. Assigning |False| causes any existing text frame to
|
|
268
|
+
be removed along with any text contained in the text frame.
|
|
269
|
+
"""
|
|
270
|
+
if self._title.tx_rich is None:
|
|
271
|
+
return False
|
|
272
|
+
return True
|
|
273
|
+
|
|
274
|
+
@has_text_frame.setter
|
|
275
|
+
def has_text_frame(self, value):
|
|
276
|
+
if bool(value) is True:
|
|
277
|
+
self._title.get_or_add_tx_rich()
|
|
278
|
+
else:
|
|
279
|
+
self._title._remove_tx()
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def text_frame(self):
|
|
283
|
+
"""|TextFrame| instance for this axis title.
|
|
284
|
+
|
|
285
|
+
Return a |TextFrame| instance allowing read/write access to the text
|
|
286
|
+
of this axis title and its text formatting properties. Accessing this
|
|
287
|
+
property is destructive as it adds a new text frame if not already
|
|
288
|
+
present.
|
|
289
|
+
"""
|
|
290
|
+
rich = self._title.get_or_add_tx_rich()
|
|
291
|
+
return TextFrame(rich, self)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class CategoryAxis(_BaseAxis):
|
|
295
|
+
"""A category axis of a chart."""
|
|
296
|
+
|
|
297
|
+
@property
|
|
298
|
+
def category_type(self):
|
|
299
|
+
"""
|
|
300
|
+
A member of :ref:`XlCategoryType` specifying the scale type of this
|
|
301
|
+
axis. Unconditionally ``CATEGORY_SCALE`` for a |CategoryAxis| object.
|
|
302
|
+
"""
|
|
303
|
+
return XL_CATEGORY_TYPE.CATEGORY_SCALE
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
class DateAxis(_BaseAxis):
|
|
307
|
+
"""A category axis with dates as its category labels.
|
|
308
|
+
|
|
309
|
+
This axis-type has some special display behaviors such as making length of equal
|
|
310
|
+
periods equal and normalizing month start dates despite unequal month lengths.
|
|
311
|
+
"""
|
|
312
|
+
|
|
313
|
+
@property
|
|
314
|
+
def category_type(self):
|
|
315
|
+
"""
|
|
316
|
+
A member of :ref:`XlCategoryType` specifying the scale type of this
|
|
317
|
+
axis. Unconditionally ``TIME_SCALE`` for a |DateAxis| object.
|
|
318
|
+
"""
|
|
319
|
+
return XL_CATEGORY_TYPE.TIME_SCALE
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
class MajorGridlines(ElementProxy):
|
|
323
|
+
"""Provides access to the properties of the major gridlines appearing on an axis."""
|
|
324
|
+
|
|
325
|
+
def __init__(self, xAx):
|
|
326
|
+
super(MajorGridlines, self).__init__(xAx)
|
|
327
|
+
self._xAx = xAx # axis element, catAx or valAx
|
|
328
|
+
|
|
329
|
+
@lazyproperty
|
|
330
|
+
def format(self):
|
|
331
|
+
"""
|
|
332
|
+
The |ChartFormat| object providing access to the shape formatting
|
|
333
|
+
properties of this data point, such as line and fill.
|
|
334
|
+
"""
|
|
335
|
+
majorGridlines = self._xAx.get_or_add_majorGridlines()
|
|
336
|
+
return ChartFormat(majorGridlines)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
class TickLabels(object):
|
|
340
|
+
"""A service class providing access to formatting of axis tick mark labels."""
|
|
341
|
+
|
|
342
|
+
def __init__(self, xAx_elm):
|
|
343
|
+
super(TickLabels, self).__init__()
|
|
344
|
+
self._element = xAx_elm
|
|
345
|
+
|
|
346
|
+
@lazyproperty
|
|
347
|
+
def font(self):
|
|
348
|
+
"""
|
|
349
|
+
The |Font| object that provides access to the text properties for
|
|
350
|
+
these tick labels, such as bold, italic, etc.
|
|
351
|
+
"""
|
|
352
|
+
defRPr = self._element.defRPr
|
|
353
|
+
font = Font(defRPr)
|
|
354
|
+
return font
|
|
355
|
+
|
|
356
|
+
@property
|
|
357
|
+
def number_format(self):
|
|
358
|
+
"""
|
|
359
|
+
Read/write string (e.g. "$#,##0.00") specifying the format for the
|
|
360
|
+
numbers on this axis. The syntax for these strings is the same as it
|
|
361
|
+
appears in the PowerPoint or Excel UI. Returns 'General' if no number
|
|
362
|
+
format has been set. Note that this format string has no effect on
|
|
363
|
+
rendered tick labels when :meth:`number_format_is_linked` is |True|.
|
|
364
|
+
Assigning a format string to this property automatically sets
|
|
365
|
+
:meth:`number_format_is_linked` to |False|.
|
|
366
|
+
"""
|
|
367
|
+
numFmt = self._element.numFmt
|
|
368
|
+
if numFmt is None:
|
|
369
|
+
return "General"
|
|
370
|
+
return numFmt.formatCode
|
|
371
|
+
|
|
372
|
+
@number_format.setter
|
|
373
|
+
def number_format(self, value):
|
|
374
|
+
numFmt = self._element.get_or_add_numFmt()
|
|
375
|
+
numFmt.formatCode = value
|
|
376
|
+
self.number_format_is_linked = False
|
|
377
|
+
|
|
378
|
+
@property
|
|
379
|
+
def number_format_is_linked(self):
|
|
380
|
+
"""
|
|
381
|
+
Read/write boolean specifying whether number formatting should be
|
|
382
|
+
taken from the source spreadsheet rather than the value of
|
|
383
|
+
:meth:`number_format`.
|
|
384
|
+
"""
|
|
385
|
+
numFmt = self._element.numFmt
|
|
386
|
+
if numFmt is None:
|
|
387
|
+
return False
|
|
388
|
+
souceLinked = numFmt.sourceLinked
|
|
389
|
+
if souceLinked is None:
|
|
390
|
+
return True
|
|
391
|
+
return numFmt.sourceLinked
|
|
392
|
+
|
|
393
|
+
@number_format_is_linked.setter
|
|
394
|
+
def number_format_is_linked(self, value):
|
|
395
|
+
numFmt = self._element.get_or_add_numFmt()
|
|
396
|
+
# `formatCode` is schema-required on <c:numFmt>; default it whenever it's
|
|
397
|
+
# absent (newly created or a pre-existing element that lacks it) so the
|
|
398
|
+
# linked flag can't be toggled into an invalid, PowerPoint-rejected
|
|
399
|
+
# element. An existing explicit value is preserved.
|
|
400
|
+
if numFmt.get("formatCode") is None:
|
|
401
|
+
numFmt.formatCode = "General"
|
|
402
|
+
numFmt.sourceLinked = value
|
|
403
|
+
|
|
404
|
+
@property
|
|
405
|
+
def offset(self):
|
|
406
|
+
"""
|
|
407
|
+
Read/write int value in range 0-1000 specifying the spacing between
|
|
408
|
+
the tick mark labels and the axis as a percentange of the default
|
|
409
|
+
value. 100 if no label offset setting is present.
|
|
410
|
+
"""
|
|
411
|
+
lblOffset = self._element.lblOffset
|
|
412
|
+
if lblOffset is None:
|
|
413
|
+
return 100
|
|
414
|
+
return lblOffset.val
|
|
415
|
+
|
|
416
|
+
@offset.setter
|
|
417
|
+
def offset(self, value):
|
|
418
|
+
if self._element.tag != qn("c:catAx"):
|
|
419
|
+
raise ValueError("only a category axis has an offset")
|
|
420
|
+
self._element._remove_lblOffset()
|
|
421
|
+
if value == 100:
|
|
422
|
+
return
|
|
423
|
+
lblOffset = self._element._add_lblOffset()
|
|
424
|
+
lblOffset.val = value
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
class ValueAxis(_BaseAxis):
|
|
428
|
+
"""An axis having continuous (as opposed to discrete) values.
|
|
429
|
+
|
|
430
|
+
The vertical axis is generally a value axis, however both axes of an XY-type chart
|
|
431
|
+
are value axes.
|
|
432
|
+
"""
|
|
433
|
+
|
|
434
|
+
@property
|
|
435
|
+
def crosses(self):
|
|
436
|
+
"""
|
|
437
|
+
Member of :ref:`XlAxisCrosses` enumeration specifying the point on
|
|
438
|
+
this axis where the other axis crosses, such as auto/zero, minimum,
|
|
439
|
+
or maximum. Returns `XL_AXIS_CROSSES.CUSTOM` when a specific numeric
|
|
440
|
+
crossing point (e.g. 1.5) is defined.
|
|
441
|
+
"""
|
|
442
|
+
crosses = self._cross_xAx.crosses
|
|
443
|
+
if crosses is None:
|
|
444
|
+
return XL_AXIS_CROSSES.CUSTOM
|
|
445
|
+
return crosses.val
|
|
446
|
+
|
|
447
|
+
@crosses.setter
|
|
448
|
+
def crosses(self, value):
|
|
449
|
+
cross_xAx = self._cross_xAx
|
|
450
|
+
if value == XL_AXIS_CROSSES.CUSTOM:
|
|
451
|
+
if cross_xAx.crossesAt is not None:
|
|
452
|
+
return
|
|
453
|
+
cross_xAx._remove_crosses()
|
|
454
|
+
cross_xAx._remove_crossesAt()
|
|
455
|
+
if value == XL_AXIS_CROSSES.CUSTOM:
|
|
456
|
+
cross_xAx._add_crossesAt(val=0.0)
|
|
457
|
+
else:
|
|
458
|
+
cross_xAx._add_crosses(val=value)
|
|
459
|
+
|
|
460
|
+
@property
|
|
461
|
+
def crosses_at(self):
|
|
462
|
+
"""
|
|
463
|
+
Numeric value on this axis at which the perpendicular axis crosses.
|
|
464
|
+
Returns |None| if no crossing value is set.
|
|
465
|
+
"""
|
|
466
|
+
crossesAt = self._cross_xAx.crossesAt
|
|
467
|
+
if crossesAt is None:
|
|
468
|
+
return None
|
|
469
|
+
return crossesAt.val
|
|
470
|
+
|
|
471
|
+
@crosses_at.setter
|
|
472
|
+
def crosses_at(self, value):
|
|
473
|
+
cross_xAx = self._cross_xAx
|
|
474
|
+
cross_xAx._remove_crosses()
|
|
475
|
+
cross_xAx._remove_crossesAt()
|
|
476
|
+
if value is None:
|
|
477
|
+
return
|
|
478
|
+
cross_xAx._add_crossesAt(val=value)
|
|
479
|
+
|
|
480
|
+
@property
|
|
481
|
+
def log_base(self):
|
|
482
|
+
"""
|
|
483
|
+
Read/write float specifying the base of the logarithmic scale for this
|
|
484
|
+
value axis. |None| (the default) indicates a linear scale. Valid
|
|
485
|
+
values are in range 2 to 1000 inclusive. Assigning |None| removes the
|
|
486
|
+
log scale, restoring a linear axis.
|
|
487
|
+
"""
|
|
488
|
+
return self._element.scaling.log_base
|
|
489
|
+
|
|
490
|
+
@log_base.setter
|
|
491
|
+
def log_base(self, value):
|
|
492
|
+
self._element.scaling.log_base = value
|
|
493
|
+
|
|
494
|
+
@property
|
|
495
|
+
def major_unit(self):
|
|
496
|
+
"""
|
|
497
|
+
The float number of units between major tick marks on this value
|
|
498
|
+
axis. |None| corresponds to the 'Auto' setting in the UI, and
|
|
499
|
+
specifies the value should be calculated by PowerPoint based on the
|
|
500
|
+
underlying chart data.
|
|
501
|
+
"""
|
|
502
|
+
majorUnit = self._element.majorUnit
|
|
503
|
+
if majorUnit is None:
|
|
504
|
+
return None
|
|
505
|
+
return majorUnit.val
|
|
506
|
+
|
|
507
|
+
@major_unit.setter
|
|
508
|
+
def major_unit(self, value):
|
|
509
|
+
self._element._remove_majorUnit()
|
|
510
|
+
if value is None:
|
|
511
|
+
return
|
|
512
|
+
self._element._add_majorUnit(val=value)
|
|
513
|
+
|
|
514
|
+
@property
|
|
515
|
+
def minor_unit(self):
|
|
516
|
+
"""
|
|
517
|
+
The float number of units between minor tick marks on this value
|
|
518
|
+
axis. |None| corresponds to the 'Auto' setting in the UI, and
|
|
519
|
+
specifies the value should be calculated by PowerPoint based on the
|
|
520
|
+
underlying chart data.
|
|
521
|
+
"""
|
|
522
|
+
minorUnit = self._element.minorUnit
|
|
523
|
+
if minorUnit is None:
|
|
524
|
+
return None
|
|
525
|
+
return minorUnit.val
|
|
526
|
+
|
|
527
|
+
@minor_unit.setter
|
|
528
|
+
def minor_unit(self, value):
|
|
529
|
+
self._element._remove_minorUnit()
|
|
530
|
+
if value is None:
|
|
531
|
+
return
|
|
532
|
+
self._element._add_minorUnit(val=value)
|
|
533
|
+
|
|
534
|
+
@property
|
|
535
|
+
def _cross_xAx(self):
|
|
536
|
+
"""
|
|
537
|
+
The axis element in the same group (primary/secondary) that crosses
|
|
538
|
+
this axis.
|
|
539
|
+
"""
|
|
540
|
+
crossAx_id = self._element.crossAx.val
|
|
541
|
+
expr = '(../c:catAx | ../c:valAx | ../c:dateAx)/c:axId[@val="%d"]' % crossAx_id
|
|
542
|
+
cross_axId = self._element.xpath(expr)[0]
|
|
543
|
+
return cross_axId.getparent()
|