series.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. # Copyright (c) 2010-2024 openpyxl
  2. from openpyxl.descriptors.serialisable import Serialisable
  3. from openpyxl.descriptors import (
  4. Typed,
  5. String,
  6. Integer,
  7. Bool,
  8. Alias,
  9. Sequence,
  10. )
  11. from openpyxl.descriptors.excel import ExtensionList
  12. from openpyxl.descriptors.nested import (
  13. NestedInteger,
  14. NestedBool,
  15. NestedNoneSet,
  16. NestedText,
  17. )
  18. from .shapes import GraphicalProperties
  19. from .data_source import (
  20. AxDataSource,
  21. NumDataSource,
  22. NumRef,
  23. StrRef,
  24. )
  25. from .error_bar import ErrorBars
  26. from .label import DataLabelList
  27. from .marker import DataPoint, PictureOptions, Marker
  28. from .trendline import Trendline
  29. attribute_mapping = {
  30. 'area': ('idx', 'order', 'tx', 'spPr', 'pictureOptions', 'dPt', 'dLbls', 'errBars',
  31. 'trendline', 'cat', 'val',),
  32. 'bar':('idx', 'order','tx', 'spPr', 'invertIfNegative', 'pictureOptions', 'dPt',
  33. 'dLbls', 'trendline', 'errBars', 'cat', 'val', 'shape'),
  34. 'bubble':('idx','order', 'tx', 'spPr', 'invertIfNegative', 'dPt', 'dLbls',
  35. 'trendline', 'errBars', 'xVal', 'yVal', 'bubbleSize', 'bubble3D'),
  36. 'line':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'trendline',
  37. 'errBars', 'cat', 'val', 'smooth'),
  38. 'pie':('idx', 'order', 'tx', 'spPr', 'explosion', 'dPt', 'dLbls', 'cat', 'val'),
  39. 'radar':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'cat', 'val'),
  40. 'scatter':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'trendline',
  41. 'errBars', 'xVal', 'yVal', 'smooth'),
  42. 'surface':('idx', 'order', 'tx', 'spPr', 'cat', 'val'),
  43. }
  44. class SeriesLabel(Serialisable):
  45. tagname = "tx"
  46. strRef = Typed(expected_type=StrRef, allow_none=True)
  47. v = NestedText(expected_type=str, allow_none=True)
  48. value = Alias('v')
  49. __elements__ = ('strRef', 'v')
  50. def __init__(self,
  51. strRef=None,
  52. v=None):
  53. self.strRef = strRef
  54. self.v = v
  55. class Series(Serialisable):
  56. """
  57. Generic series object. Should not be instantiated directly.
  58. User the chart.Series factory instead.
  59. """
  60. tagname = "ser"
  61. idx = NestedInteger()
  62. order = NestedInteger()
  63. tx = Typed(expected_type=SeriesLabel, allow_none=True)
  64. title = Alias('tx')
  65. spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
  66. graphicalProperties = Alias('spPr')
  67. # area chart
  68. pictureOptions = Typed(expected_type=PictureOptions, allow_none=True)
  69. dPt = Sequence(expected_type=DataPoint, allow_none=True)
  70. data_points = Alias("dPt")
  71. dLbls = Typed(expected_type=DataLabelList, allow_none=True)
  72. labels = Alias("dLbls")
  73. trendline = Typed(expected_type=Trendline, allow_none=True)
  74. errBars = Typed(expected_type=ErrorBars, allow_none=True)
  75. cat = Typed(expected_type=AxDataSource, allow_none=True)
  76. identifiers = Alias("cat")
  77. val = Typed(expected_type=NumDataSource, allow_none=True)
  78. extLst = Typed(expected_type=ExtensionList, allow_none=True)
  79. #bar chart
  80. invertIfNegative = NestedBool(allow_none=True)
  81. shape = NestedNoneSet(values=(['cone', 'coneToMax', 'box', 'cylinder', 'pyramid', 'pyramidToMax']))
  82. #bubble chart
  83. xVal = Typed(expected_type=AxDataSource, allow_none=True)
  84. yVal = Typed(expected_type=NumDataSource, allow_none=True)
  85. bubbleSize = Typed(expected_type=NumDataSource, allow_none=True)
  86. zVal = Alias("bubbleSize")
  87. bubble3D = NestedBool(allow_none=True)
  88. #line chart
  89. marker = Typed(expected_type=Marker, allow_none=True)
  90. smooth = NestedBool(allow_none=True)
  91. #pie chart
  92. explosion = NestedInteger(allow_none=True)
  93. __elements__ = ()
  94. def __init__(self,
  95. idx=0,
  96. order=0,
  97. tx=None,
  98. spPr=None,
  99. pictureOptions=None,
  100. dPt=(),
  101. dLbls=None,
  102. trendline=None,
  103. errBars=None,
  104. cat=None,
  105. val=None,
  106. invertIfNegative=None,
  107. shape=None,
  108. xVal=None,
  109. yVal=None,
  110. bubbleSize=None,
  111. bubble3D=None,
  112. marker=None,
  113. smooth=None,
  114. explosion=None,
  115. extLst=None,
  116. ):
  117. self.idx = idx
  118. self.order = order
  119. self.tx = tx
  120. if spPr is None:
  121. spPr = GraphicalProperties()
  122. self.spPr = spPr
  123. self.pictureOptions = pictureOptions
  124. self.dPt = dPt
  125. self.dLbls = dLbls
  126. self.trendline = trendline
  127. self.errBars = errBars
  128. self.cat = cat
  129. self.val = val
  130. self.invertIfNegative = invertIfNegative
  131. self.shape = shape
  132. self.xVal = xVal
  133. self.yVal = yVal
  134. self.bubbleSize = bubbleSize
  135. self.bubble3D = bubble3D
  136. if marker is None:
  137. marker = Marker()
  138. self.marker = marker
  139. self.smooth = smooth
  140. self.explosion = explosion
  141. def to_tree(self, tagname=None, idx=None):
  142. """The index can need rebasing"""
  143. if idx is not None:
  144. if self.order == self.idx:
  145. self.order = idx # rebase the order if the index has been rebased
  146. self.idx = idx
  147. return super().to_tree(tagname)
  148. class XYSeries(Series):
  149. """Dedicated series for charts that have x and y series"""
  150. idx = Series.idx
  151. order = Series.order
  152. tx = Series.tx
  153. spPr = Series.spPr
  154. dPt = Series.dPt
  155. dLbls = Series.dLbls
  156. trendline = Series.trendline
  157. errBars = Series.errBars
  158. xVal = Series.xVal
  159. yVal = Series.yVal
  160. invertIfNegative = Series.invertIfNegative
  161. bubbleSize = Series.bubbleSize
  162. bubble3D = Series.bubble3D
  163. marker = Series.marker
  164. smooth = Series.smooth