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
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
"""Series-related oxml objects."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pptx2.enum.chart import (
|
|
6
|
+
XL_ERROR_BAR_DIRECTION,
|
|
7
|
+
XL_ERROR_BAR_INCLUDE,
|
|
8
|
+
XL_ERROR_BAR_TYPE,
|
|
9
|
+
XL_TRENDLINE_TYPE,
|
|
10
|
+
)
|
|
11
|
+
from pptx2.oxml import parse_xml
|
|
12
|
+
from pptx2.oxml.chart.datalabel import CT_DLbls
|
|
13
|
+
from pptx2.oxml.ns import nsdecls
|
|
14
|
+
from pptx2.oxml.simpletypes import XsdUnsignedInt
|
|
15
|
+
from pptx2.oxml.xmlchemy import (
|
|
16
|
+
BaseOxmlElement,
|
|
17
|
+
OneAndOnlyOne,
|
|
18
|
+
OptionalAttribute,
|
|
19
|
+
OxmlElement,
|
|
20
|
+
RequiredAttribute,
|
|
21
|
+
ZeroOrMore,
|
|
22
|
+
ZeroOrOne,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class CT_AxDataSource(BaseOxmlElement):
|
|
27
|
+
"""
|
|
28
|
+
``<c:cat>`` custom element class used in category charts to specify
|
|
29
|
+
category labels and hierarchy.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
multiLvlStrRef = ZeroOrOne("c:multiLvlStrRef", successors=())
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def lvls(self):
|
|
36
|
+
"""
|
|
37
|
+
Return a list containing the `c:lvl` descendent elements in document
|
|
38
|
+
order. These will only be present when the required single child
|
|
39
|
+
is a `c:multiLvlStrRef` element. Returns an empty list when no
|
|
40
|
+
`c:lvl` descendent elements are present.
|
|
41
|
+
"""
|
|
42
|
+
return self.xpath(".//c:lvl")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class CT_DPt(BaseOxmlElement):
|
|
46
|
+
"""
|
|
47
|
+
``<c:dPt>`` custom element class, containing visual properties for a data
|
|
48
|
+
point.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
_tag_seq = (
|
|
52
|
+
"c:idx",
|
|
53
|
+
"c:invertIfNegative",
|
|
54
|
+
"c:marker",
|
|
55
|
+
"c:bubble3D",
|
|
56
|
+
"c:explosion",
|
|
57
|
+
"c:spPr",
|
|
58
|
+
"c:pictureOptions",
|
|
59
|
+
"c:extLst",
|
|
60
|
+
)
|
|
61
|
+
idx = OneAndOnlyOne("c:idx")
|
|
62
|
+
marker = ZeroOrOne("c:marker", successors=_tag_seq[3:])
|
|
63
|
+
spPr = ZeroOrOne("c:spPr", successors=_tag_seq[6:])
|
|
64
|
+
del _tag_seq
|
|
65
|
+
|
|
66
|
+
@classmethod
|
|
67
|
+
def new_dPt(cls):
|
|
68
|
+
"""
|
|
69
|
+
Return a newly created "loose" `c:dPt` element containing its default
|
|
70
|
+
subtree.
|
|
71
|
+
"""
|
|
72
|
+
dPt = OxmlElement("c:dPt")
|
|
73
|
+
dPt.append(OxmlElement("c:idx"))
|
|
74
|
+
return dPt
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class CT_Lvl(BaseOxmlElement):
|
|
78
|
+
"""
|
|
79
|
+
``<c:lvl>`` custom element class used in multi-level categories to
|
|
80
|
+
specify a level of hierarchy.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
pt = ZeroOrMore("c:pt", successors=())
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class CT_NumDataSource(BaseOxmlElement):
|
|
87
|
+
"""
|
|
88
|
+
``<c:yVal>`` custom element class used in XY and bubble charts, and
|
|
89
|
+
perhaps others.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
numRef = OneAndOnlyOne("c:numRef")
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def ptCount_val(self):
|
|
96
|
+
"""
|
|
97
|
+
Return the value of `./c:numRef/c:numCache/c:ptCount/@val`,
|
|
98
|
+
specifying how many `c:pt` elements are in this numeric data cache.
|
|
99
|
+
Returns 0 if no `c:ptCount` element is present, as this is the least
|
|
100
|
+
disruptive way to degrade when no cached point data is available.
|
|
101
|
+
This situation is not expected, but is valid according to the schema.
|
|
102
|
+
"""
|
|
103
|
+
results = self.xpath(".//c:ptCount/@val")
|
|
104
|
+
return int(results[0]) if results else 0
|
|
105
|
+
|
|
106
|
+
def pt_v(self, idx):
|
|
107
|
+
"""
|
|
108
|
+
Return the Y value for data point *idx* in this cache, or None if no
|
|
109
|
+
value is present for that data point.
|
|
110
|
+
"""
|
|
111
|
+
results = self.xpath(".//c:pt[@idx=%d]" % idx)
|
|
112
|
+
return results[0].value if results else None
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class CT_SeriesComposite(BaseOxmlElement):
|
|
116
|
+
"""
|
|
117
|
+
``<c:ser>`` custom element class. Note there are several different series
|
|
118
|
+
element types in the schema, such as ``CT_LineSer`` and ``CT_BarSer``,
|
|
119
|
+
but they all share the same tag name. This class acts as a composite and
|
|
120
|
+
depends on the caller not to do anything invalid for a series belonging
|
|
121
|
+
to a particular plot type.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
_tag_seq = (
|
|
125
|
+
"c:idx",
|
|
126
|
+
"c:order",
|
|
127
|
+
"c:tx",
|
|
128
|
+
"c:spPr",
|
|
129
|
+
"c:invertIfNegative",
|
|
130
|
+
"c:pictureOptions",
|
|
131
|
+
"c:marker",
|
|
132
|
+
"c:explosion",
|
|
133
|
+
"c:dPt",
|
|
134
|
+
"c:dLbls",
|
|
135
|
+
"c:trendline",
|
|
136
|
+
"c:errBars",
|
|
137
|
+
"c:cat",
|
|
138
|
+
"c:val",
|
|
139
|
+
"c:xVal",
|
|
140
|
+
"c:yVal",
|
|
141
|
+
"c:shape",
|
|
142
|
+
"c:smooth",
|
|
143
|
+
"c:bubbleSize",
|
|
144
|
+
"c:bubble3D",
|
|
145
|
+
"c:extLst",
|
|
146
|
+
)
|
|
147
|
+
idx = OneAndOnlyOne("c:idx")
|
|
148
|
+
order = OneAndOnlyOne("c:order")
|
|
149
|
+
tx = ZeroOrOne("c:tx", successors=_tag_seq[3:])
|
|
150
|
+
spPr = ZeroOrOne("c:spPr", successors=_tag_seq[4:])
|
|
151
|
+
invertIfNegative = ZeroOrOne("c:invertIfNegative", successors=_tag_seq[5:])
|
|
152
|
+
marker = ZeroOrOne("c:marker", successors=_tag_seq[7:])
|
|
153
|
+
dPt = ZeroOrMore("c:dPt", successors=_tag_seq[9:])
|
|
154
|
+
dLbls = ZeroOrOne("c:dLbls", successors=_tag_seq[10:])
|
|
155
|
+
trendline = ZeroOrMore("c:trendline", successors=_tag_seq[11:])
|
|
156
|
+
errBars = ZeroOrOne("c:errBars", successors=_tag_seq[12:])
|
|
157
|
+
cat = ZeroOrOne("c:cat", successors=_tag_seq[13:])
|
|
158
|
+
val = ZeroOrOne("c:val", successors=_tag_seq[14:])
|
|
159
|
+
xVal = ZeroOrOne("c:xVal", successors=_tag_seq[15:])
|
|
160
|
+
yVal = ZeroOrOne("c:yVal", successors=_tag_seq[16:])
|
|
161
|
+
smooth = ZeroOrOne("c:smooth", successors=_tag_seq[18:])
|
|
162
|
+
bubbleSize = ZeroOrOne("c:bubbleSize", successors=_tag_seq[19:])
|
|
163
|
+
del _tag_seq
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def bubbleSize_ptCount_val(self):
|
|
167
|
+
"""
|
|
168
|
+
Return the number of bubble size values as reflected in the `val`
|
|
169
|
+
attribute of `./c:bubbleSize//c:ptCount`, or 0 if not present.
|
|
170
|
+
"""
|
|
171
|
+
vals = self.xpath("./c:bubbleSize//c:ptCount/@val")
|
|
172
|
+
if not vals:
|
|
173
|
+
return 0
|
|
174
|
+
return int(vals[0])
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def cat_ptCount_val(self):
|
|
178
|
+
"""
|
|
179
|
+
Return the number of categories as reflected in the `val` attribute
|
|
180
|
+
of `./c:cat//c:ptCount`, or 0 if not present.
|
|
181
|
+
"""
|
|
182
|
+
vals = self.xpath("./c:cat//c:ptCount/@val")
|
|
183
|
+
if not vals:
|
|
184
|
+
return 0
|
|
185
|
+
return int(vals[0])
|
|
186
|
+
|
|
187
|
+
def get_dLbl(self, idx):
|
|
188
|
+
"""
|
|
189
|
+
Return the `c:dLbl` element representing the label for the data point
|
|
190
|
+
at offset *idx* in this series, or |None| if not present.
|
|
191
|
+
"""
|
|
192
|
+
dLbls = self.dLbls
|
|
193
|
+
if dLbls is None:
|
|
194
|
+
return None
|
|
195
|
+
return dLbls.get_dLbl_for_point(idx)
|
|
196
|
+
|
|
197
|
+
def get_or_add_dLbl(self, idx):
|
|
198
|
+
"""
|
|
199
|
+
Return the `c:dLbl` element representing the label of the point at
|
|
200
|
+
offset *idx* in this series, newly created if not yet present.
|
|
201
|
+
"""
|
|
202
|
+
dLbls = self.get_or_add_dLbls()
|
|
203
|
+
return dLbls.get_or_add_dLbl_for_point(idx)
|
|
204
|
+
|
|
205
|
+
def get_or_add_dPt_for_point(self, idx):
|
|
206
|
+
"""
|
|
207
|
+
Return the `c:dPt` child representing the visual properties of the
|
|
208
|
+
data point at index *idx*.
|
|
209
|
+
"""
|
|
210
|
+
matches = self.xpath('c:dPt[c:idx[@val="%d"]]' % idx)
|
|
211
|
+
if matches:
|
|
212
|
+
return matches[0]
|
|
213
|
+
dPt = self._add_dPt()
|
|
214
|
+
dPt.idx.val = idx
|
|
215
|
+
return dPt
|
|
216
|
+
|
|
217
|
+
@property
|
|
218
|
+
def xVal_ptCount_val(self):
|
|
219
|
+
"""
|
|
220
|
+
Return the number of X values as reflected in the `val` attribute of
|
|
221
|
+
`./c:xVal//c:ptCount`, or 0 if not present.
|
|
222
|
+
"""
|
|
223
|
+
vals = self.xpath("./c:xVal//c:ptCount/@val")
|
|
224
|
+
if not vals:
|
|
225
|
+
return 0
|
|
226
|
+
return int(vals[0])
|
|
227
|
+
|
|
228
|
+
@property
|
|
229
|
+
def yVal_ptCount_val(self):
|
|
230
|
+
"""
|
|
231
|
+
Return the number of Y values as reflected in the `val` attribute of
|
|
232
|
+
`./c:yVal//c:ptCount`, or 0 if not present.
|
|
233
|
+
"""
|
|
234
|
+
vals = self.xpath("./c:yVal//c:ptCount/@val")
|
|
235
|
+
if not vals:
|
|
236
|
+
return 0
|
|
237
|
+
return int(vals[0])
|
|
238
|
+
|
|
239
|
+
def _new_dLbls(self):
|
|
240
|
+
"""Override metaclass method that creates `c:dLbls` element."""
|
|
241
|
+
return CT_DLbls.new_dLbls()
|
|
242
|
+
|
|
243
|
+
def _new_dPt(self):
|
|
244
|
+
"""
|
|
245
|
+
Overrides the metaclass generated method to get `c:dPt` with minimal
|
|
246
|
+
subtree.
|
|
247
|
+
"""
|
|
248
|
+
return CT_DPt.new_dPt()
|
|
249
|
+
|
|
250
|
+
def _new_errBars(self):
|
|
251
|
+
"""Override metaclass method to create a schema-valid `c:errBars`.
|
|
252
|
+
|
|
253
|
+
A bare ``<c:errBars/>`` is invalid (the `errBarType` and `errValType`
|
|
254
|
+
children are schema-required); seed those defaults so the element is
|
|
255
|
+
valid the moment it is materialised.
|
|
256
|
+
"""
|
|
257
|
+
return CT_ErrBars.new_errBars()
|
|
258
|
+
|
|
259
|
+
def _new_trendline(self):
|
|
260
|
+
"""Override metaclass method to create a schema-valid `c:trendline`.
|
|
261
|
+
|
|
262
|
+
Seeds the required ``<c:trendlineType>`` child (defaulting to
|
|
263
|
+
``linear``) so the element is schema-valid on creation.
|
|
264
|
+
"""
|
|
265
|
+
return CT_Trendline.new_trendline()
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
class CT_StrVal_NumVal_Composite(BaseOxmlElement):
|
|
269
|
+
"""
|
|
270
|
+
``<c:pt>`` element, can be either CT_StrVal or CT_NumVal complex type.
|
|
271
|
+
Using this class for both, differentiating as needed.
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
v = OneAndOnlyOne("c:v")
|
|
275
|
+
idx = RequiredAttribute("idx", XsdUnsignedInt)
|
|
276
|
+
|
|
277
|
+
@property
|
|
278
|
+
def value(self):
|
|
279
|
+
"""
|
|
280
|
+
The float value of the text in the required ``<c:v>`` child.
|
|
281
|
+
"""
|
|
282
|
+
return float(self.v.text)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
class CT_TrendlineType(BaseOxmlElement):
|
|
286
|
+
"""``<c:trendlineType>`` element, the kind of trendline curve to fit."""
|
|
287
|
+
|
|
288
|
+
val = OptionalAttribute("val", XL_TRENDLINE_TYPE, default=XL_TRENDLINE_TYPE.LINEAR)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
class CT_Trendline(BaseOxmlElement):
|
|
292
|
+
"""``<c:trendline>`` element, an analytical trend curve fitted to a series."""
|
|
293
|
+
|
|
294
|
+
_tag_seq = (
|
|
295
|
+
"c:name",
|
|
296
|
+
"c:spPr",
|
|
297
|
+
"c:trendlineType",
|
|
298
|
+
"c:order",
|
|
299
|
+
"c:period",
|
|
300
|
+
"c:forward",
|
|
301
|
+
"c:backward",
|
|
302
|
+
"c:intercept",
|
|
303
|
+
"c:dispRSqr",
|
|
304
|
+
"c:dispEq",
|
|
305
|
+
"c:trendlineLbl",
|
|
306
|
+
"c:extLst",
|
|
307
|
+
)
|
|
308
|
+
name = ZeroOrOne("c:name", successors=_tag_seq[1:])
|
|
309
|
+
spPr = ZeroOrOne("c:spPr", successors=_tag_seq[2:])
|
|
310
|
+
trendlineType = OneAndOnlyOne("c:trendlineType")
|
|
311
|
+
order = ZeroOrOne("c:order", successors=_tag_seq[4:])
|
|
312
|
+
period = ZeroOrOne("c:period", successors=_tag_seq[5:])
|
|
313
|
+
forward = ZeroOrOne("c:forward", successors=_tag_seq[6:])
|
|
314
|
+
backward = ZeroOrOne("c:backward", successors=_tag_seq[7:])
|
|
315
|
+
intercept = ZeroOrOne("c:intercept", successors=_tag_seq[8:])
|
|
316
|
+
dispRSqr = ZeroOrOne("c:dispRSqr", successors=_tag_seq[9:])
|
|
317
|
+
dispEq = ZeroOrOne("c:dispEq", successors=_tag_seq[10:])
|
|
318
|
+
del _tag_seq
|
|
319
|
+
|
|
320
|
+
@classmethod
|
|
321
|
+
def new_trendline(cls):
|
|
322
|
+
"""Return a newly created "loose" `c:trendline` element.
|
|
323
|
+
|
|
324
|
+
Contains the single required `c:trendlineType` child, defaulting to
|
|
325
|
+
``linear``, so the element is schema-valid the moment it is created.
|
|
326
|
+
"""
|
|
327
|
+
return parse_xml(
|
|
328
|
+
'<c:trendline %s><c:trendlineType val="linear"/></c:trendline>' % nsdecls("c")
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
class CT_TrendlineName(BaseOxmlElement):
|
|
333
|
+
"""``<c:name>`` child of `c:trendline`, a plain-string legend label."""
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
class CT_ErrBars(BaseOxmlElement):
|
|
337
|
+
"""``<c:errBars>`` element, error bars drawn from each data point."""
|
|
338
|
+
|
|
339
|
+
_tag_seq = (
|
|
340
|
+
"c:errDir",
|
|
341
|
+
"c:errBarType",
|
|
342
|
+
"c:errValType",
|
|
343
|
+
"c:noEndCap",
|
|
344
|
+
"c:plus",
|
|
345
|
+
"c:minus",
|
|
346
|
+
"c:val",
|
|
347
|
+
"c:spPr",
|
|
348
|
+
"c:extLst",
|
|
349
|
+
)
|
|
350
|
+
errDir = ZeroOrOne("c:errDir", successors=_tag_seq[1:])
|
|
351
|
+
errBarType = ZeroOrOne("c:errBarType", successors=_tag_seq[2:])
|
|
352
|
+
errValType = ZeroOrOne("c:errValType", successors=_tag_seq[3:])
|
|
353
|
+
noEndCap = ZeroOrOne("c:noEndCap", successors=_tag_seq[4:])
|
|
354
|
+
plus = ZeroOrOne("c:plus", successors=_tag_seq[5:])
|
|
355
|
+
minus = ZeroOrOne("c:minus", successors=_tag_seq[6:])
|
|
356
|
+
val = ZeroOrOne("c:val", successors=_tag_seq[7:])
|
|
357
|
+
spPr = ZeroOrOne("c:spPr", successors=_tag_seq[8:])
|
|
358
|
+
del _tag_seq
|
|
359
|
+
|
|
360
|
+
@classmethod
|
|
361
|
+
def new_errBars(cls):
|
|
362
|
+
"""Return a newly created "loose" `c:errBars` element.
|
|
363
|
+
|
|
364
|
+
The element contains the two schema-required children
|
|
365
|
+
(`c:errBarType` and `c:errValType`) so it is schema-valid the moment
|
|
366
|
+
it is created.
|
|
367
|
+
"""
|
|
368
|
+
return parse_xml(
|
|
369
|
+
"<c:errBars %s>\n"
|
|
370
|
+
' <c:errBarType val="both"/>\n'
|
|
371
|
+
' <c:errValType val="fixedVal"/>\n'
|
|
372
|
+
"</c:errBars>\n" % nsdecls("c")
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
class CT_ErrDir(BaseOxmlElement):
|
|
377
|
+
"""``<c:errDir>`` element, the axis along which error bars are drawn."""
|
|
378
|
+
|
|
379
|
+
val = RequiredAttribute("val", XL_ERROR_BAR_DIRECTION)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
class CT_ErrBarType(BaseOxmlElement):
|
|
383
|
+
"""``<c:errBarType>`` element, the direction error bars extend."""
|
|
384
|
+
|
|
385
|
+
val = OptionalAttribute("val", XL_ERROR_BAR_TYPE, default=XL_ERROR_BAR_TYPE.BOTH)
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
class CT_ErrValType(BaseOxmlElement):
|
|
389
|
+
"""``<c:errValType>`` element, how the error amount is calculated."""
|
|
390
|
+
|
|
391
|
+
val = OptionalAttribute("val", XL_ERROR_BAR_INCLUDE, default=XL_ERROR_BAR_INCLUDE.FIXED_VALUE)
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
# -- element-class registration for the trendline / errBars subtree. These are
|
|
395
|
+
# -- registered here (rather than from `pptx2.oxml.__init__`) so the whole
|
|
396
|
+
# -- analytics feature is self-contained within the chart oxml package. The
|
|
397
|
+
# -- import is local to avoid a circular import at package-initialization time.
|
|
398
|
+
from pptx2.oxml import register_element_cls # noqa: E402
|
|
399
|
+
from pptx2.oxml.chart.shared import ( # noqa: E402
|
|
400
|
+
CT_Boolean,
|
|
401
|
+
CT_Boolean_Explicit,
|
|
402
|
+
CT_Double,
|
|
403
|
+
CT_UnsignedInt,
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
# -- trendline + errBars container elements --
|
|
407
|
+
register_element_cls("c:trendline", CT_Trendline)
|
|
408
|
+
register_element_cls("c:trendlineType", CT_TrendlineType)
|
|
409
|
+
register_element_cls("c:errBars", CT_ErrBars)
|
|
410
|
+
register_element_cls("c:errDir", CT_ErrDir)
|
|
411
|
+
register_element_cls("c:errBarType", CT_ErrBarType)
|
|
412
|
+
register_element_cls("c:errValType", CT_ErrValType)
|
|
413
|
+
register_element_cls("c:name", CT_TrendlineName)
|
|
414
|
+
# -- custom error-bar plus/minus numeric data sources --
|
|
415
|
+
register_element_cls("c:plus", CT_NumDataSource)
|
|
416
|
+
register_element_cls("c:minus", CT_NumDataSource)
|
|
417
|
+
# -- scalar trendline children (c:order is already registered globally as
|
|
418
|
+
# -- CT_UnsignedInt for the series order element, which serves here too) --
|
|
419
|
+
register_element_cls("c:period", CT_UnsignedInt)
|
|
420
|
+
register_element_cls("c:forward", CT_Double)
|
|
421
|
+
register_element_cls("c:backward", CT_Double)
|
|
422
|
+
register_element_cls("c:intercept", CT_Double)
|
|
423
|
+
register_element_cls("c:dispEq", CT_Boolean_Explicit)
|
|
424
|
+
register_element_cls("c:dispRSqr", CT_Boolean_Explicit)
|
|
425
|
+
register_element_cls("c:noEndCap", CT_Boolean)
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""Shared oxml objects for charts."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pptx2.oxml import parse_xml
|
|
6
|
+
from pptx2.oxml.ns import nsdecls
|
|
7
|
+
from pptx2.oxml.simpletypes import (
|
|
8
|
+
ST_LayoutMode,
|
|
9
|
+
XsdBoolean,
|
|
10
|
+
XsdDouble,
|
|
11
|
+
XsdString,
|
|
12
|
+
XsdUnsignedInt,
|
|
13
|
+
)
|
|
14
|
+
from pptx2.oxml.xmlchemy import (
|
|
15
|
+
BaseOxmlElement,
|
|
16
|
+
OptionalAttribute,
|
|
17
|
+
RequiredAttribute,
|
|
18
|
+
ZeroOrOne,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class CT_Boolean(BaseOxmlElement):
|
|
23
|
+
"""
|
|
24
|
+
Common complex type used for elements having a True/False value.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
val = OptionalAttribute("val", XsdBoolean, default=True)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class CT_Boolean_Explicit(BaseOxmlElement):
|
|
31
|
+
"""Always spells out the `val` attribute, e.g. `val=1`.
|
|
32
|
+
|
|
33
|
+
At least one boolean element is improperly interpreted by one or more
|
|
34
|
+
versions of PowerPoint. The `c:overlay` element is interpreted as |False|
|
|
35
|
+
when no `val` attribute is present, contrary to the behavior described in
|
|
36
|
+
the schema. A remedy for this is to interpret a missing `val` attribute
|
|
37
|
+
as |True| (consistent with the spec), but always write the attribute
|
|
38
|
+
whenever there is occasion for changing the element.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
_val = OptionalAttribute("val", XsdBoolean, default=True)
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def val(self):
|
|
45
|
+
return self._val
|
|
46
|
+
|
|
47
|
+
@val.setter
|
|
48
|
+
def val(self, value):
|
|
49
|
+
val_str = "1" if bool(value) is True else "0"
|
|
50
|
+
self.set("val", val_str)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class CT_Double(BaseOxmlElement):
|
|
54
|
+
"""
|
|
55
|
+
Used for floating point values.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
val = RequiredAttribute("val", XsdDouble)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class CT_Layout(BaseOxmlElement):
|
|
62
|
+
"""
|
|
63
|
+
``<c:layout>`` custom element class
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
manualLayout = ZeroOrOne("c:manualLayout", successors=("c:extLst",))
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def horz_offset(self):
|
|
70
|
+
"""
|
|
71
|
+
The float value in ./c:manualLayout/c:x when
|
|
72
|
+
c:layout/c:manualLayout/c:xMode@val == "factor". 0.0 if that XPath
|
|
73
|
+
expression finds no match.
|
|
74
|
+
"""
|
|
75
|
+
manualLayout = self.manualLayout
|
|
76
|
+
if manualLayout is None:
|
|
77
|
+
return 0.0
|
|
78
|
+
return manualLayout.horz_offset
|
|
79
|
+
|
|
80
|
+
@horz_offset.setter
|
|
81
|
+
def horz_offset(self, offset):
|
|
82
|
+
"""
|
|
83
|
+
Set the value of ./c:manualLayout/c:x@val to *offset* and
|
|
84
|
+
./c:manualLayout/c:xMode@val to "factor". Remove ./c:manualLayout if
|
|
85
|
+
*offset* == 0.
|
|
86
|
+
"""
|
|
87
|
+
if offset == 0.0:
|
|
88
|
+
self._remove_manualLayout()
|
|
89
|
+
return
|
|
90
|
+
manualLayout = self.get_or_add_manualLayout()
|
|
91
|
+
manualLayout.horz_offset = offset
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class CT_LayoutMode(BaseOxmlElement):
|
|
95
|
+
"""
|
|
96
|
+
Used for ``<c:xMode>``, ``<c:yMode>``, ``<c:wMode>``, and ``<c:hMode>``
|
|
97
|
+
child elements of CT_ManualLayout.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
val = OptionalAttribute("val", ST_LayoutMode, default=ST_LayoutMode.FACTOR)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class CT_ManualLayout(BaseOxmlElement):
|
|
104
|
+
"""
|
|
105
|
+
``<c:manualLayout>`` custom element class
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
_tag_seq = (
|
|
109
|
+
"c:layoutTarget",
|
|
110
|
+
"c:xMode",
|
|
111
|
+
"c:yMode",
|
|
112
|
+
"c:wMode",
|
|
113
|
+
"c:hMode",
|
|
114
|
+
"c:x",
|
|
115
|
+
"c:y",
|
|
116
|
+
"c:w",
|
|
117
|
+
"c:h",
|
|
118
|
+
"c:extLst",
|
|
119
|
+
)
|
|
120
|
+
xMode = ZeroOrOne("c:xMode", successors=_tag_seq[2:])
|
|
121
|
+
x = ZeroOrOne("c:x", successors=_tag_seq[6:])
|
|
122
|
+
del _tag_seq
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
def horz_offset(self):
|
|
126
|
+
"""
|
|
127
|
+
The float value in ./c:x@val when ./c:xMode@val == "factor". 0.0 when
|
|
128
|
+
./c:x is not present or ./c:xMode@val != "factor".
|
|
129
|
+
"""
|
|
130
|
+
x, xMode = self.x, self.xMode
|
|
131
|
+
if x is None or xMode is None or xMode.val != ST_LayoutMode.FACTOR:
|
|
132
|
+
return 0.0
|
|
133
|
+
return x.val
|
|
134
|
+
|
|
135
|
+
@horz_offset.setter
|
|
136
|
+
def horz_offset(self, offset):
|
|
137
|
+
"""
|
|
138
|
+
Set the value of ./c:x@val to *offset* and ./c:xMode@val to "factor".
|
|
139
|
+
"""
|
|
140
|
+
self.get_or_add_xMode().val = ST_LayoutMode.FACTOR
|
|
141
|
+
self.get_or_add_x().val = offset
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class CT_NumFmt(BaseOxmlElement):
|
|
145
|
+
"""
|
|
146
|
+
``<c:numFmt>`` element specifying the formatting for number labels on a
|
|
147
|
+
tick mark or data point.
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
formatCode = RequiredAttribute("formatCode", XsdString)
|
|
151
|
+
sourceLinked = OptionalAttribute("sourceLinked", XsdBoolean)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class CT_Title(BaseOxmlElement):
|
|
155
|
+
"""`c:title` custom element class."""
|
|
156
|
+
|
|
157
|
+
_tag_seq = ("c:tx", "c:layout", "c:overlay", "c:spPr", "c:txPr", "c:extLst")
|
|
158
|
+
tx = ZeroOrOne("c:tx", successors=_tag_seq[1:])
|
|
159
|
+
spPr = ZeroOrOne("c:spPr", successors=_tag_seq[4:])
|
|
160
|
+
del _tag_seq
|
|
161
|
+
|
|
162
|
+
def get_or_add_tx_rich(self):
|
|
163
|
+
"""Return `c:tx/c:rich`, newly created if not present.
|
|
164
|
+
|
|
165
|
+
Return the `c:rich` grandchild at `c:tx/c:rich`. Both the `c:tx` and
|
|
166
|
+
`c:rich` elements are created if not already present. Any
|
|
167
|
+
`c:tx/c:strRef` element is removed. (Such an element would contain
|
|
168
|
+
a cell reference for the axis title text in the chart's Excel
|
|
169
|
+
worksheet.)
|
|
170
|
+
"""
|
|
171
|
+
tx = self.get_or_add_tx()
|
|
172
|
+
tx._remove_strRef()
|
|
173
|
+
return tx.get_or_add_rich()
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def tx_rich(self):
|
|
177
|
+
"""Return `c:tx/c:rich` or |None| if not present."""
|
|
178
|
+
richs = self.xpath("c:tx/c:rich")
|
|
179
|
+
if not richs:
|
|
180
|
+
return None
|
|
181
|
+
return richs[0]
|
|
182
|
+
|
|
183
|
+
@staticmethod
|
|
184
|
+
def new_title():
|
|
185
|
+
"""Return "loose" `c:title` element containing default children."""
|
|
186
|
+
return parse_xml(
|
|
187
|
+
"<c:title %s>" " <c:layout/>" ' <c:overlay val="0"/>' "</c:title>" % nsdecls("c")
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class CT_Tx(BaseOxmlElement):
|
|
192
|
+
"""
|
|
193
|
+
``<c:tx>`` element containing the text for a label on a data point or
|
|
194
|
+
other chart item.
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
strRef = ZeroOrOne("c:strRef")
|
|
198
|
+
rich = ZeroOrOne("c:rich")
|
|
199
|
+
|
|
200
|
+
def _new_rich(self):
|
|
201
|
+
return parse_xml(
|
|
202
|
+
"<c:rich %s>"
|
|
203
|
+
" <a:bodyPr/>"
|
|
204
|
+
" <a:lstStyle/>"
|
|
205
|
+
" <a:p>"
|
|
206
|
+
" <a:pPr>"
|
|
207
|
+
" <a:defRPr/>"
|
|
208
|
+
" </a:pPr>"
|
|
209
|
+
' <a:endParaRPr lang="en-US"/>'
|
|
210
|
+
" </a:p>"
|
|
211
|
+
"</c:rich>" % nsdecls("c", "a")
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class CT_UnsignedInt(BaseOxmlElement):
|
|
216
|
+
"""
|
|
217
|
+
``<c:idx>`` element and others.
|
|
218
|
+
"""
|
|
219
|
+
|
|
220
|
+
val = RequiredAttribute("val", XsdUnsignedInt)
|