diff options
Diffstat (limited to '.venv/lib/python3.12/site-packages/openpyxl/chart')
34 files changed, 3625 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/_3d.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/_3d.py new file mode 100644 index 00000000..1651a993 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/_3d.py @@ -0,0 +1,105 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors import Typed, Alias +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors.nested import ( + NestedBool, + NestedInteger, + NestedMinMax, +) +from openpyxl.descriptors.excel import ExtensionList +from .marker import PictureOptions +from .shapes import GraphicalProperties + + +class View3D(Serialisable): + + tagname = "view3D" + + rotX = NestedMinMax(min=-90, max=90, allow_none=True) + x_rotation = Alias('rotX') + hPercent = NestedMinMax(min=5, max=500, allow_none=True) + height_percent = Alias('hPercent') + rotY = NestedInteger(min=-90, max=90, allow_none=True) + y_rotation = Alias('rotY') + depthPercent = NestedInteger(allow_none=True) + rAngAx = NestedBool(allow_none=True) + right_angle_axes = Alias('rAngAx') + perspective = NestedInteger(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('rotX', 'hPercent', 'rotY', 'depthPercent', 'rAngAx', + 'perspective',) + + def __init__(self, + rotX=15, + hPercent=None, + rotY=20, + depthPercent=None, + rAngAx=True, + perspective=None, + extLst=None, + ): + self.rotX = rotX + self.hPercent = hPercent + self.rotY = rotY + self.depthPercent = depthPercent + self.rAngAx = rAngAx + self.perspective = perspective + + +class Surface(Serialisable): + + tagname = "surface" + + thickness = NestedInteger(allow_none=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + pictureOptions = Typed(expected_type=PictureOptions, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('thickness', 'spPr', 'pictureOptions',) + + def __init__(self, + thickness=None, + spPr=None, + pictureOptions=None, + extLst=None, + ): + self.thickness = thickness + self.spPr = spPr + self.pictureOptions = pictureOptions + + +class _3DBase(Serialisable): + + """ + Base class for 3D charts + """ + + tagname = "ChartBase" + + view3D = Typed(expected_type=View3D, allow_none=True) + floor = Typed(expected_type=Surface, allow_none=True) + sideWall = Typed(expected_type=Surface, allow_none=True) + backWall = Typed(expected_type=Surface, allow_none=True) + + def __init__(self, + view3D=None, + floor=None, + sideWall=None, + backWall=None, + ): + if view3D is None: + view3D = View3D() + self.view3D = view3D + if floor is None: + floor = Surface() + self.floor = floor + if sideWall is None: + sideWall = Surface() + self.sideWall = sideWall + if backWall is None: + backWall = Surface() + self.backWall = backWall + super(_3DBase, self).__init__() diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/__init__.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/__init__.py new file mode 100644 index 00000000..ecc4d8bf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/__init__.py @@ -0,0 +1,19 @@ +# Copyright (c) 2010-2024 openpyxl + +from .area_chart import AreaChart, AreaChart3D +from .bar_chart import BarChart, BarChart3D +from .bubble_chart import BubbleChart +from .line_chart import LineChart, LineChart3D +from .pie_chart import ( + PieChart, + PieChart3D, + DoughnutChart, + ProjectedPieChart +) +from .radar_chart import RadarChart +from .scatter_chart import ScatterChart +from .stock_chart import StockChart +from .surface_chart import SurfaceChart, SurfaceChart3D + +from .series_factory import SeriesFactory as Series +from .reference import Reference diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/_chart.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/_chart.py new file mode 100644 index 00000000..6a613546 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/_chart.py @@ -0,0 +1,199 @@ +# Copyright (c) 2010-2024 openpyxl + +from collections import OrderedDict +from operator import attrgetter + +from openpyxl.descriptors import ( + Typed, + Integer, + Alias, + MinMax, + Bool, + Set, +) +from openpyxl.descriptors.sequence import ValueSequence +from openpyxl.descriptors.serialisable import Serialisable + +from ._3d import _3DBase +from .data_source import AxDataSource, NumRef +from .layout import Layout +from .legend import Legend +from .reference import Reference +from .series_factory import SeriesFactory +from .series import attribute_mapping +from .shapes import GraphicalProperties +from .title import TitleDescriptor + +class AxId(Serialisable): + + val = Integer() + + def __init__(self, val): + self.val = val + + +def PlotArea(): + from .chartspace import PlotArea + return PlotArea() + + +class ChartBase(Serialisable): + + """ + Base class for all charts + """ + + legend = Typed(expected_type=Legend, allow_none=True) + layout = Typed(expected_type=Layout, allow_none=True) + roundedCorners = Bool(allow_none=True) + axId = ValueSequence(expected_type=int) + visible_cells_only = Bool(allow_none=True) + display_blanks = Set(values=['span', 'gap', 'zero']) + graphical_properties = Typed(expected_type=GraphicalProperties, allow_none=True) + + _series_type = "" + ser = () + series = Alias('ser') + title = TitleDescriptor() + anchor = "E15" # default anchor position + width = 15 # in cm, approx 5 rows + height = 7.5 # in cm, approx 14 rows + _id = 1 + _path = "/xl/charts/chart{0}.xml" + style = MinMax(allow_none=True, min=1, max=48) + mime_type = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" + graphical_properties = Typed(expected_type=GraphicalProperties, allow_none=True) # mapped to chartspace + + __elements__ = () + + + def __init__(self, axId=(), **kw): + self._charts = [self] + self.title = None + self.layout = None + self.roundedCorners = None + self.legend = Legend() + self.graphical_properties = None + self.style = None + self.plot_area = PlotArea() + self.axId = axId + self.display_blanks = 'gap' + self.pivotSource = None + self.pivotFormats = () + self.visible_cells_only = True + self.idx_base = 0 + self.graphical_properties = None + super().__init__() + + + def __hash__(self): + """ + Just need to check for identity + """ + return id(self) + + def __iadd__(self, other): + """ + Combine the chart with another one + """ + if not isinstance(other, ChartBase): + raise TypeError("Only other charts can be added") + self._charts.append(other) + return self + + + def to_tree(self, namespace=None, tagname=None, idx=None): + self.axId = [id for id in self._axes] + if self.ser is not None: + for s in self.ser: + s.__elements__ = attribute_mapping[self._series_type] + return super().to_tree(tagname, idx) + + + def _reindex(self): + """ + Normalise and rebase series: sort by order and then rebase order + + """ + # sort data series in order and rebase + ds = sorted(self.series, key=attrgetter("order")) + for idx, s in enumerate(ds): + s.order = idx + self.series = ds + + + def _write(self): + from .chartspace import ChartSpace, ChartContainer + self.plot_area.layout = self.layout + + idx_base = self.idx_base + for chart in self._charts: + if chart not in self.plot_area._charts: + chart.idx_base = idx_base + idx_base += len(chart.series) + self.plot_area._charts = self._charts + + container = ChartContainer(plotArea=self.plot_area, legend=self.legend, title=self.title) + if isinstance(chart, _3DBase): + container.view3D = chart.view3D + container.floor = chart.floor + container.sideWall = chart.sideWall + container.backWall = chart.backWall + container.plotVisOnly = self.visible_cells_only + container.dispBlanksAs = self.display_blanks + container.pivotFmts = self.pivotFormats + cs = ChartSpace(chart=container) + cs.style = self.style + cs.roundedCorners = self.roundedCorners + cs.pivotSource = self.pivotSource + cs.spPr = self.graphical_properties + return cs.to_tree() + + + @property + def _axes(self): + x = getattr(self, "x_axis", None) + y = getattr(self, "y_axis", None) + z = getattr(self, "z_axis", None) + return OrderedDict([(axis.axId, axis) for axis in (x, y, z) if axis]) + + + def set_categories(self, labels): + """ + Set the categories / x-axis values + """ + if not isinstance(labels, Reference): + labels = Reference(range_string=labels) + for s in self.ser: + s.cat = AxDataSource(numRef=NumRef(f=labels)) + + + def add_data(self, data, from_rows=False, titles_from_data=False): + """ + Add a range of data in a single pass. + The default is to treat each column as a data series. + """ + if not isinstance(data, Reference): + data = Reference(range_string=data) + + if from_rows: + values = data.rows + + else: + values = data.cols + + for ref in values: + series = SeriesFactory(ref, title_from_data=titles_from_data) + self.series.append(series) + + + def append(self, value): + """Append a data series to the chart""" + l = self.series[:] + l.append(value) + self.series = l + + + @property + def path(self): + return self._path.format(self._id) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/area_chart.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/area_chart.py new file mode 100644 index 00000000..d3d98085 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/area_chart.py @@ -0,0 +1,106 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Set, + Bool, + Integer, + Sequence, + Alias, +) + +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedMinMax, + NestedSet, + NestedBool, +) + +from ._chart import ChartBase +from .descriptors import NestedGapAmount +from .axis import TextAxis, NumericAxis, SeriesAxis, ChartLines +from .label import DataLabelList +from .series import Series + + +class _AreaChartBase(ChartBase): + + grouping = NestedSet(values=(['percentStacked', 'standard', 'stacked'])) + varyColors = NestedBool(nested=True, allow_none=True) + ser = Sequence(expected_type=Series, allow_none=True) + dLbls = Typed(expected_type=DataLabelList, allow_none=True) + dataLabels = Alias("dLbls") + dropLines = Typed(expected_type=ChartLines, allow_none=True) + + _series_type = "area" + + __elements__ = ('grouping', 'varyColors', 'ser', 'dLbls', 'dropLines') + + def __init__(self, + grouping="standard", + varyColors=None, + ser=(), + dLbls=None, + dropLines=None, + ): + self.grouping = grouping + self.varyColors = varyColors + self.ser = ser + self.dLbls = dLbls + self.dropLines = dropLines + super().__init__() + + +class AreaChart(_AreaChartBase): + + tagname = "areaChart" + + grouping = _AreaChartBase.grouping + varyColors = _AreaChartBase.varyColors + ser = _AreaChartBase.ser + dLbls = _AreaChartBase.dLbls + dropLines = _AreaChartBase.dropLines + + # chart properties actually used by containing classes + x_axis = Typed(expected_type=TextAxis) + y_axis = Typed(expected_type=NumericAxis) + + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = _AreaChartBase.__elements__ + ('axId',) + + def __init__(self, + axId=None, + extLst=None, + **kw + ): + self.x_axis = TextAxis() + self.y_axis = NumericAxis() + super().__init__(**kw) + + +class AreaChart3D(AreaChart): + + tagname = "area3DChart" + + grouping = _AreaChartBase.grouping + varyColors = _AreaChartBase.varyColors + ser = _AreaChartBase.ser + dLbls = _AreaChartBase.dLbls + dropLines = _AreaChartBase.dropLines + + gapDepth = NestedGapAmount() + + x_axis = Typed(expected_type=TextAxis) + y_axis = Typed(expected_type=NumericAxis) + z_axis = Typed(expected_type=SeriesAxis, allow_none=True) + + __elements__ = AreaChart.__elements__ + ('gapDepth', ) + + def __init__(self, gapDepth=None, **kw): + self.gapDepth = gapDepth + super(AreaChart3D, self).__init__(**kw) + self.x_axis = TextAxis() + self.y_axis = NumericAxis() + self.z_axis = SeriesAxis() diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/axis.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/axis.py new file mode 100644 index 00000000..7e99416c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/axis.py @@ -0,0 +1,401 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Float, + NoneSet, + Bool, + Integer, + MinMax, + NoneSet, + Set, + String, + Alias, +) + +from openpyxl.descriptors.excel import ( + ExtensionList, + Percentage, + _explicit_none, +) +from openpyxl.descriptors.nested import ( + NestedValue, + NestedSet, + NestedBool, + NestedNoneSet, + NestedFloat, + NestedInteger, + NestedMinMax, +) +from openpyxl.xml.constants import CHART_NS + +from .descriptors import NumberFormatDescriptor +from .layout import Layout +from .text import Text, RichText +from .shapes import GraphicalProperties +from .title import Title, TitleDescriptor + + +class ChartLines(Serialisable): + + tagname = "chartLines" + + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + + def __init__(self, spPr=None): + self.spPr = spPr + + +class Scaling(Serialisable): + + tagname = "scaling" + + logBase = NestedFloat(allow_none=True) + orientation = NestedSet(values=(['maxMin', 'minMax'])) + max = NestedFloat(allow_none=True) + min = NestedFloat(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('logBase', 'orientation', 'max', 'min',) + + def __init__(self, + logBase=None, + orientation="minMax", + max=None, + min=None, + extLst=None, + ): + self.logBase = logBase + self.orientation = orientation + self.max = max + self.min = min + + +class _BaseAxis(Serialisable): + + axId = NestedInteger(expected_type=int) + scaling = Typed(expected_type=Scaling) + delete = NestedBool(allow_none=True) + axPos = NestedSet(values=(['b', 'l', 'r', 't'])) + majorGridlines = Typed(expected_type=ChartLines, allow_none=True) + minorGridlines = Typed(expected_type=ChartLines, allow_none=True) + title = TitleDescriptor() + numFmt = NumberFormatDescriptor() + number_format = Alias("numFmt") + majorTickMark = NestedNoneSet(values=(['cross', 'in', 'out']), to_tree=_explicit_none) + minorTickMark = NestedNoneSet(values=(['cross', 'in', 'out']), to_tree=_explicit_none) + tickLblPos = NestedNoneSet(values=(['high', 'low', 'nextTo'])) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + txPr = Typed(expected_type=RichText, allow_none=True) + textProperties = Alias('txPr') + crossAx = NestedInteger(expected_type=int) # references other axis + crosses = NestedNoneSet(values=(['autoZero', 'max', 'min'])) + crossesAt = NestedFloat(allow_none=True) + + # crosses & crossesAt are mutually exclusive + + __elements__ = ('axId', 'scaling', 'delete', 'axPos', 'majorGridlines', + 'minorGridlines', 'title', 'numFmt', 'majorTickMark', 'minorTickMark', + 'tickLblPos', 'spPr', 'txPr', 'crossAx', 'crosses', 'crossesAt') + + def __init__(self, + axId=None, + scaling=None, + delete=None, + axPos='l', + majorGridlines=None, + minorGridlines=None, + title=None, + numFmt=None, + majorTickMark=None, + minorTickMark=None, + tickLblPos=None, + spPr=None, + txPr= None, + crossAx=None, + crosses=None, + crossesAt=None, + ): + self.axId = axId + if scaling is None: + scaling = Scaling() + self.scaling = scaling + self.delete = delete + self.axPos = axPos + self.majorGridlines = majorGridlines + self.minorGridlines = minorGridlines + self.title = title + self.numFmt = numFmt + self.majorTickMark = majorTickMark + self.minorTickMark = minorTickMark + self.tickLblPos = tickLblPos + self.spPr = spPr + self.txPr = txPr + self.crossAx = crossAx + self.crosses = crosses + self.crossesAt = crossesAt + + +class DisplayUnitsLabel(Serialisable): + + tagname = "dispUnitsLbl" + + layout = Typed(expected_type=Layout, allow_none=True) + tx = Typed(expected_type=Text, allow_none=True) + text = Alias("tx") + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias("spPr") + txPr = Typed(expected_type=RichText, allow_none=True) + textPropertes = Alias("txPr") + + __elements__ = ('layout', 'tx', 'spPr', 'txPr') + + def __init__(self, + layout=None, + tx=None, + spPr=None, + txPr=None, + ): + self.layout = layout + self.tx = tx + self.spPr = spPr + self.txPr = txPr + + +class DisplayUnitsLabelList(Serialisable): + + tagname = "dispUnits" + + custUnit = NestedFloat(allow_none=True) + builtInUnit = NestedNoneSet(values=(['hundreds', 'thousands', + 'tenThousands', 'hundredThousands', 'millions', 'tenMillions', + 'hundredMillions', 'billions', 'trillions'])) + dispUnitsLbl = Typed(expected_type=DisplayUnitsLabel, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('custUnit', 'builtInUnit', 'dispUnitsLbl',) + + def __init__(self, + custUnit=None, + builtInUnit=None, + dispUnitsLbl=None, + extLst=None, + ): + self.custUnit = custUnit + self.builtInUnit = builtInUnit + self.dispUnitsLbl = dispUnitsLbl + + +class NumericAxis(_BaseAxis): + + tagname = "valAx" + + axId = _BaseAxis.axId + scaling = _BaseAxis.scaling + delete = _BaseAxis.delete + axPos = _BaseAxis.axPos + majorGridlines = _BaseAxis.majorGridlines + minorGridlines = _BaseAxis.minorGridlines + title = _BaseAxis.title + numFmt = _BaseAxis.numFmt + majorTickMark = _BaseAxis.majorTickMark + minorTickMark = _BaseAxis.minorTickMark + tickLblPos = _BaseAxis.tickLblPos + spPr = _BaseAxis.spPr + txPr = _BaseAxis.txPr + crossAx = _BaseAxis.crossAx + crosses = _BaseAxis.crosses + crossesAt = _BaseAxis.crossesAt + + crossBetween = NestedNoneSet(values=(['between', 'midCat'])) + majorUnit = NestedFloat(allow_none=True) + minorUnit = NestedFloat(allow_none=True) + dispUnits = Typed(expected_type=DisplayUnitsLabelList, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = _BaseAxis.__elements__ + ('crossBetween', 'majorUnit', + 'minorUnit', 'dispUnits',) + + + def __init__(self, + crossBetween=None, + majorUnit=None, + minorUnit=None, + dispUnits=None, + extLst=None, + **kw + ): + self.crossBetween = crossBetween + self.majorUnit = majorUnit + self.minorUnit = minorUnit + self.dispUnits = dispUnits + kw.setdefault('majorGridlines', ChartLines()) + kw.setdefault('axId', 100) + kw.setdefault('crossAx', 10) + super().__init__(**kw) + + + @classmethod + def from_tree(cls, node): + """ + Special case value axes with no gridlines + """ + self = super().from_tree(node) + gridlines = node.find("{%s}majorGridlines" % CHART_NS) + if gridlines is None: + self.majorGridlines = None + return self + + + +class TextAxis(_BaseAxis): + + tagname = "catAx" + + axId = _BaseAxis.axId + scaling = _BaseAxis.scaling + delete = _BaseAxis.delete + axPos = _BaseAxis.axPos + majorGridlines = _BaseAxis.majorGridlines + minorGridlines = _BaseAxis.minorGridlines + title = _BaseAxis.title + numFmt = _BaseAxis.numFmt + majorTickMark = _BaseAxis.majorTickMark + minorTickMark = _BaseAxis.minorTickMark + tickLblPos = _BaseAxis.tickLblPos + spPr = _BaseAxis.spPr + txPr = _BaseAxis.txPr + crossAx = _BaseAxis.crossAx + crosses = _BaseAxis.crosses + crossesAt = _BaseAxis.crossesAt + + auto = NestedBool(allow_none=True) + lblAlgn = NestedNoneSet(values=(['ctr', 'l', 'r'])) + lblOffset = NestedMinMax(min=0, max=1000) + tickLblSkip = NestedInteger(allow_none=True) + tickMarkSkip = NestedInteger(allow_none=True) + noMultiLvlLbl = NestedBool(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = _BaseAxis.__elements__ + ('auto', 'lblAlgn', 'lblOffset', + 'tickLblSkip', 'tickMarkSkip', 'noMultiLvlLbl') + + def __init__(self, + auto=None, + lblAlgn=None, + lblOffset=100, + tickLblSkip=None, + tickMarkSkip=None, + noMultiLvlLbl=None, + extLst=None, + **kw + ): + self.auto = auto + self.lblAlgn = lblAlgn + self.lblOffset = lblOffset + self.tickLblSkip = tickLblSkip + self.tickMarkSkip = tickMarkSkip + self.noMultiLvlLbl = noMultiLvlLbl + kw.setdefault('axId', 10) + kw.setdefault('crossAx', 100) + super().__init__(**kw) + + +class DateAxis(TextAxis): + + tagname = "dateAx" + + axId = _BaseAxis.axId + scaling = _BaseAxis.scaling + delete = _BaseAxis.delete + axPos = _BaseAxis.axPos + majorGridlines = _BaseAxis.majorGridlines + minorGridlines = _BaseAxis.minorGridlines + title = _BaseAxis.title + numFmt = _BaseAxis.numFmt + majorTickMark = _BaseAxis.majorTickMark + minorTickMark = _BaseAxis.minorTickMark + tickLblPos = _BaseAxis.tickLblPos + spPr = _BaseAxis.spPr + txPr = _BaseAxis.txPr + crossAx = _BaseAxis.crossAx + crosses = _BaseAxis.crosses + crossesAt = _BaseAxis.crossesAt + + auto = NestedBool(allow_none=True) + lblOffset = NestedInteger(allow_none=True) + baseTimeUnit = NestedNoneSet(values=(['days', 'months', 'years'])) + majorUnit = NestedFloat(allow_none=True) + majorTimeUnit = NestedNoneSet(values=(['days', 'months', 'years'])) + minorUnit = NestedFloat(allow_none=True) + minorTimeUnit = NestedNoneSet(values=(['days', 'months', 'years'])) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = _BaseAxis.__elements__ + ('auto', 'lblOffset', + 'baseTimeUnit', 'majorUnit', 'majorTimeUnit', 'minorUnit', + 'minorTimeUnit') + + def __init__(self, + auto=None, + lblOffset=None, + baseTimeUnit=None, + majorUnit=None, + majorTimeUnit=None, + minorUnit=None, + minorTimeUnit=None, + extLst=None, + **kw + ): + self.auto = auto + self.lblOffset = lblOffset + self.baseTimeUnit = baseTimeUnit + self.majorUnit = majorUnit + self.majorTimeUnit = majorTimeUnit + self.minorUnit = minorUnit + self.minorTimeUnit = minorTimeUnit + kw.setdefault('axId', 500) + kw.setdefault('lblOffset', lblOffset) + super().__init__(**kw) + + +class SeriesAxis(_BaseAxis): + + tagname = "serAx" + + axId = _BaseAxis.axId + scaling = _BaseAxis.scaling + delete = _BaseAxis.delete + axPos = _BaseAxis.axPos + majorGridlines = _BaseAxis.majorGridlines + minorGridlines = _BaseAxis.minorGridlines + title = _BaseAxis.title + numFmt = _BaseAxis.numFmt + majorTickMark = _BaseAxis.majorTickMark + minorTickMark = _BaseAxis.minorTickMark + tickLblPos = _BaseAxis.tickLblPos + spPr = _BaseAxis.spPr + txPr = _BaseAxis.txPr + crossAx = _BaseAxis.crossAx + crosses = _BaseAxis.crosses + crossesAt = _BaseAxis.crossesAt + + tickLblSkip = NestedInteger(allow_none=True) + tickMarkSkip = NestedInteger(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = _BaseAxis.__elements__ + ('tickLblSkip', 'tickMarkSkip') + + def __init__(self, + tickLblSkip=None, + tickMarkSkip=None, + extLst=None, + **kw + ): + self.tickLblSkip = tickLblSkip + self.tickMarkSkip = tickMarkSkip + kw.setdefault('axId', 1000) + kw.setdefault('crossAx', 10) + super().__init__(**kw) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/bar_chart.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/bar_chart.py new file mode 100644 index 00000000..fa08e076 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/bar_chart.py @@ -0,0 +1,144 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Bool, + Integer, + Sequence, + Alias, +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedNoneSet, + NestedSet, + NestedBool, + NestedInteger, + NestedMinMax, +) + +from .descriptors import ( + NestedGapAmount, + NestedOverlap, +) +from ._chart import ChartBase +from ._3d import _3DBase +from .axis import TextAxis, NumericAxis, SeriesAxis, ChartLines +from .shapes import GraphicalProperties +from .series import Series +from .legend import Legend +from .label import DataLabelList + + +class _BarChartBase(ChartBase): + + barDir = NestedSet(values=(['bar', 'col'])) + type = Alias("barDir") + grouping = NestedSet(values=(['percentStacked', 'clustered', 'standard', + 'stacked'])) + varyColors = NestedBool(nested=True, allow_none=True) + ser = Sequence(expected_type=Series, allow_none=True) + dLbls = Typed(expected_type=DataLabelList, allow_none=True) + dataLabels = Alias("dLbls") + + __elements__ = ('barDir', 'grouping', 'varyColors', 'ser', 'dLbls') + + _series_type = "bar" + + def __init__(self, + barDir="col", + grouping="clustered", + varyColors=None, + ser=(), + dLbls=None, + **kw + ): + self.barDir = barDir + self.grouping = grouping + self.varyColors = varyColors + self.ser = ser + self.dLbls = dLbls + super().__init__(**kw) + + +class BarChart(_BarChartBase): + + tagname = "barChart" + + barDir = _BarChartBase.barDir + grouping = _BarChartBase.grouping + varyColors = _BarChartBase.varyColors + ser = _BarChartBase.ser + dLbls = _BarChartBase.dLbls + + gapWidth = NestedGapAmount() + overlap = NestedOverlap() + serLines = Typed(expected_type=ChartLines, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + # chart properties actually used by containing classes + x_axis = Typed(expected_type=TextAxis) + y_axis = Typed(expected_type=NumericAxis) + + __elements__ = _BarChartBase.__elements__ + ('gapWidth', 'overlap', 'serLines', 'axId') + + def __init__(self, + gapWidth=150, + overlap=None, + serLines=None, + extLst=None, + **kw + ): + self.gapWidth = gapWidth + self.overlap = overlap + self.serLines = serLines + self.x_axis = TextAxis() + self.y_axis = NumericAxis() + self.legend = Legend() + super().__init__(**kw) + + +class BarChart3D(_BarChartBase, _3DBase): + + tagname = "bar3DChart" + + barDir = _BarChartBase.barDir + grouping = _BarChartBase.grouping + varyColors = _BarChartBase.varyColors + ser = _BarChartBase.ser + dLbls = _BarChartBase.dLbls + + view3D = _3DBase.view3D + floor = _3DBase.floor + sideWall = _3DBase.sideWall + backWall = _3DBase.backWall + + gapWidth = NestedGapAmount() + gapDepth = NestedGapAmount() + shape = NestedNoneSet(values=(['cone', 'coneToMax', 'box', 'cylinder', 'pyramid', 'pyramidToMax'])) + serLines = Typed(expected_type=ChartLines, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + x_axis = Typed(expected_type=TextAxis) + y_axis = Typed(expected_type=NumericAxis) + z_axis = Typed(expected_type=SeriesAxis, allow_none=True) + + __elements__ = _BarChartBase.__elements__ + ('gapWidth', 'gapDepth', 'shape', 'serLines', 'axId') + + def __init__(self, + gapWidth=150, + gapDepth=150, + shape=None, + serLines=None, + extLst=None, + **kw + ): + self.gapWidth = gapWidth + self.gapDepth = gapDepth + self.shape = shape + self.serLines = serLines + self.x_axis = TextAxis() + self.y_axis = NumericAxis() + self.z_axis = SeriesAxis() + + super(BarChart3D, self).__init__(**kw) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/bubble_chart.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/bubble_chart.py new file mode 100644 index 00000000..3fca043a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/bubble_chart.py @@ -0,0 +1,67 @@ +#Autogenerated schema +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Set, + MinMax, + Bool, + Integer, + Alias, + Sequence, +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedNoneSet, + NestedMinMax, + NestedBool, +) + +from ._chart import ChartBase +from .axis import TextAxis, NumericAxis +from .series import XYSeries +from .label import DataLabelList + + +class BubbleChart(ChartBase): + + tagname = "bubbleChart" + + varyColors = NestedBool(allow_none=True) + ser = Sequence(expected_type=XYSeries, allow_none=True) + dLbls = Typed(expected_type=DataLabelList, allow_none=True) + dataLabels = Alias("dLbls") + bubble3D = NestedBool(allow_none=True) + bubbleScale = NestedMinMax(min=0, max=300, allow_none=True) + showNegBubbles = NestedBool(allow_none=True) + sizeRepresents = NestedNoneSet(values=(['area', 'w'])) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + x_axis = Typed(expected_type=NumericAxis) + y_axis = Typed(expected_type=NumericAxis) + + _series_type = "bubble" + + __elements__ = ('varyColors', 'ser', 'dLbls', 'bubble3D', 'bubbleScale', + 'showNegBubbles', 'sizeRepresents', 'axId') + + def __init__(self, + varyColors=None, + ser=(), + dLbls=None, + bubble3D=None, + bubbleScale=None, + showNegBubbles=None, + sizeRepresents=None, + extLst=None, + **kw + ): + self.varyColors = varyColors + self.ser = ser + self.dLbls = dLbls + self.bubble3D = bubble3D + self.bubbleScale = bubbleScale + self.showNegBubbles = showNegBubbles + self.sizeRepresents = sizeRepresents + self.x_axis = NumericAxis(axId=10, crossAx=20) + self.y_axis = NumericAxis(axId=20, crossAx=10) + super().__init__(**kw) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/chartspace.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/chartspace.py new file mode 100644 index 00000000..cba213c2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/chartspace.py @@ -0,0 +1,195 @@ + +# Copyright (c) 2010-2024 openpyxl + +""" +Enclosing chart object. The various chart types are actually child objects. +Will probably need to call this indirectly +""" + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + String, + Alias, +) +from openpyxl.descriptors.excel import ( + ExtensionList, + Relation +) +from openpyxl.descriptors.nested import ( + NestedBool, + NestedNoneSet, + NestedString, + NestedMinMax, +) +from openpyxl.descriptors.sequence import NestedSequence +from openpyxl.xml.constants import CHART_NS + +from openpyxl.drawing.colors import ColorMapping +from .text import RichText +from .shapes import GraphicalProperties +from .legend import Legend +from ._3d import _3DBase +from .plotarea import PlotArea +from .title import Title +from .pivot import ( + PivotFormat, + PivotSource, +) +from .print_settings import PrintSettings + + +class ChartContainer(Serialisable): + + tagname = "chart" + + title = Typed(expected_type=Title, allow_none=True) + autoTitleDeleted = NestedBool(allow_none=True) + pivotFmts = NestedSequence(expected_type=PivotFormat) + view3D = _3DBase.view3D + floor = _3DBase.floor + sideWall = _3DBase.sideWall + backWall = _3DBase.backWall + plotArea = Typed(expected_type=PlotArea, ) + legend = Typed(expected_type=Legend, allow_none=True) + plotVisOnly = NestedBool() + dispBlanksAs = NestedNoneSet(values=(['span', 'gap', 'zero'])) + showDLblsOverMax = NestedBool(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('title', 'autoTitleDeleted', 'pivotFmts', 'view3D', + 'floor', 'sideWall', 'backWall', 'plotArea', 'legend', 'plotVisOnly', + 'dispBlanksAs', 'showDLblsOverMax') + + def __init__(self, + title=None, + autoTitleDeleted=None, + pivotFmts=(), + view3D=None, + floor=None, + sideWall=None, + backWall=None, + plotArea=None, + legend=None, + plotVisOnly=True, + dispBlanksAs="gap", + showDLblsOverMax=None, + extLst=None, + ): + self.title = title + self.autoTitleDeleted = autoTitleDeleted + self.pivotFmts = pivotFmts + self.view3D = view3D + self.floor = floor + self.sideWall = sideWall + self.backWall = backWall + if plotArea is None: + plotArea = PlotArea() + self.plotArea = plotArea + self.legend = legend + self.plotVisOnly = plotVisOnly + self.dispBlanksAs = dispBlanksAs + self.showDLblsOverMax = showDLblsOverMax + + +class Protection(Serialisable): + + tagname = "protection" + + chartObject = NestedBool(allow_none=True) + data = NestedBool(allow_none=True) + formatting = NestedBool(allow_none=True) + selection = NestedBool(allow_none=True) + userInterface = NestedBool(allow_none=True) + + __elements__ = ("chartObject", "data", "formatting", "selection", "userInterface") + + def __init__(self, + chartObject=None, + data=None, + formatting=None, + selection=None, + userInterface=None, + ): + self.chartObject = chartObject + self.data = data + self.formatting = formatting + self.selection = selection + self.userInterface = userInterface + + +class ExternalData(Serialisable): + + tagname = "externalData" + + autoUpdate = NestedBool(allow_none=True) + id = String() # Needs namespace + + def __init__(self, + autoUpdate=None, + id=None + ): + self.autoUpdate = autoUpdate + self.id = id + + +class ChartSpace(Serialisable): + + tagname = "chartSpace" + + date1904 = NestedBool(allow_none=True) + lang = NestedString(allow_none=True) + roundedCorners = NestedBool(allow_none=True) + style = NestedMinMax(allow_none=True, min=1, max=48) + clrMapOvr = Typed(expected_type=ColorMapping, allow_none=True) + pivotSource = Typed(expected_type=PivotSource, allow_none=True) + protection = Typed(expected_type=Protection, allow_none=True) + chart = Typed(expected_type=ChartContainer) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphical_properties = Alias("spPr") + txPr = Typed(expected_type=RichText, allow_none=True) + textProperties = Alias("txPr") + externalData = Typed(expected_type=ExternalData, allow_none=True) + printSettings = Typed(expected_type=PrintSettings, allow_none=True) + userShapes = Relation() + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('date1904', 'lang', 'roundedCorners', 'style', + 'clrMapOvr', 'pivotSource', 'protection', 'chart', 'spPr', 'txPr', + 'externalData', 'printSettings', 'userShapes') + + def __init__(self, + date1904=None, + lang=None, + roundedCorners=None, + style=None, + clrMapOvr=None, + pivotSource=None, + protection=None, + chart=None, + spPr=None, + txPr=None, + externalData=None, + printSettings=None, + userShapes=None, + extLst=None, + ): + self.date1904 = date1904 + self.lang = lang + self.roundedCorners = roundedCorners + self.style = style + self.clrMapOvr = clrMapOvr + self.pivotSource = pivotSource + self.protection = protection + self.chart = chart + self.spPr = spPr + self.txPr = txPr + self.externalData = externalData + self.printSettings = printSettings + self.userShapes = userShapes + + + def to_tree(self, tagname=None, idx=None, namespace=None): + tree = super().to_tree() + tree.set("xmlns", CHART_NS) + return tree diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/data_source.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/data_source.py new file mode 100644 index 00000000..c38eafb2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/data_source.py @@ -0,0 +1,246 @@ +""" +Collection of utility primitives for charts. +""" + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Bool, + Typed, + Alias, + String, + Integer, + Sequence, +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedString, + NestedText, + NestedInteger, +) + + +class NumFmt(Serialisable): + + formatCode = String() + sourceLinked = Bool() + + def __init__(self, + formatCode=None, + sourceLinked=False + ): + self.formatCode = formatCode + self.sourceLinked = sourceLinked + + +class NumberValueDescriptor(NestedText): + """ + Data should be numerical but isn't always :-/ + """ + + allow_none = True + + def __set__(self, instance, value): + if value == "#N/A": + self.expected_type = str + else: + self.expected_type = float + super().__set__(instance, value) + + +class NumVal(Serialisable): + + idx = Integer() + formatCode = NestedText(allow_none=True, expected_type=str) + v = NumberValueDescriptor() + + def __init__(self, + idx=None, + formatCode=None, + v=None, + ): + self.idx = idx + self.formatCode = formatCode + self.v = v + + +class NumData(Serialisable): + + formatCode = NestedText(expected_type=str, allow_none=True) + ptCount = NestedInteger(allow_none=True) + pt = Sequence(expected_type=NumVal) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('formatCode', 'ptCount', 'pt') + + def __init__(self, + formatCode=None, + ptCount=None, + pt=(), + extLst=None, + ): + self.formatCode = formatCode + self.ptCount = ptCount + self.pt = pt + + +class NumRef(Serialisable): + + f = NestedText(expected_type=str) + ref = Alias('f') + numCache = Typed(expected_type=NumData, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('f', 'numCache') + + def __init__(self, + f=None, + numCache=None, + extLst=None, + ): + self.f = f + self.numCache = numCache + + +class StrVal(Serialisable): + + tagname = "strVal" + + idx = Integer() + v = NestedText(expected_type=str) + + def __init__(self, + idx=0, + v=None, + ): + self.idx = idx + self.v = v + + +class StrData(Serialisable): + + tagname = "strData" + + ptCount = NestedInteger(allow_none=True) + pt = Sequence(expected_type=StrVal) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('ptCount', 'pt') + + def __init__(self, + ptCount=None, + pt=(), + extLst=None, + ): + self.ptCount = ptCount + self.pt = pt + + +class StrRef(Serialisable): + + tagname = "strRef" + + f = NestedText(expected_type=str, allow_none=True) + strCache = Typed(expected_type=StrData, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('f', 'strCache') + + def __init__(self, + f=None, + strCache=None, + extLst=None, + ): + self.f = f + self.strCache = strCache + + +class NumDataSource(Serialisable): + + numRef = Typed(expected_type=NumRef, allow_none=True) + numLit = Typed(expected_type=NumData, allow_none=True) + + + def __init__(self, + numRef=None, + numLit=None, + ): + self.numRef = numRef + self.numLit = numLit + + +class Level(Serialisable): + + tagname = "lvl" + + pt = Sequence(expected_type=StrVal) + + __elements__ = ('pt',) + + def __init__(self, + pt=(), + ): + self.pt = pt + + +class MultiLevelStrData(Serialisable): + + tagname = "multiLvlStrData" + + ptCount = Integer(allow_none=True) + lvl = Sequence(expected_type=Level) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('ptCount', 'lvl',) + + def __init__(self, + ptCount=None, + lvl=(), + extLst=None, + ): + self.ptCount = ptCount + self.lvl = lvl + + +class MultiLevelStrRef(Serialisable): + + tagname = "multiLvlStrRef" + + f = NestedText(expected_type=str) + multiLvlStrCache = Typed(expected_type=MultiLevelStrData, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('multiLvlStrCache', 'f') + + def __init__(self, + f=None, + multiLvlStrCache=None, + extLst=None, + ): + self.f = f + self.multiLvlStrCache = multiLvlStrCache + + +class AxDataSource(Serialisable): + + tagname = "cat" + + numRef = Typed(expected_type=NumRef, allow_none=True) + numLit = Typed(expected_type=NumData, allow_none=True) + strRef = Typed(expected_type=StrRef, allow_none=True) + strLit = Typed(expected_type=StrData, allow_none=True) + multiLvlStrRef = Typed(expected_type=MultiLevelStrRef, allow_none=True) + + def __init__(self, + numRef=None, + numLit=None, + strRef=None, + strLit=None, + multiLvlStrRef=None, + ): + if not any([numLit, numRef, strRef, strLit, multiLvlStrRef]): + raise TypeError("A data source must be provided") + self.numRef = numRef + self.numLit = numLit + self.strRef = strRef + self.strLit = strLit + self.multiLvlStrRef = multiLvlStrRef diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/descriptors.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/descriptors.py new file mode 100644 index 00000000..6bc94348 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/descriptors.py @@ -0,0 +1,43 @@ +# Copyright (c) 2010-2024 openpyxl + + + +from openpyxl.descriptors.nested import ( + NestedMinMax + ) + +from openpyxl.descriptors import Typed + +from .data_source import NumFmt + +""" +Utility descriptors for the chart module. +For convenience but also clarity. +""" + +class NestedGapAmount(NestedMinMax): + + allow_none = True + min = 0 + max = 500 + + +class NestedOverlap(NestedMinMax): + + allow_none = True + min = -100 + max = 100 + + +class NumberFormatDescriptor(Typed): + """ + Allow direct assignment of format code + """ + + expected_type = NumFmt + allow_none = True + + def __set__(self, instance, value): + if isinstance(value, str): + value = NumFmt(value) + super().__set__(instance, value) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/error_bar.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/error_bar.py new file mode 100644 index 00000000..6ae24451 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/error_bar.py @@ -0,0 +1,62 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Float, + Set, + Alias +) + +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedNoneSet, + NestedSet, + NestedBool, + NestedFloat, +) + +from .data_source import NumDataSource +from .shapes import GraphicalProperties + + +class ErrorBars(Serialisable): + + tagname = "errBars" + + errDir = NestedNoneSet(values=(['x', 'y'])) + direction = Alias("errDir") + errBarType = NestedSet(values=(['both', 'minus', 'plus'])) + style = Alias("errBarType") + errValType = NestedSet(values=(['cust', 'fixedVal', 'percentage', 'stdDev', 'stdErr'])) + size = Alias("errValType") + noEndCap = NestedBool(nested=True, allow_none=True) + plus = Typed(expected_type=NumDataSource, allow_none=True) + minus = Typed(expected_type=NumDataSource, allow_none=True) + val = NestedFloat(allow_none=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias("spPr") + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('errDir','errBarType', 'errValType', 'noEndCap','minus', 'plus', 'val', 'spPr') + + + def __init__(self, + errDir=None, + errBarType="both", + errValType="fixedVal", + noEndCap=None, + plus=None, + minus=None, + val=None, + spPr=None, + extLst=None, + ): + self.errDir = errDir + self.errBarType = errBarType + self.errValType = errValType + self.noEndCap = noEndCap + self.plus = plus + self.minus = minus + self.val = val + self.spPr = spPr diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/label.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/label.py new file mode 100644 index 00000000..d6eacb16 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/label.py @@ -0,0 +1,127 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Sequence, + Alias, + Typed +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedNoneSet, + NestedBool, + NestedString, + NestedInteger, + ) + +from .shapes import GraphicalProperties +from .text import RichText + + +class _DataLabelBase(Serialisable): + + numFmt = NestedString(allow_none=True, attribute="formatCode") + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + txPr = Typed(expected_type=RichText, allow_none=True) + textProperties = Alias('txPr') + dLblPos = NestedNoneSet(values=['bestFit', 'b', 'ctr', 'inBase', 'inEnd', + 'l', 'outEnd', 'r', 't']) + position = Alias('dLblPos') + showLegendKey = NestedBool(allow_none=True) + showVal = NestedBool(allow_none=True) + showCatName = NestedBool(allow_none=True) + showSerName = NestedBool(allow_none=True) + showPercent = NestedBool(allow_none=True) + showBubbleSize = NestedBool(allow_none=True) + showLeaderLines = NestedBool(allow_none=True) + separator = NestedString(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ("numFmt", "spPr", "txPr", "dLblPos", "showLegendKey", + "showVal", "showCatName", "showSerName", "showPercent", "showBubbleSize", + "showLeaderLines", "separator") + + def __init__(self, + numFmt=None, + spPr=None, + txPr=None, + dLblPos=None, + showLegendKey=None, + showVal=None, + showCatName=None, + showSerName=None, + showPercent=None, + showBubbleSize=None, + showLeaderLines=None, + separator=None, + extLst=None, + ): + self.numFmt = numFmt + self.spPr = spPr + self.txPr = txPr + self.dLblPos = dLblPos + self.showLegendKey = showLegendKey + self.showVal = showVal + self.showCatName = showCatName + self.showSerName = showSerName + self.showPercent = showPercent + self.showBubbleSize = showBubbleSize + self.showLeaderLines = showLeaderLines + self.separator = separator + + +class DataLabel(_DataLabelBase): + + tagname = "dLbl" + + idx = NestedInteger() + + numFmt = _DataLabelBase.numFmt + spPr = _DataLabelBase.spPr + txPr = _DataLabelBase.txPr + dLblPos = _DataLabelBase.dLblPos + showLegendKey = _DataLabelBase.showLegendKey + showVal = _DataLabelBase.showVal + showCatName = _DataLabelBase.showCatName + showSerName = _DataLabelBase.showSerName + showPercent = _DataLabelBase.showPercent + showBubbleSize = _DataLabelBase.showBubbleSize + showLeaderLines = _DataLabelBase.showLeaderLines + separator = _DataLabelBase.separator + extLst = _DataLabelBase.extLst + + __elements__ = ("idx",) + _DataLabelBase.__elements__ + + def __init__(self, idx=0, **kw ): + self.idx = idx + super().__init__(**kw) + + +class DataLabelList(_DataLabelBase): + + tagname = "dLbls" + + dLbl = Sequence(expected_type=DataLabel, allow_none=True) + + delete = NestedBool(allow_none=True) + numFmt = _DataLabelBase.numFmt + spPr = _DataLabelBase.spPr + txPr = _DataLabelBase.txPr + dLblPos = _DataLabelBase.dLblPos + showLegendKey = _DataLabelBase.showLegendKey + showVal = _DataLabelBase.showVal + showCatName = _DataLabelBase.showCatName + showSerName = _DataLabelBase.showSerName + showPercent = _DataLabelBase.showPercent + showBubbleSize = _DataLabelBase.showBubbleSize + showLeaderLines = _DataLabelBase.showLeaderLines + separator = _DataLabelBase.separator + extLst = _DataLabelBase.extLst + + __elements__ = ("delete", "dLbl",) + _DataLabelBase.__elements__ + + def __init__(self, dLbl=(), delete=None, **kw): + self.dLbl = dLbl + self.delete = delete + super().__init__(**kw) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/layout.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/layout.py new file mode 100644 index 00000000..f2f65530 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/layout.py @@ -0,0 +1,74 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + NoneSet, + Float, + Typed, + Alias, +) + +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedNoneSet, + NestedSet, + NestedMinMax, +) + +class ManualLayout(Serialisable): + + tagname = "manualLayout" + + layoutTarget = NestedNoneSet(values=(['inner', 'outer'])) + xMode = NestedNoneSet(values=(['edge', 'factor'])) + yMode = NestedNoneSet(values=(['edge', 'factor'])) + wMode = NestedSet(values=(['edge', 'factor'])) + hMode = NestedSet(values=(['edge', 'factor'])) + x = NestedMinMax(min=-1, max=1, allow_none=True) + y = NestedMinMax(min=-1, max=1, allow_none=True) + w = NestedMinMax(min=0, max=1, allow_none=True) + width = Alias('w') + h = NestedMinMax(min=0, max=1, allow_none=True) + height = Alias('h') + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('layoutTarget', 'xMode', 'yMode', 'wMode', 'hMode', 'x', + 'y', 'w', 'h') + + def __init__(self, + layoutTarget=None, + xMode=None, + yMode=None, + wMode="factor", + hMode="factor", + x=None, + y=None, + w=None, + h=None, + extLst=None, + ): + self.layoutTarget = layoutTarget + self.xMode = xMode + self.yMode = yMode + self.wMode = wMode + self.hMode = hMode + self.x = x + self.y = y + self.w = w + self.h = h + + +class Layout(Serialisable): + + tagname = "layout" + + manualLayout = Typed(expected_type=ManualLayout, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('manualLayout',) + + def __init__(self, + manualLayout=None, + extLst=None, + ): + self.manualLayout = manualLayout diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/legend.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/legend.py new file mode 100644 index 00000000..1f7c802b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/legend.py @@ -0,0 +1,75 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Integer, + Alias, + Sequence, +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedBool, + NestedSet, + NestedInteger +) + +from .layout import Layout +from .shapes import GraphicalProperties +from .text import RichText + + +class LegendEntry(Serialisable): + + tagname = "legendEntry" + + idx = NestedInteger() + delete = NestedBool() + txPr = Typed(expected_type=RichText, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('idx', 'delete', 'txPr') + + def __init__(self, + idx=0, + delete=False, + txPr=None, + extLst=None, + ): + self.idx = idx + self.delete = delete + self.txPr = txPr + + +class Legend(Serialisable): + + tagname = "legend" + + legendPos = NestedSet(values=(['b', 'tr', 'l', 'r', 't'])) + position = Alias('legendPos') + legendEntry = Sequence(expected_type=LegendEntry) + layout = Typed(expected_type=Layout, allow_none=True) + overlay = NestedBool(allow_none=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + txPr = Typed(expected_type=RichText, allow_none=True) + textProperties = Alias('txPr') + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('legendPos', 'legendEntry', 'layout', 'overlay', 'spPr', 'txPr',) + + def __init__(self, + legendPos="r", + legendEntry=(), + layout=None, + overlay=None, + spPr=None, + txPr=None, + extLst=None, + ): + self.legendPos = legendPos + self.legendEntry = legendEntry + self.layout = layout + self.overlay = overlay + self.spPr = spPr + self.txPr = txPr diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/line_chart.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/line_chart.py new file mode 100644 index 00000000..0aa3ad5b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/line_chart.py @@ -0,0 +1,129 @@ +#Autogenerated schema +from openpyxl.descriptors import ( + Typed, + Sequence, + Alias, + ) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedSet, + NestedBool, +) + +from ._chart import ChartBase +from .updown_bars import UpDownBars +from .descriptors import NestedGapAmount +from .axis import TextAxis, NumericAxis, SeriesAxis, ChartLines, _BaseAxis +from .label import DataLabelList +from .series import Series + + +class _LineChartBase(ChartBase): + + grouping = NestedSet(values=(['percentStacked', 'standard', 'stacked'])) + varyColors = NestedBool(allow_none=True) + ser = Sequence(expected_type=Series, allow_none=True) + dLbls = Typed(expected_type=DataLabelList, allow_none=True) + dataLabels = Alias("dLbls") + dropLines = Typed(expected_type=ChartLines, allow_none=True) + + _series_type = "line" + + __elements__ = ('grouping', 'varyColors', 'ser', 'dLbls', 'dropLines') + + def __init__(self, + grouping="standard", + varyColors=None, + ser=(), + dLbls=None, + dropLines=None, + **kw + ): + self.grouping = grouping + self.varyColors = varyColors + self.ser = ser + self.dLbls = dLbls + self.dropLines = dropLines + super().__init__(**kw) + + +class LineChart(_LineChartBase): + + tagname = "lineChart" + + grouping = _LineChartBase.grouping + varyColors = _LineChartBase.varyColors + ser = _LineChartBase.ser + dLbls = _LineChartBase.dLbls + dropLines =_LineChartBase.dropLines + + hiLowLines = Typed(expected_type=ChartLines, allow_none=True) + upDownBars = Typed(expected_type=UpDownBars, allow_none=True) + marker = NestedBool(allow_none=True) + smooth = NestedBool(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + x_axis = Typed(expected_type=_BaseAxis) + y_axis = Typed(expected_type=NumericAxis) + + __elements__ = _LineChartBase.__elements__ + ('hiLowLines', 'upDownBars', 'marker', 'smooth', 'axId') + + def __init__(self, + hiLowLines=None, + upDownBars=None, + marker=None, + smooth=None, + extLst=None, + **kw + ): + self.hiLowLines = hiLowLines + self.upDownBars = upDownBars + self.marker = marker + self.smooth = smooth + self.x_axis = TextAxis() + self.y_axis = NumericAxis() + + super().__init__(**kw) + + +class LineChart3D(_LineChartBase): + + tagname = "line3DChart" + + grouping = _LineChartBase.grouping + varyColors = _LineChartBase.varyColors + ser = _LineChartBase.ser + dLbls = _LineChartBase.dLbls + dropLines =_LineChartBase.dropLines + + gapDepth = NestedGapAmount() + hiLowLines = Typed(expected_type=ChartLines, allow_none=True) + upDownBars = Typed(expected_type=UpDownBars, allow_none=True) + marker = NestedBool(allow_none=True) + smooth = NestedBool(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + x_axis = Typed(expected_type=TextAxis) + y_axis = Typed(expected_type=NumericAxis) + z_axis = Typed(expected_type=SeriesAxis) + + __elements__ = _LineChartBase.__elements__ + ('gapDepth', 'hiLowLines', + 'upDownBars', 'marker', 'smooth', 'axId') + + def __init__(self, + gapDepth=None, + hiLowLines=None, + upDownBars=None, + marker=None, + smooth=None, + **kw + ): + self.gapDepth = gapDepth + self.hiLowLines = hiLowLines + self.upDownBars = upDownBars + self.marker = marker + self.smooth = smooth + self.x_axis = TextAxis() + self.y_axis = NumericAxis() + self.z_axis = SeriesAxis() + super(LineChart3D, self).__init__(**kw) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/marker.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/marker.py new file mode 100644 index 00000000..61e2641d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/marker.py @@ -0,0 +1,90 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Alias, +) + +from openpyxl.descriptors.excel import( + ExtensionList, + _explicit_none, +) + +from openpyxl.descriptors.nested import ( + NestedBool, + NestedInteger, + NestedMinMax, + NestedNoneSet, +) + +from .layout import Layout +from .picture import PictureOptions +from .shapes import * +from .text import * +from .error_bar import * + + +class Marker(Serialisable): + + tagname = "marker" + + symbol = NestedNoneSet(values=(['circle', 'dash', 'diamond', 'dot', 'picture', + 'plus', 'square', 'star', 'triangle', 'x', 'auto']), + to_tree=_explicit_none) + size = NestedMinMax(min=2, max=72, allow_none=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('symbol', 'size', 'spPr') + + def __init__(self, + symbol=None, + size=None, + spPr=None, + extLst=None, + ): + self.symbol = symbol + self.size = size + if spPr is None: + spPr = GraphicalProperties() + self.spPr = spPr + + +class DataPoint(Serialisable): + + tagname = "dPt" + + idx = NestedInteger() + invertIfNegative = NestedBool(allow_none=True) + marker = Typed(expected_type=Marker, allow_none=True) + bubble3D = NestedBool(allow_none=True) + explosion = NestedInteger(allow_none=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + pictureOptions = Typed(expected_type=PictureOptions, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('idx', 'invertIfNegative', 'marker', 'bubble3D', + 'explosion', 'spPr', 'pictureOptions') + + def __init__(self, + idx=None, + invertIfNegative=None, + marker=None, + bubble3D=None, + explosion=None, + spPr=None, + pictureOptions=None, + extLst=None, + ): + self.idx = idx + self.invertIfNegative = invertIfNegative + self.marker = marker + self.bubble3D = bubble3D + self.explosion = explosion + if spPr is None: + spPr = GraphicalProperties() + self.spPr = spPr + self.pictureOptions = pictureOptions diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/picture.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/picture.py new file mode 100644 index 00000000..8c917d8c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/picture.py @@ -0,0 +1,35 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable + +from openpyxl.descriptors.nested import ( + NestedBool, + NestedFloat, + NestedMinMax, + NestedNoneSet, +) + +class PictureOptions(Serialisable): + + tagname = "pictureOptions" + + applyToFront = NestedBool(allow_none=True, nested=True) + applyToSides = NestedBool(allow_none=True, nested=True) + applyToEnd = NestedBool(allow_none=True, nested=True) + pictureFormat = NestedNoneSet(values=(['stretch', 'stack', 'stackScale']), nested=True) + pictureStackUnit = NestedFloat(allow_none=True, nested=True) + + __elements__ = ('applyToFront', 'applyToSides', 'applyToEnd', 'pictureFormat', 'pictureStackUnit') + + def __init__(self, + applyToFront=None, + applyToSides=None, + applyToEnd=None, + pictureFormat=None, + pictureStackUnit=None, + ): + self.applyToFront = applyToFront + self.applyToSides = applyToSides + self.applyToEnd = applyToEnd + self.pictureFormat = pictureFormat + self.pictureStackUnit = pictureStackUnit diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/pie_chart.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/pie_chart.py new file mode 100644 index 00000000..6bb67e1e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/pie_chart.py @@ -0,0 +1,177 @@ +#Autogenerated schema +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Bool, + MinMax, + Integer, + NoneSet, + Float, + Alias, + Sequence, +) +from openpyxl.descriptors.excel import ExtensionList, Percentage +from openpyxl.descriptors.nested import ( + NestedBool, + NestedMinMax, + NestedInteger, + NestedFloat, + NestedNoneSet, + NestedSet, +) +from openpyxl.descriptors.sequence import ValueSequence + +from ._chart import ChartBase +from .axis import ChartLines +from .descriptors import NestedGapAmount +from .series import Series +from .label import DataLabelList + + +class _PieChartBase(ChartBase): + + varyColors = NestedBool(allow_none=True) + ser = Sequence(expected_type=Series, allow_none=True) + dLbls = Typed(expected_type=DataLabelList, allow_none=True) + dataLabels = Alias("dLbls") + + _series_type = "pie" + + __elements__ = ('varyColors', 'ser', 'dLbls') + + def __init__(self, + varyColors=True, + ser=(), + dLbls=None, + ): + self.varyColors = varyColors + self.ser = ser + self.dLbls = dLbls + super().__init__() + + + +class PieChart(_PieChartBase): + + tagname = "pieChart" + + varyColors = _PieChartBase.varyColors + ser = _PieChartBase.ser + dLbls = _PieChartBase.dLbls + + firstSliceAng = NestedMinMax(min=0, max=360) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = _PieChartBase.__elements__ + ('firstSliceAng', ) + + def __init__(self, + firstSliceAng=0, + extLst=None, + **kw + ): + self.firstSliceAng = firstSliceAng + super().__init__(**kw) + + +class PieChart3D(_PieChartBase): + + tagname = "pie3DChart" + + varyColors = _PieChartBase.varyColors + ser = _PieChartBase.ser + dLbls = _PieChartBase.dLbls + + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = _PieChartBase.__elements__ + + +class DoughnutChart(_PieChartBase): + + tagname = "doughnutChart" + + varyColors = _PieChartBase.varyColors + ser = _PieChartBase.ser + dLbls = _PieChartBase.dLbls + + firstSliceAng = NestedMinMax(min=0, max=360) + holeSize = NestedMinMax(min=1, max=90, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = _PieChartBase.__elements__ + ('firstSliceAng', 'holeSize') + + def __init__(self, + firstSliceAng=0, + holeSize=10, + extLst=None, + **kw + ): + self.firstSliceAng = firstSliceAng + self.holeSize = holeSize + super().__init__(**kw) + + +class CustomSplit(Serialisable): + + tagname = "custSplit" + + secondPiePt = ValueSequence(expected_type=int) + + __elements__ = ('secondPiePt',) + + def __init__(self, + secondPiePt=(), + ): + self.secondPiePt = secondPiePt + + +class ProjectedPieChart(_PieChartBase): + + """ + From the spec 21.2.2.126 + + This element contains the pie of pie or bar of pie series on this + chart. Only the first series shall be displayed. The splitType element + shall determine whether the splitPos and custSplit elements apply. + """ + + tagname = "ofPieChart" + + varyColors = _PieChartBase.varyColors + ser = _PieChartBase.ser + dLbls = _PieChartBase.dLbls + + ofPieType = NestedSet(values=(['pie', 'bar'])) + type = Alias('ofPieType') + gapWidth = NestedGapAmount() + splitType = NestedNoneSet(values=(['auto', 'cust', 'percent', 'pos', 'val'])) + splitPos = NestedFloat(allow_none=True) + custSplit = Typed(expected_type=CustomSplit, allow_none=True) + secondPieSize = NestedMinMax(min=5, max=200, allow_none=True) + serLines = Typed(expected_type=ChartLines, allow_none=True) + join_lines = Alias('serLines') + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = _PieChartBase.__elements__ + ('ofPieType', 'gapWidth', + 'splitType', 'splitPos', 'custSplit', 'secondPieSize', 'serLines') + + def __init__(self, + ofPieType="pie", + gapWidth=None, + splitType="auto", + splitPos=None, + custSplit=None, + secondPieSize=75, + serLines=None, + extLst=None, + **kw + ): + self.ofPieType = ofPieType + self.gapWidth = gapWidth + self.splitType = splitType + self.splitPos = splitPos + self.custSplit = custSplit + self.secondPieSize = secondPieSize + if serLines is None: + self.serLines = ChartLines() + super().__init__(**kw) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/pivot.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/pivot.py new file mode 100644 index 00000000..937fd294 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/pivot.py @@ -0,0 +1,65 @@ + +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Alias, + Typed, +) +from openpyxl.descriptors.nested import NestedInteger, NestedText +from openpyxl.descriptors.excel import ExtensionList + +from .label import DataLabel +from .marker import Marker +from .shapes import GraphicalProperties +from .text import RichText + + +class PivotSource(Serialisable): + + tagname = "pivotSource" + + name = NestedText(expected_type=str) + fmtId = NestedInteger(expected_type=int) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('name', 'fmtId') + + def __init__(self, + name=None, + fmtId=None, + extLst=None, + ): + self.name = name + self.fmtId = fmtId + + +class PivotFormat(Serialisable): + + tagname = "pivotFmt" + + idx = NestedInteger(nested=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias("spPr") + txPr = Typed(expected_type=RichText, allow_none=True) + TextBody = Alias("txPr") + marker = Typed(expected_type=Marker, allow_none=True) + dLbl = Typed(expected_type=DataLabel, allow_none=True) + DataLabel = Alias("dLbl") + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('idx', 'spPr', 'txPr', 'marker', 'dLbl') + + def __init__(self, + idx=0, + spPr=None, + txPr=None, + marker=None, + dLbl=None, + extLst=None, + ): + self.idx = idx + self.spPr = spPr + self.txPr = txPr + self.marker = marker + self.dLbl = dLbl diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/plotarea.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/plotarea.py new file mode 100644 index 00000000..268bfbc4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/plotarea.py @@ -0,0 +1,162 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Alias, +) +from openpyxl.descriptors.excel import ( + ExtensionList, +) +from openpyxl.descriptors.sequence import ( + MultiSequence, + MultiSequencePart, +) +from openpyxl.descriptors.nested import ( + NestedBool, +) + +from ._3d import _3DBase +from .area_chart import AreaChart, AreaChart3D +from .bar_chart import BarChart, BarChart3D +from .bubble_chart import BubbleChart +from .line_chart import LineChart, LineChart3D +from .pie_chart import PieChart, PieChart3D, ProjectedPieChart, DoughnutChart +from .radar_chart import RadarChart +from .scatter_chart import ScatterChart +from .stock_chart import StockChart +from .surface_chart import SurfaceChart, SurfaceChart3D +from .layout import Layout +from .shapes import GraphicalProperties +from .text import RichText + +from .axis import ( + NumericAxis, + TextAxis, + SeriesAxis, + DateAxis, +) + + +class DataTable(Serialisable): + + tagname = "dTable" + + showHorzBorder = NestedBool(allow_none=True) + showVertBorder = NestedBool(allow_none=True) + showOutline = NestedBool(allow_none=True) + showKeys = NestedBool(allow_none=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + txPr = Typed(expected_type=RichText, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('showHorzBorder', 'showVertBorder', 'showOutline', + 'showKeys', 'spPr', 'txPr') + + def __init__(self, + showHorzBorder=None, + showVertBorder=None, + showOutline=None, + showKeys=None, + spPr=None, + txPr=None, + extLst=None, + ): + self.showHorzBorder = showHorzBorder + self.showVertBorder = showVertBorder + self.showOutline = showOutline + self.showKeys = showKeys + self.spPr = spPr + self.txPr = txPr + + +class PlotArea(Serialisable): + + tagname = "plotArea" + + layout = Typed(expected_type=Layout, allow_none=True) + dTable = Typed(expected_type=DataTable, allow_none=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias("spPr") + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + # at least one chart + _charts = MultiSequence() + areaChart = MultiSequencePart(expected_type=AreaChart, store="_charts") + area3DChart = MultiSequencePart(expected_type=AreaChart3D, store="_charts") + lineChart = MultiSequencePart(expected_type=LineChart, store="_charts") + line3DChart = MultiSequencePart(expected_type=LineChart3D, store="_charts") + stockChart = MultiSequencePart(expected_type=StockChart, store="_charts") + radarChart = MultiSequencePart(expected_type=RadarChart, store="_charts") + scatterChart = MultiSequencePart(expected_type=ScatterChart, store="_charts") + pieChart = MultiSequencePart(expected_type=PieChart, store="_charts") + pie3DChart = MultiSequencePart(expected_type=PieChart3D, store="_charts") + doughnutChart = MultiSequencePart(expected_type=DoughnutChart, store="_charts") + barChart = MultiSequencePart(expected_type=BarChart, store="_charts") + bar3DChart = MultiSequencePart(expected_type=BarChart3D, store="_charts") + ofPieChart = MultiSequencePart(expected_type=ProjectedPieChart, store="_charts") + surfaceChart = MultiSequencePart(expected_type=SurfaceChart, store="_charts") + surface3DChart = MultiSequencePart(expected_type=SurfaceChart3D, store="_charts") + bubbleChart = MultiSequencePart(expected_type=BubbleChart, store="_charts") + + # axes + _axes = MultiSequence() + valAx = MultiSequencePart(expected_type=NumericAxis, store="_axes") + catAx = MultiSequencePart(expected_type=TextAxis, store="_axes") + dateAx = MultiSequencePart(expected_type=DateAxis, store="_axes") + serAx = MultiSequencePart(expected_type=SeriesAxis, store="_axes") + + __elements__ = ('layout', '_charts', '_axes', 'dTable', 'spPr') + + def __init__(self, + layout=None, + dTable=None, + spPr=None, + _charts=(), + _axes=(), + extLst=None, + ): + self.layout = layout + self.dTable = dTable + self.spPr = spPr + self._charts = _charts + self._axes = _axes + + + def to_tree(self, tagname=None, idx=None, namespace=None): + axIds = {ax.axId for ax in self._axes} + for chart in self._charts: + for id, axis in chart._axes.items(): + if id not in axIds: + setattr(self, axis.tagname, axis) + axIds.add(id) + + return super().to_tree(tagname) + + + @classmethod + def from_tree(cls, node): + self = super().from_tree(node) + axes = dict((axis.axId, axis) for axis in self._axes) + for chart in self._charts: + if isinstance(chart, (ScatterChart, BubbleChart)): + x, y = (axes[axId] for axId in chart.axId) + chart.x_axis = x + chart.y_axis = y + continue + + for axId in chart.axId: + axis = axes.get(axId) + if axis is None and isinstance(chart, _3DBase): + # Series Axis can be optional + chart.z_axis = None + continue + if axis.tagname in ("catAx", "dateAx"): + chart.x_axis = axis + elif axis.tagname == "valAx": + chart.y_axis = axis + elif axis.tagname == "serAx": + chart.z_axis = axis + + return self diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/print_settings.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/print_settings.py new file mode 100644 index 00000000..65137310 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/print_settings.py @@ -0,0 +1,57 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Float, + Typed, + Alias, +) + +from openpyxl.worksheet.page import PrintPageSetup +from openpyxl.worksheet.header_footer import HeaderFooter + + +class PageMargins(Serialisable): + """ + Identical to openpyxl.worksheet.page.Pagemargins but element names are different :-/ + """ + tagname = "pageMargins" + + l = Float() + left = Alias('l') + r = Float() + right = Alias('r') + t = Float() + top = Alias('t') + b = Float() + bottom = Alias('b') + header = Float() + footer = Float() + + def __init__(self, l=0.75, r=0.75, t=1, b=1, header=0.5, footer=0.5): + self.l = l + self.r = r + self.t = t + self.b = b + self.header = header + self.footer = footer + + +class PrintSettings(Serialisable): + + tagname = "printSettings" + + headerFooter = Typed(expected_type=HeaderFooter, allow_none=True) + pageMargins = Typed(expected_type=PageMargins, allow_none=True) + pageSetup = Typed(expected_type=PrintPageSetup, allow_none=True) + + __elements__ = ("headerFooter", "pageMargins", "pageMargins") + + def __init__(self, + headerFooter=None, + pageMargins=None, + pageSetup=None, + ): + self.headerFooter = headerFooter + self.pageMargins = pageMargins + self.pageSetup = pageSetup diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/radar_chart.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/radar_chart.py new file mode 100644 index 00000000..fa3aa0da --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/radar_chart.py @@ -0,0 +1,55 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Sequence, + Typed, + Alias, +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedBool, + NestedInteger, + NestedSet +) + +from ._chart import ChartBase +from .axis import TextAxis, NumericAxis +from .series import Series +from .label import DataLabelList + + +class RadarChart(ChartBase): + + tagname = "radarChart" + + radarStyle = NestedSet(values=(['standard', 'marker', 'filled'])) + type = Alias("radarStyle") + varyColors = NestedBool(nested=True, allow_none=True) + ser = Sequence(expected_type=Series, allow_none=True) + dLbls = Typed(expected_type=DataLabelList, allow_none=True) + dataLabels = Alias("dLbls") + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + _series_type = "radar" + + x_axis = Typed(expected_type=TextAxis) + y_axis = Typed(expected_type=NumericAxis) + + __elements__ = ('radarStyle', 'varyColors', 'ser', 'dLbls', 'axId') + + def __init__(self, + radarStyle="standard", + varyColors=None, + ser=(), + dLbls=None, + extLst=None, + **kw + ): + self.radarStyle = radarStyle + self.varyColors = varyColors + self.ser = ser + self.dLbls = dLbls + self.x_axis = TextAxis() + self.y_axis = NumericAxis() + super().__init__(**kw) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/reader.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/reader.py new file mode 100644 index 00000000..0ef719f9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/reader.py @@ -0,0 +1,32 @@ +# Copyright (c) 2010-2024 openpyxl + +""" +Read a chart +""" + +def read_chart(chartspace): + cs = chartspace + plot = cs.chart.plotArea + + chart = plot._charts[0] + chart._charts = plot._charts + + chart.title = cs.chart.title + chart.display_blanks = cs.chart.dispBlanksAs + chart.visible_cells_only = cs.chart.plotVisOnly + chart.layout = plot.layout + chart.legend = cs.chart.legend + + # 3d attributes + chart.floor = cs.chart.floor + chart.sideWall = cs.chart.sideWall + chart.backWall = cs.chart.backWall + chart.pivotSource = cs.pivotSource + chart.pivotFormats = cs.chart.pivotFmts + chart.idx_base = min((s.idx for s in chart.series), default=0) + chart._reindex() + + # Border, fill, etc. + chart.graphical_properties = cs.graphical_properties + + return chart diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/reference.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/reference.py new file mode 100644 index 00000000..dc102791 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/reference.py @@ -0,0 +1,124 @@ +# Copyright (c) 2010-2024 openpyxl + +from itertools import chain + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + MinMax, + Typed, + String, + Strict, +) +from openpyxl.worksheet.worksheet import Worksheet +from openpyxl.utils import ( + get_column_letter, + range_to_tuple, + quote_sheetname +) + + +class DummyWorksheet: + + + def __init__(self, title): + self.title = title + + +class Reference(Strict): + + """ + Normalise cell range references + """ + + min_row = MinMax(min=1, max=1000000, expected_type=int) + max_row = MinMax(min=1, max=1000000, expected_type=int) + min_col = MinMax(min=1, max=16384, expected_type=int) + max_col = MinMax(min=1, max=16384, expected_type=int) + range_string = String(allow_none=True) + + def __init__(self, + worksheet=None, + min_col=None, + min_row=None, + max_col=None, + max_row=None, + range_string=None + ): + if range_string is not None: + sheetname, boundaries = range_to_tuple(range_string) + min_col, min_row, max_col, max_row = boundaries + worksheet = DummyWorksheet(sheetname) + + self.worksheet = worksheet + self.min_col = min_col + self.min_row = min_row + if max_col is None: + max_col = min_col + self.max_col = max_col + if max_row is None: + max_row = min_row + self.max_row = max_row + + + def __repr__(self): + return str(self) + + + def __str__(self): + fmt = u"{0}!${1}${2}:${3}${4}" + if (self.min_col == self.max_col + and self.min_row == self.max_row): + fmt = u"{0}!${1}${2}" + return fmt.format(self.sheetname, + get_column_letter(self.min_col), self.min_row, + get_column_letter(self.max_col), self.max_row + ) + + + __str__ = __str__ + + + + def __len__(self): + if self.min_row == self.max_row: + return 1 + self.max_col - self.min_col + return 1 + self.max_row - self.min_row + + + def __eq__(self, other): + return str(self) == str(other) + + + @property + def rows(self): + """ + Return all rows in the range + """ + for row in range(self.min_row, self.max_row+1): + yield Reference(self.worksheet, self.min_col, row, self.max_col, row) + + + @property + def cols(self): + """ + Return all columns in the range + """ + for col in range(self.min_col, self.max_col+1): + yield Reference(self.worksheet, col, self.min_row, col, self.max_row) + + + def pop(self): + """ + Return and remove the first cell + """ + cell = "{0}{1}".format(get_column_letter(self.min_col), self.min_row) + if self.min_row == self.max_row: + self.min_col += 1 + else: + self.min_row += 1 + return cell + + + @property + def sheetname(self): + return quote_sheetname(self.worksheet.title) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/scatter_chart.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/scatter_chart.py new file mode 100644 index 00000000..2699239e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/scatter_chart.py @@ -0,0 +1,53 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Sequence, + Alias +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedNoneSet, + NestedBool, +) + +from ._chart import ChartBase +from .axis import NumericAxis, TextAxis +from .series import XYSeries +from .label import DataLabelList + + +class ScatterChart(ChartBase): + + tagname = "scatterChart" + + scatterStyle = NestedNoneSet(values=(['line', 'lineMarker', 'marker', 'smooth', 'smoothMarker'])) + varyColors = NestedBool(allow_none=True) + ser = Sequence(expected_type=XYSeries, allow_none=True) + dLbls = Typed(expected_type=DataLabelList, allow_none=True) + dataLabels = Alias("dLbls") + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + x_axis = Typed(expected_type=(NumericAxis, TextAxis)) + y_axis = Typed(expected_type=NumericAxis) + + _series_type = "scatter" + + __elements__ = ('scatterStyle', 'varyColors', 'ser', 'dLbls', 'axId',) + + def __init__(self, + scatterStyle=None, + varyColors=None, + ser=(), + dLbls=None, + extLst=None, + **kw + ): + self.scatterStyle = scatterStyle + self.varyColors = varyColors + self.ser = ser + self.dLbls = dLbls + self.x_axis = NumericAxis(axId=10, crossAx=20) + self.y_axis = NumericAxis(axId=20, crossAx=10) + super().__init__(**kw) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/series.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/series.py new file mode 100644 index 00000000..f1403a6c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/series.py @@ -0,0 +1,197 @@ +# Copyright (c) 2010-2024 openpyxl + + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + String, + Integer, + Bool, + Alias, + Sequence, +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedInteger, + NestedBool, + NestedNoneSet, + NestedText, +) + +from .shapes import GraphicalProperties +from .data_source import ( + AxDataSource, + NumDataSource, + NumRef, + StrRef, +) +from .error_bar import ErrorBars +from .label import DataLabelList +from .marker import DataPoint, PictureOptions, Marker +from .trendline import Trendline + +attribute_mapping = { + 'area': ('idx', 'order', 'tx', 'spPr', 'pictureOptions', 'dPt', 'dLbls', 'errBars', + 'trendline', 'cat', 'val',), + 'bar':('idx', 'order','tx', 'spPr', 'invertIfNegative', 'pictureOptions', 'dPt', + 'dLbls', 'trendline', 'errBars', 'cat', 'val', 'shape'), + 'bubble':('idx','order', 'tx', 'spPr', 'invertIfNegative', 'dPt', 'dLbls', + 'trendline', 'errBars', 'xVal', 'yVal', 'bubbleSize', 'bubble3D'), + 'line':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'trendline', + 'errBars', 'cat', 'val', 'smooth'), + 'pie':('idx', 'order', 'tx', 'spPr', 'explosion', 'dPt', 'dLbls', 'cat', 'val'), + 'radar':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'cat', 'val'), + 'scatter':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'trendline', + 'errBars', 'xVal', 'yVal', 'smooth'), + 'surface':('idx', 'order', 'tx', 'spPr', 'cat', 'val'), + } + + +class SeriesLabel(Serialisable): + + tagname = "tx" + + strRef = Typed(expected_type=StrRef, allow_none=True) + v = NestedText(expected_type=str, allow_none=True) + value = Alias('v') + + __elements__ = ('strRef', 'v') + + def __init__(self, + strRef=None, + v=None): + self.strRef = strRef + self.v = v + + +class Series(Serialisable): + + """ + Generic series object. Should not be instantiated directly. + User the chart.Series factory instead. + """ + + tagname = "ser" + + idx = NestedInteger() + order = NestedInteger() + tx = Typed(expected_type=SeriesLabel, allow_none=True) + title = Alias('tx') + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + + # area chart + pictureOptions = Typed(expected_type=PictureOptions, allow_none=True) + dPt = Sequence(expected_type=DataPoint, allow_none=True) + data_points = Alias("dPt") + dLbls = Typed(expected_type=DataLabelList, allow_none=True) + labels = Alias("dLbls") + trendline = Typed(expected_type=Trendline, allow_none=True) + errBars = Typed(expected_type=ErrorBars, allow_none=True) + cat = Typed(expected_type=AxDataSource, allow_none=True) + identifiers = Alias("cat") + val = Typed(expected_type=NumDataSource, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + #bar chart + invertIfNegative = NestedBool(allow_none=True) + shape = NestedNoneSet(values=(['cone', 'coneToMax', 'box', 'cylinder', 'pyramid', 'pyramidToMax'])) + + #bubble chart + xVal = Typed(expected_type=AxDataSource, allow_none=True) + yVal = Typed(expected_type=NumDataSource, allow_none=True) + bubbleSize = Typed(expected_type=NumDataSource, allow_none=True) + zVal = Alias("bubbleSize") + bubble3D = NestedBool(allow_none=True) + + #line chart + marker = Typed(expected_type=Marker, allow_none=True) + smooth = NestedBool(allow_none=True) + + #pie chart + explosion = NestedInteger(allow_none=True) + + __elements__ = () + + + def __init__(self, + idx=0, + order=0, + tx=None, + spPr=None, + pictureOptions=None, + dPt=(), + dLbls=None, + trendline=None, + errBars=None, + cat=None, + val=None, + invertIfNegative=None, + shape=None, + xVal=None, + yVal=None, + bubbleSize=None, + bubble3D=None, + marker=None, + smooth=None, + explosion=None, + extLst=None, + ): + self.idx = idx + self.order = order + self.tx = tx + if spPr is None: + spPr = GraphicalProperties() + self.spPr = spPr + self.pictureOptions = pictureOptions + self.dPt = dPt + self.dLbls = dLbls + self.trendline = trendline + self.errBars = errBars + self.cat = cat + self.val = val + self.invertIfNegative = invertIfNegative + self.shape = shape + self.xVal = xVal + self.yVal = yVal + self.bubbleSize = bubbleSize + self.bubble3D = bubble3D + if marker is None: + marker = Marker() + self.marker = marker + self.smooth = smooth + self.explosion = explosion + + + def to_tree(self, tagname=None, idx=None): + """The index can need rebasing""" + if idx is not None: + if self.order == self.idx: + self.order = idx # rebase the order if the index has been rebased + self.idx = idx + return super().to_tree(tagname) + + +class XYSeries(Series): + + """Dedicated series for charts that have x and y series""" + + idx = Series.idx + order = Series.order + tx = Series.tx + spPr = Series.spPr + + dPt = Series.dPt + dLbls = Series.dLbls + trendline = Series.trendline + errBars = Series.errBars + xVal = Series.xVal + yVal = Series.yVal + + invertIfNegative = Series.invertIfNegative + + bubbleSize = Series.bubbleSize + bubble3D = Series.bubble3D + + marker = Series.marker + smooth = Series.smooth diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/series_factory.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/series_factory.py new file mode 100644 index 00000000..90b368d9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/series_factory.py @@ -0,0 +1,41 @@ +# Copyright (c) 2010-2024 openpyxl + +from .data_source import NumDataSource, NumRef, AxDataSource +from .reference import Reference +from .series import Series, XYSeries, SeriesLabel, StrRef +from openpyxl.utils import rows_from_range, quote_sheetname + + +def SeriesFactory(values, xvalues=None, zvalues=None, title=None, title_from_data=False): + """ + Convenience Factory for creating chart data series. + """ + + if not isinstance(values, Reference): + values = Reference(range_string=values) + + if title_from_data: + cell = values.pop() + title = u"{0}!{1}".format(values.sheetname, cell) + title = SeriesLabel(strRef=StrRef(title)) + elif title is not None: + title = SeriesLabel(v=title) + + source = NumDataSource(numRef=NumRef(f=values)) + if xvalues is not None: + if not isinstance(xvalues, Reference): + xvalues = Reference(range_string=xvalues) + series = XYSeries() + series.yVal = source + series.xVal = AxDataSource(numRef=NumRef(f=xvalues)) + if zvalues is not None: + if not isinstance(zvalues, Reference): + zvalues = Reference(range_string=zvalues) + series.zVal = NumDataSource(NumRef(f=zvalues)) + else: + series = Series() + series.val = source + + if title is not None: + series.title = title + return series diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/shapes.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/shapes.py new file mode 100644 index 00000000..7736c1ad --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/shapes.py @@ -0,0 +1,89 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Alias +) +from openpyxl.descriptors.nested import ( + EmptyTag +) +from openpyxl.drawing.colors import ColorChoiceDescriptor +from openpyxl.drawing.fill import * +from openpyxl.drawing.line import LineProperties +from openpyxl.drawing.geometry import ( + Shape3D, + Scene3D, + Transform2D, + CustomGeometry2D, + PresetGeometry2D, +) + + +class GraphicalProperties(Serialisable): + + """ + Somewhat vaguely 21.2.2.197 says this: + + This element specifies the formatting for the parent chart element. The + custGeom, prstGeom, scene3d, and xfrm elements are not supported. The + bwMode attribute is not supported. + + This doesn't leave much. And the element is used in different places. + """ + + tagname = "spPr" + + bwMode = NoneSet(values=(['clr', 'auto', 'gray', 'ltGray', 'invGray', + 'grayWhite', 'blackGray', 'blackWhite', 'black', 'white', 'hidden'] + ) + ) + + xfrm = Typed(expected_type=Transform2D, allow_none=True) + transform = Alias('xfrm') + custGeom = Typed(expected_type=CustomGeometry2D, allow_none=True) # either or + prstGeom = Typed(expected_type=PresetGeometry2D, allow_none=True) + + # fills one of + noFill = EmptyTag(namespace=DRAWING_NS) + solidFill = ColorChoiceDescriptor() + gradFill = Typed(expected_type=GradientFillProperties, allow_none=True) + pattFill = Typed(expected_type=PatternFillProperties, allow_none=True) + + ln = Typed(expected_type=LineProperties, allow_none=True) + line = Alias('ln') + scene3d = Typed(expected_type=Scene3D, allow_none=True) + sp3d = Typed(expected_type=Shape3D, allow_none=True) + shape3D = Alias('sp3d') + extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True) + + __elements__ = ('xfrm', 'prstGeom', 'noFill', 'solidFill', 'gradFill', 'pattFill', + 'ln', 'scene3d', 'sp3d') + + def __init__(self, + bwMode=None, + xfrm=None, + noFill=None, + solidFill=None, + gradFill=None, + pattFill=None, + ln=None, + scene3d=None, + custGeom=None, + prstGeom=None, + sp3d=None, + extLst=None, + ): + self.bwMode = bwMode + self.xfrm = xfrm + self.noFill = noFill + self.solidFill = solidFill + self.gradFill = gradFill + self.pattFill = pattFill + if ln is None: + ln = LineProperties() + self.ln = ln + self.custGeom = custGeom + self.prstGeom = prstGeom + self.scene3d = scene3d + self.sp3d = sp3d diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/stock_chart.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/stock_chart.py new file mode 100644 index 00000000..119c7901 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/stock_chart.py @@ -0,0 +1,54 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Sequence, + Alias, +) +from openpyxl.descriptors.excel import ExtensionList + +from ._chart import ChartBase +from .axis import TextAxis, NumericAxis, ChartLines +from .updown_bars import UpDownBars +from .label import DataLabelList +from .series import Series + + +class StockChart(ChartBase): + + tagname = "stockChart" + + ser = Sequence(expected_type=Series) #min 3, max4 + dLbls = Typed(expected_type=DataLabelList, allow_none=True) + dataLabels = Alias('dLbls') + dropLines = Typed(expected_type=ChartLines, allow_none=True) + hiLowLines = Typed(expected_type=ChartLines, allow_none=True) + upDownBars = Typed(expected_type=UpDownBars, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + x_axis = Typed(expected_type=TextAxis) + y_axis = Typed(expected_type=NumericAxis) + + _series_type = "line" + + __elements__ = ('ser', 'dLbls', 'dropLines', 'hiLowLines', 'upDownBars', + 'axId') + + def __init__(self, + ser=(), + dLbls=None, + dropLines=None, + hiLowLines=None, + upDownBars=None, + extLst=None, + **kw + ): + self.ser = ser + self.dLbls = dLbls + self.dropLines = dropLines + self.hiLowLines = hiLowLines + self.upDownBars = upDownBars + self.x_axis = TextAxis() + self.y_axis = NumericAxis() + super().__init__(**kw) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/surface_chart.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/surface_chart.py new file mode 100644 index 00000000..5f388e14 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/surface_chart.py @@ -0,0 +1,119 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Integer, + Bool, + Alias, + Sequence, +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedInteger, + NestedBool, +) + +from ._chart import ChartBase +from ._3d import _3DBase +from .axis import TextAxis, NumericAxis, SeriesAxis +from .shapes import GraphicalProperties +from .series import Series + + +class BandFormat(Serialisable): + + tagname = "bandFmt" + + idx = NestedInteger() + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias("spPr") + + __elements__ = ('idx', 'spPr') + + def __init__(self, + idx=0, + spPr=None, + ): + self.idx = idx + self.spPr = spPr + + +class BandFormatList(Serialisable): + + tagname = "bandFmts" + + bandFmt = Sequence(expected_type=BandFormat, allow_none=True) + + __elements__ = ('bandFmt',) + + def __init__(self, + bandFmt=(), + ): + self.bandFmt = bandFmt + + +class _SurfaceChartBase(ChartBase): + + wireframe = NestedBool(allow_none=True) + ser = Sequence(expected_type=Series, allow_none=True) + bandFmts = Typed(expected_type=BandFormatList, allow_none=True) + + _series_type = "surface" + + __elements__ = ('wireframe', 'ser', 'bandFmts') + + def __init__(self, + wireframe=None, + ser=(), + bandFmts=None, + **kw + ): + self.wireframe = wireframe + self.ser = ser + self.bandFmts = bandFmts + super().__init__(**kw) + + +class SurfaceChart3D(_SurfaceChartBase, _3DBase): + + tagname = "surface3DChart" + + wireframe = _SurfaceChartBase.wireframe + ser = _SurfaceChartBase.ser + bandFmts = _SurfaceChartBase.bandFmts + + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + x_axis = Typed(expected_type=TextAxis) + y_axis = Typed(expected_type=NumericAxis) + z_axis = Typed(expected_type=SeriesAxis) + + __elements__ = _SurfaceChartBase.__elements__ + ('axId',) + + def __init__(self, **kw): + self.x_axis = TextAxis() + self.y_axis = NumericAxis() + self.z_axis = SeriesAxis() + super(SurfaceChart3D, self).__init__(**kw) + + +class SurfaceChart(SurfaceChart3D): + + tagname = "surfaceChart" + + wireframe = _SurfaceChartBase.wireframe + ser = _SurfaceChartBase.ser + bandFmts = _SurfaceChartBase.bandFmts + + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = SurfaceChart3D.__elements__ + + def __init__(self, **kw): + super().__init__(**kw) + self.y_axis.delete = True + self.view3D.x_rotation = 90 + self.view3D.y_rotation = 0 + self.view3D.perspective = False + self.view3D.right_angle_axes = False diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/text.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/text.py new file mode 100644 index 00000000..bd034c24 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/text.py @@ -0,0 +1,78 @@ +# Copyright (c) 2010-2024 openpyxl +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Alias, + Sequence, +) + + +from openpyxl.drawing.text import ( + RichTextProperties, + ListStyle, + Paragraph, +) + +from .data_source import StrRef + + +class RichText(Serialisable): + + """ + From the specification: 21.2.2.216 + + This element specifies text formatting. The lstStyle element is not supported. + """ + + tagname = "rich" + + bodyPr = Typed(expected_type=RichTextProperties) + properties = Alias("bodyPr") + lstStyle = Typed(expected_type=ListStyle, allow_none=True) + p = Sequence(expected_type=Paragraph) + paragraphs = Alias('p') + + __elements__ = ("bodyPr", "lstStyle", "p") + + def __init__(self, + bodyPr=None, + lstStyle=None, + p=None, + ): + if bodyPr is None: + bodyPr = RichTextProperties() + self.bodyPr = bodyPr + self.lstStyle = lstStyle + if p is None: + p = [Paragraph()] + self.p = p + + +class Text(Serialisable): + + """ + The value can be either a cell reference or a text element + If both are present then the reference will be used. + """ + + tagname = "tx" + + strRef = Typed(expected_type=StrRef, allow_none=True) + rich = Typed(expected_type=RichText, allow_none=True) + + __elements__ = ("strRef", "rich") + + def __init__(self, + strRef=None, + rich=None + ): + self.strRef = strRef + if rich is None: + rich = RichText() + self.rich = rich + + + def to_tree(self, tagname=None, idx=None, namespace=None): + if self.strRef and self.rich: + self.rich = None # can only have one + return super().to_tree(tagname, idx, namespace) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/title.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/title.py new file mode 100644 index 00000000..10f79d7a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/title.py @@ -0,0 +1,76 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Alias, +) + +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import NestedBool + +from .text import Text, RichText +from .layout import Layout +from .shapes import GraphicalProperties + +from openpyxl.drawing.text import ( + Paragraph, + RegularTextRun, + LineBreak, + ParagraphProperties, + CharacterProperties, +) + + +class Title(Serialisable): + tagname = "title" + + tx = Typed(expected_type=Text, allow_none=True) + text = Alias('tx') + layout = Typed(expected_type=Layout, allow_none=True) + overlay = NestedBool(allow_none=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + txPr = Typed(expected_type=RichText, allow_none=True) + body = Alias('txPr') + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('tx', 'layout', 'overlay', 'spPr', 'txPr') + + def __init__(self, + tx=None, + layout=None, + overlay=None, + spPr=None, + txPr=None, + extLst=None, + ): + if tx is None: + tx = Text() + self.tx = tx + self.layout = layout + self.overlay = overlay + self.spPr = spPr + self.txPr = txPr + + + +def title_maker(text): + title = Title() + paraprops = ParagraphProperties() + paraprops.defRPr = CharacterProperties() + paras = [Paragraph(r=[RegularTextRun(t=s)], pPr=paraprops) for s in text.split("\n")] + + title.tx.rich.paragraphs = paras + return title + + +class TitleDescriptor(Typed): + + expected_type = Title + allow_none = True + + def __set__(self, instance, value): + if isinstance(value, str): + value = title_maker(value) + super().__set__(instance, value) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/trendline.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/trendline.py new file mode 100644 index 00000000..bf6d2366 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/trendline.py @@ -0,0 +1,98 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + String, + Alias +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedBool, + NestedInteger, + NestedFloat, + NestedSet +) + +from .data_source import NumFmt +from .shapes import GraphicalProperties +from .text import RichText, Text +from .layout import Layout + + +class TrendlineLabel(Serialisable): + + tagname = "trendlineLbl" + + layout = Typed(expected_type=Layout, allow_none=True) + tx = Typed(expected_type=Text, allow_none=True) + numFmt = Typed(expected_type=NumFmt, allow_none=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias("spPr") + txPr = Typed(expected_type=RichText, allow_none=True) + textProperties = Alias("txPr") + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('layout', 'tx', 'numFmt', 'spPr', 'txPr') + + def __init__(self, + layout=None, + tx=None, + numFmt=None, + spPr=None, + txPr=None, + extLst=None, + ): + self.layout = layout + self.tx = tx + self.numFmt = numFmt + self.spPr = spPr + self.txPr = txPr + + +class Trendline(Serialisable): + + tagname = "trendline" + + name = String(allow_none=True) + spPr = Typed(expected_type=GraphicalProperties, allow_none=True) + graphicalProperties = Alias('spPr') + trendlineType = NestedSet(values=(['exp', 'linear', 'log', 'movingAvg', 'poly', 'power'])) + order = NestedInteger(allow_none=True) + period = NestedInteger(allow_none=True) + forward = NestedFloat(allow_none=True) + backward = NestedFloat(allow_none=True) + intercept = NestedFloat(allow_none=True) + dispRSqr = NestedBool(allow_none=True) + dispEq = NestedBool(allow_none=True) + trendlineLbl = Typed(expected_type=TrendlineLabel, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('spPr', 'trendlineType', 'order', 'period', 'forward', + 'backward', 'intercept', 'dispRSqr', 'dispEq', 'trendlineLbl') + + def __init__(self, + name=None, + spPr=None, + trendlineType='linear', + order=None, + period=None, + forward=None, + backward=None, + intercept=None, + dispRSqr=None, + dispEq=None, + trendlineLbl=None, + extLst=None, + ): + self.name = name + self.spPr = spPr + self.trendlineType = trendlineType + self.order = order + self.period = period + self.forward = forward + self.backward = backward + self.intercept = intercept + self.dispRSqr = dispRSqr + self.dispEq = dispEq + self.trendlineLbl = trendlineLbl diff --git a/.venv/lib/python3.12/site-packages/openpyxl/chart/updown_bars.py b/.venv/lib/python3.12/site-packages/openpyxl/chart/updown_bars.py new file mode 100644 index 00000000..6de7ab8a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/chart/updown_bars.py @@ -0,0 +1,31 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import Typed +from openpyxl.descriptors.excel import ExtensionList + +from .shapes import GraphicalProperties +from .axis import ChartLines +from .descriptors import NestedGapAmount + + +class UpDownBars(Serialisable): + + tagname = "upbars" + + gapWidth = NestedGapAmount() + upBars = Typed(expected_type=ChartLines, allow_none=True) + downBars = Typed(expected_type=ChartLines, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('gapWidth', 'upBars', 'downBars') + + def __init__(self, + gapWidth=150, + upBars=None, + downBars=None, + extLst=None, + ): + self.gapWidth = gapWidth + self.upBars = upBars + self.downBars = downBars |