Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/openpyxl/chart/_chart.py : 40%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Copyright (c) 2010-2020 openpyxl
3from collections import OrderedDict
5from openpyxl.descriptors import (
6 Typed,
7 Integer,
8 Alias,
9 MinMax,
10 Bool,
11 Set,
12)
13from openpyxl.descriptors.sequence import ValueSequence
14from openpyxl.descriptors.serialisable import Serialisable
16from ._3d import _3DBase
17from .data_source import AxDataSource, NumRef
18from .layout import Layout
19from .legend import Legend
20from .reference import Reference
21from .series_factory import SeriesFactory
22from .series import attribute_mapping
23from .shapes import GraphicalProperties
24from .title import TitleDescriptor
26class AxId(Serialisable):
28 val = Integer()
30 def __init__(self, val):
31 self.val = val
34def PlotArea():
35 from .chartspace import PlotArea
36 return PlotArea()
39class ChartBase(Serialisable):
41 """
42 Base class for all charts
43 """
45 legend = Typed(expected_type=Legend, allow_none=True)
46 layout = Typed(expected_type=Layout, allow_none=True)
47 roundedCorners = Bool(allow_none=True)
48 axId = ValueSequence(expected_type=int)
49 visible_cells_only = Bool(allow_none=True)
50 display_blanks = Set(values=['span', 'gap', 'zero'])
52 _series_type = ""
53 ser = ()
54 series = Alias('ser')
55 title = TitleDescriptor()
56 anchor = "E15" # default anchor position
57 width = 15 # in cm, approx 5 rows
58 height = 7.5 # in cm, approx 14 rows
59 _id = 1
60 _path = "/xl/charts/chart{0}.xml"
61 style = MinMax(allow_none=True, min=1, max=48)
62 mime_type = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"
63 graphical_properties = Typed(expected_type=GraphicalProperties, allow_none=True)
65 __elements__ = ()
68 def __init__(self, axId=(), **kw):
69 self._charts = [self]
70 self.title = None
71 self.layout = None
72 self.roundedCorners = None
73 self.legend = Legend()
74 self.graphical_properties = None
75 self.style = None
76 self.plot_area = PlotArea()
77 self.axId = axId
78 self.display_blanks = 'gap'
79 self.pivotSource = None
80 self.pivotFormats = ()
81 self.visible_cells_only = True
82 self.idx_base = 0
83 super(ChartBase, self).__init__()
86 def __hash__(self):
87 """
88 Just need to check for identity
89 """
90 return id(self)
92 def __iadd__(self, other):
93 """
94 Combine the chart with another one
95 """
96 if not isinstance(other, ChartBase):
97 raise TypeError("Only other charts can be added")
98 self._charts.append(other)
99 return self
102 def to_tree(self, namespace=None, tagname=None, idx=None):
103 self.axId = [id for id in self._axes]
104 if self.ser is not None:
105 for s in self.ser:
106 s.__elements__ = attribute_mapping[self._series_type]
107 return super(ChartBase, self).to_tree(tagname, idx)
110 def _write(self):
111 from .chartspace import ChartSpace, ChartContainer
112 self.plot_area.layout = self.layout
114 idx_base = self.idx_base
115 for chart in self._charts:
116 if chart not in self.plot_area._charts:
117 chart.idx_base = idx_base
118 idx_base += len(chart.series)
119 self.plot_area._charts = self._charts
121 container = ChartContainer(plotArea=self.plot_area, legend=self.legend, title=self.title)
122 if isinstance(chart, _3DBase):
123 container.view3D = chart.view3D
124 container.floor = chart.floor
125 container.sideWall = chart.sideWall
126 container.backWall = chart.backWall
127 container.plotVisOnly = self.visible_cells_only
128 container.dispBlanksAs = self.display_blanks
129 container.pivotFmts = self.pivotFormats
130 cs = ChartSpace(chart=container)
131 cs.style = self.style
132 cs.roundedCorners = self.roundedCorners
133 cs.pivotSource = self.pivotSource
134 return cs.to_tree()
137 @property
138 def _axes(self):
139 x = getattr(self, "x_axis", None)
140 y = getattr(self, "y_axis", None)
141 z = getattr(self, "z_axis", None)
142 return OrderedDict([(axis.axId, axis) for axis in (x, y, z) if axis])
145 def set_categories(self, labels):
146 """
147 Set the categories / x-axis values
148 """
149 if not isinstance(labels, Reference):
150 labels = Reference(range_string=labels)
151 for s in self.ser:
152 s.cat = AxDataSource(numRef=NumRef(f=labels))
155 def add_data(self, data, from_rows=False, titles_from_data=False):
156 """
157 Add a range of data in a single pass.
158 The default is to treat each column as a data series.
159 """
160 if not isinstance(data, Reference):
161 data = Reference(range_string=data)
163 if from_rows:
164 values = data.rows
166 else:
167 values = data.cols
169 for ref in values:
170 series = SeriesFactory(ref, title_from_data=titles_from_data)
171 self.series.append(series)
174 def append(self, value):
175 """Append a data series to the chart"""
176 l = self.series[:]
177 l.append(value)
178 self.series = l
181 @property
182 def path(self):
183 return self._path.format(self._id)