forked from Alsan/Post_finder
402 lines
12 KiB
Python
402 lines
12 KiB
Python
# 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)
|