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.
Files changed (175) hide show
  1. pptx2/__init__.py +152 -0
  2. pptx2/_color.py +75 -0
  3. pptx2/_slide_importer.py +597 -0
  4. pptx2/_svg.py +155 -0
  5. pptx2/_template_applier.py +292 -0
  6. pptx2/_textstyle.py +187 -0
  7. pptx2/accessibility.py +365 -0
  8. pptx2/action.py +270 -0
  9. pptx2/animation.py +2237 -0
  10. pptx2/api.py +49 -0
  11. pptx2/audit.py +258 -0
  12. pptx2/chart/__init__.py +0 -0
  13. pptx2/chart/analytics.py +381 -0
  14. pptx2/chart/axis.py +543 -0
  15. pptx2/chart/category.py +200 -0
  16. pptx2/chart/chart.py +670 -0
  17. pptx2/chart/data.py +864 -0
  18. pptx2/chart/datalabel.py +406 -0
  19. pptx2/chart/legend.py +86 -0
  20. pptx2/chart/marker.py +70 -0
  21. pptx2/chart/palettes.py +129 -0
  22. pptx2/chart/plot.py +462 -0
  23. pptx2/chart/point.py +101 -0
  24. pptx2/chart/quick_layouts.py +325 -0
  25. pptx2/chart/series.py +334 -0
  26. pptx2/chart/xlsx.py +272 -0
  27. pptx2/chart/xmlwriter.py +1845 -0
  28. pptx2/compose/__init__.py +28 -0
  29. pptx2/compose/from_spec.py +1094 -0
  30. pptx2/design/__init__.py +8 -0
  31. pptx2/design/components.py +607 -0
  32. pptx2/design/figures.py +389 -0
  33. pptx2/design/layout.py +370 -0
  34. pptx2/design/recipes.py +1967 -0
  35. pptx2/design/style.py +209 -0
  36. pptx2/design/tokens.py +915 -0
  37. pptx2/diagrams.py +754 -0
  38. pptx2/dml/__init__.py +0 -0
  39. pptx2/dml/chtfmt.py +40 -0
  40. pptx2/dml/color.py +496 -0
  41. pptx2/dml/effect.py +909 -0
  42. pptx2/dml/fill.py +691 -0
  43. pptx2/dml/line.py +287 -0
  44. pptx2/dml/picture.py +212 -0
  45. pptx2/dml/three_d.py +381 -0
  46. pptx2/enum/__init__.py +0 -0
  47. pptx2/enum/action.py +71 -0
  48. pptx2/enum/animation.py +31 -0
  49. pptx2/enum/base.py +218 -0
  50. pptx2/enum/chart.py +574 -0
  51. pptx2/enum/dml.py +740 -0
  52. pptx2/enum/lang.py +685 -0
  53. pptx2/enum/presentation.py +133 -0
  54. pptx2/enum/shapes.py +1029 -0
  55. pptx2/enum/text.py +230 -0
  56. pptx2/exc.py +42 -0
  57. pptx2/formats.py +139 -0
  58. pptx2/geometry.py +420 -0
  59. pptx2/inherit.py +109 -0
  60. pptx2/lint.py +2256 -0
  61. pptx2/math.py +177 -0
  62. pptx2/media.py +197 -0
  63. pptx2/opc/__init__.py +0 -0
  64. pptx2/opc/constants.py +332 -0
  65. pptx2/opc/oxml.py +188 -0
  66. pptx2/opc/package.py +762 -0
  67. pptx2/opc/packuri.py +109 -0
  68. pptx2/opc/serialized.py +296 -0
  69. pptx2/opc/shared.py +20 -0
  70. pptx2/opc/spec.py +45 -0
  71. pptx2/oxml/__init__.py +555 -0
  72. pptx2/oxml/action.py +53 -0
  73. pptx2/oxml/chart/__init__.py +0 -0
  74. pptx2/oxml/chart/axis.py +337 -0
  75. pptx2/oxml/chart/chart.py +481 -0
  76. pptx2/oxml/chart/datalabel.py +253 -0
  77. pptx2/oxml/chart/legend.py +72 -0
  78. pptx2/oxml/chart/marker.py +61 -0
  79. pptx2/oxml/chart/plot.py +365 -0
  80. pptx2/oxml/chart/series.py +425 -0
  81. pptx2/oxml/chart/shared.py +220 -0
  82. pptx2/oxml/coreprops.py +288 -0
  83. pptx2/oxml/dml/__init__.py +0 -0
  84. pptx2/oxml/dml/color.py +135 -0
  85. pptx2/oxml/dml/effect.py +213 -0
  86. pptx2/oxml/dml/fill.py +316 -0
  87. pptx2/oxml/dml/line.py +12 -0
  88. pptx2/oxml/dml/three_d.py +110 -0
  89. pptx2/oxml/ns.py +135 -0
  90. pptx2/oxml/presentation.py +313 -0
  91. pptx2/oxml/shapes/__init__.py +19 -0
  92. pptx2/oxml/shapes/autoshape.py +467 -0
  93. pptx2/oxml/shapes/connector.py +107 -0
  94. pptx2/oxml/shapes/graphfrm.py +347 -0
  95. pptx2/oxml/shapes/groupshape.py +329 -0
  96. pptx2/oxml/shapes/picture.py +270 -0
  97. pptx2/oxml/shapes/shared.py +577 -0
  98. pptx2/oxml/simpletypes.py +1027 -0
  99. pptx2/oxml/slide.py +563 -0
  100. pptx2/oxml/table.py +650 -0
  101. pptx2/oxml/text.py +815 -0
  102. pptx2/oxml/theme.py +36 -0
  103. pptx2/oxml/xmlchemy.py +717 -0
  104. pptx2/package.py +222 -0
  105. pptx2/parts/__init__.py +0 -0
  106. pptx2/parts/chart.py +95 -0
  107. pptx2/parts/coreprops.py +167 -0
  108. pptx2/parts/diagram.py +37 -0
  109. pptx2/parts/embeddedpackage.py +93 -0
  110. pptx2/parts/image.py +275 -0
  111. pptx2/parts/media.py +37 -0
  112. pptx2/parts/presentation.py +136 -0
  113. pptx2/parts/slide.py +371 -0
  114. pptx2/presentation.py +408 -0
  115. pptx2/py.typed +0 -0
  116. pptx2/render.py +586 -0
  117. pptx2/section.py +272 -0
  118. pptx2/shapes/__init__.py +26 -0
  119. pptx2/shapes/autoshape.py +442 -0
  120. pptx2/shapes/base.py +1078 -0
  121. pptx2/shapes/connector.py +297 -0
  122. pptx2/shapes/freeform.py +337 -0
  123. pptx2/shapes/graphfrm.py +316 -0
  124. pptx2/shapes/group.py +264 -0
  125. pptx2/shapes/picture.py +422 -0
  126. pptx2/shapes/placeholder.py +468 -0
  127. pptx2/shapes/shapetree.py +2027 -0
  128. pptx2/shared.py +82 -0
  129. pptx2/skill/SKILL.md +450 -0
  130. pptx2/skill/__init__.py +78 -0
  131. pptx2/skill/__main__.py +64 -0
  132. pptx2/skill/references/animations.md +189 -0
  133. pptx2/skill/references/basics.md +421 -0
  134. pptx2/skill/references/charts.md +254 -0
  135. pptx2/skill/references/compose.md +234 -0
  136. pptx2/skill/references/design.md +366 -0
  137. pptx2/skill/references/effects.md +249 -0
  138. pptx2/skill/references/end-to-end-deck.md +231 -0
  139. pptx2/skill/references/geometry-and-arrows.md +334 -0
  140. pptx2/skill/references/lint.md +275 -0
  141. pptx2/skill/references/math.md +86 -0
  142. pptx2/skill/references/picture-effects.md +129 -0
  143. pptx2/skill/references/render.md +151 -0
  144. pptx2/skill/references/smart-art.md +75 -0
  145. pptx2/skill/references/space-aware-authoring.md +249 -0
  146. pptx2/skill/references/tables.md +244 -0
  147. pptx2/skill/references/theme.md +127 -0
  148. pptx2/skill/references/three-d.md +109 -0
  149. pptx2/skill/references/transitions.md +100 -0
  150. pptx2/slide.py +1244 -0
  151. pptx2/smart_art.py +220 -0
  152. pptx2/spec.py +633 -0
  153. pptx2/table.py +1181 -0
  154. pptx2/table_styles.py +184 -0
  155. pptx2/templates/default.pptx +0 -0
  156. pptx2/templates/docx-icon.emf +0 -0
  157. pptx2/templates/generic-icon.emf +0 -0
  158. pptx2/templates/notes.xml +23 -0
  159. pptx2/templates/notesMaster.xml +352 -0
  160. pptx2/templates/pptx-icon.emf +0 -0
  161. pptx2/templates/theme.xml +321 -0
  162. pptx2/templates/xlsx-icon.emf +0 -0
  163. pptx2/text/__init__.py +0 -0
  164. pptx2/text/fonts.py +482 -0
  165. pptx2/text/layout.py +374 -0
  166. pptx2/text/text.py +1272 -0
  167. pptx2/theme.py +721 -0
  168. pptx2/types.py +36 -0
  169. pptx2/util.py +263 -0
  170. python_pptx2-2.13.0.dist-info/METADATA +351 -0
  171. python_pptx2-2.13.0.dist-info/RECORD +175 -0
  172. python_pptx2-2.13.0.dist-info/WHEEL +5 -0
  173. python_pptx2-2.13.0.dist-info/entry_points.txt +3 -0
  174. python_pptx2-2.13.0.dist-info/licenses/LICENSE +22 -0
  175. 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)