plotarea.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. from __future__ import absolute_import
  2. # Copyright (c) 2010-2019 openpyxl
  3. from openpyxl.descriptors.serialisable import Serialisable
  4. from openpyxl.descriptors import (
  5. Typed,
  6. Alias,
  7. )
  8. from openpyxl.descriptors.excel import (
  9. ExtensionList,
  10. )
  11. from openpyxl.descriptors.sequence import (
  12. MultiSequence,
  13. MultiSequencePart,
  14. )
  15. from openpyxl.descriptors.nested import (
  16. NestedBool,
  17. )
  18. from ._3d import _3DBase
  19. from .area_chart import AreaChart, AreaChart3D
  20. from .bar_chart import BarChart, BarChart3D
  21. from .bubble_chart import BubbleChart
  22. from .line_chart import LineChart, LineChart3D
  23. from .pie_chart import PieChart, PieChart3D, ProjectedPieChart, DoughnutChart
  24. from .radar_chart import RadarChart
  25. from .scatter_chart import ScatterChart
  26. from .stock_chart import StockChart
  27. from .surface_chart import SurfaceChart, SurfaceChart3D
  28. from .layout import Layout
  29. from .shapes import GraphicalProperties
  30. from .text import RichText
  31. from .axis import (
  32. NumericAxis,
  33. TextAxis,
  34. SeriesAxis,
  35. DateAxis,
  36. )
  37. class DataTable(Serialisable):
  38. tagname = "dTable"
  39. showHorzBorder = NestedBool(allow_none=True)
  40. showVertBorder = NestedBool(allow_none=True)
  41. showOutline = NestedBool(allow_none=True)
  42. showKeys = NestedBool(allow_none=True)
  43. spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
  44. graphicalProperties = Alias('spPr')
  45. txPr = Typed(expected_type=RichText, allow_none=True)
  46. extLst = Typed(expected_type=ExtensionList, allow_none=True)
  47. __elements__ = ('showHorzBorder', 'showVertBorder', 'showOutline',
  48. 'showKeys', 'spPr', 'txPr')
  49. def __init__(self,
  50. showHorzBorder=None,
  51. showVertBorder=None,
  52. showOutline=None,
  53. showKeys=None,
  54. spPr=None,
  55. txPr=None,
  56. extLst=None,
  57. ):
  58. self.showHorzBorder = showHorzBorder
  59. self.showVertBorder = showVertBorder
  60. self.showOutline = showOutline
  61. self.showKeys = showKeys
  62. self.spPr = spPr
  63. self.txPr = txPr
  64. class PlotArea(Serialisable):
  65. tagname = "plotArea"
  66. layout = Typed(expected_type=Layout, allow_none=True)
  67. dTable = Typed(expected_type=DataTable, allow_none=True)
  68. spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
  69. graphicalProperties = Alias("spPr")
  70. extLst = Typed(expected_type=ExtensionList, allow_none=True)
  71. # at least one chart
  72. _charts = MultiSequence()
  73. areaChart = MultiSequencePart(expected_type=AreaChart, store="_charts")
  74. area3DChart = MultiSequencePart(expected_type=AreaChart3D, store="_charts")
  75. lineChart = MultiSequencePart(expected_type=LineChart, store="_charts")
  76. line3DChart = MultiSequencePart(expected_type=LineChart3D, store="_charts")
  77. stockChart = MultiSequencePart(expected_type=StockChart, store="_charts")
  78. radarChart = MultiSequencePart(expected_type=RadarChart, store="_charts")
  79. scatterChart = MultiSequencePart(expected_type=ScatterChart, store="_charts")
  80. pieChart = MultiSequencePart(expected_type=PieChart, store="_charts")
  81. pie3DChart = MultiSequencePart(expected_type=PieChart3D, store="_charts")
  82. doughnutChart = MultiSequencePart(expected_type=DoughnutChart, store="_charts")
  83. barChart = MultiSequencePart(expected_type=BarChart, store="_charts")
  84. bar3DChart = MultiSequencePart(expected_type=BarChart3D, store="_charts")
  85. ofPieChart = MultiSequencePart(expected_type=ProjectedPieChart, store="_charts")
  86. surfaceChart = MultiSequencePart(expected_type=SurfaceChart, store="_charts")
  87. surface3DChart = MultiSequencePart(expected_type=SurfaceChart3D, store="_charts")
  88. bubbleChart = MultiSequencePart(expected_type=BubbleChart, store="_charts")
  89. # axes
  90. _axes = MultiSequence()
  91. valAx = MultiSequencePart(expected_type=NumericAxis, store="_axes")
  92. catAx = MultiSequencePart(expected_type=TextAxis, store="_axes")
  93. dateAx = MultiSequencePart(expected_type=DateAxis, store="_axes")
  94. serAx = MultiSequencePart(expected_type=SeriesAxis, store="_axes")
  95. __elements__ = ('layout', '_charts', '_axes', 'dTable', 'spPr')
  96. def __init__(self,
  97. layout=None,
  98. dTable=None,
  99. spPr=None,
  100. _charts=(),
  101. _axes=(),
  102. extLst=None,
  103. ):
  104. self.layout = layout
  105. self.dTable = dTable
  106. self.spPr = spPr
  107. self._charts = _charts
  108. self._axes = _axes
  109. def to_tree(self, tagname=None, idx=None, namespace=None):
  110. axIds = set((ax.axId for ax in self._axes))
  111. for chart in self._charts:
  112. for id, axis in chart._axes.items():
  113. if id not in axIds:
  114. setattr(self, axis.tagname, axis)
  115. axIds.add(id)
  116. return super(PlotArea, self).to_tree(tagname)
  117. @classmethod
  118. def from_tree(cls, node):
  119. self = super(PlotArea, cls).from_tree(node)
  120. axes = dict((axis.axId, axis) for axis in self._axes)
  121. for chart in self._charts:
  122. if isinstance(chart, ScatterChart):
  123. x, y = (axes[axId] for axId in chart.axId)
  124. chart.x_axis = x
  125. chart.y_axis = y
  126. continue
  127. for axId in chart.axId:
  128. axis = axes.get(axId)
  129. if axis is None and isinstance(chart, _3DBase):
  130. # Series Axis can be optional
  131. chart.z_axis = None
  132. continue
  133. if axis.tagname in ("catAx", "dateAx"):
  134. chart.x_axis = axis
  135. elif axis.tagname == "valAx":
  136. chart.y_axis = axis
  137. elif axis.tagname == "serAx":
  138. chart.z_axis = axis
  139. return self