1from __future__ import absolute_import
2# Copyright (c) 2010-2019 openpyxl
3
4"""
5Enclosing chart object. The various chart types are actually child objects.
6Will probably need to call this indirectly
7"""
8
9from openpyxl.descriptors.serialisable import Serialisable
10from openpyxl.descriptors import (
11    Typed,
12    String,
13    Alias,
14)
15from openpyxl.descriptors.excel import (
16    ExtensionList,
17    Relation
18)
19from openpyxl.descriptors.nested import (
20    NestedBool,
21    NestedNoneSet,
22    NestedString,
23    NestedMinMax,
24)
25from openpyxl.descriptors.sequence import NestedSequence
26from openpyxl.xml.constants import CHART_NS
27
28from openpyxl.drawing.colors import ColorMapping
29from .text import RichText
30from .shapes import GraphicalProperties
31from .legend import Legend
32from ._3d import _3DBase
33from .plotarea import PlotArea
34from .title import Title
35from .pivot import (
36    PivotFormat,
37    PivotSource,
38)
39from .print_settings import PrintSettings
40
41
42class ChartContainer(Serialisable):
43
44    tagname = "chart"
45
46    title = Typed(expected_type=Title, allow_none=True)
47    autoTitleDeleted = NestedBool(allow_none=True)
48    pivotFmts = NestedSequence(expected_type=PivotFormat)
49    view3D = _3DBase.view3D
50    floor = _3DBase.floor
51    sideWall = _3DBase.sideWall
52    backWall = _3DBase.backWall
53    plotArea = Typed(expected_type=PlotArea, )
54    legend = Typed(expected_type=Legend, allow_none=True)
55    plotVisOnly = NestedBool()
56    dispBlanksAs = NestedNoneSet(values=(['span', 'gap', 'zero']))
57    showDLblsOverMax = NestedBool(allow_none=True)
58    extLst = Typed(expected_type=ExtensionList, allow_none=True)
59
60    __elements__ = ('title', 'autoTitleDeleted', 'pivotFmts', 'view3D',
61                    'floor', 'sideWall', 'backWall', 'plotArea', 'legend', 'plotVisOnly',
62                    'dispBlanksAs', 'showDLblsOverMax')
63
64    def __init__(self,
65                 title=None,
66                 autoTitleDeleted=None,
67                 pivotFmts=(),
68                 view3D=None,
69                 floor=None,
70                 sideWall=None,
71                 backWall=None,
72                 plotArea=None,
73                 legend=None,
74                 plotVisOnly=True,
75                 dispBlanksAs="gap",
76                 showDLblsOverMax=None,
77                 extLst=None,
78                ):
79        self.title = title
80        self.autoTitleDeleted = autoTitleDeleted
81        self.pivotFmts = pivotFmts
82        self.view3D = view3D
83        self.floor = floor
84        self.sideWall = sideWall
85        self.backWall = backWall
86        if plotArea is None:
87            plotArea = PlotArea()
88        self.plotArea = plotArea
89        self.legend = legend
90        self.plotVisOnly = plotVisOnly
91        self.dispBlanksAs = dispBlanksAs
92        self.showDLblsOverMax = showDLblsOverMax
93
94
95class Protection(Serialisable):
96
97    tagname = "protection"
98
99    chartObject = NestedBool(allow_none=True)
100    data = NestedBool(allow_none=True)
101    formatting = NestedBool(allow_none=True)
102    selection = NestedBool(allow_none=True)
103    userInterface = NestedBool(allow_none=True)
104
105    __elements__ = ("chartObject", "data", "formatting", "selection", "userInterface")
106
107    def __init__(self,
108                 chartObject=None,
109                 data=None,
110                 formatting=None,
111                 selection=None,
112                 userInterface=None,
113                ):
114        self.chartObject = chartObject
115        self.data = data
116        self.formatting = formatting
117        self.selection = selection
118        self.userInterface = userInterface
119
120
121class ExternalData(Serialisable):
122
123    tagname = "externalData"
124
125    autoUpdate = NestedBool(allow_none=True)
126    id = String() # Needs namespace
127
128    def __init__(self,
129                 autoUpdate=None,
130                 id=None
131                ):
132        self.autoUpdate = autoUpdate
133        self.id = id
134
135
136class ChartSpace(Serialisable):
137
138    tagname = "chartSpace"
139
140    date1904 = NestedBool(allow_none=True)
141    lang = NestedString(allow_none=True)
142    roundedCorners = NestedBool(allow_none=True)
143    style = NestedMinMax(allow_none=True, min=1, max=48)
144    clrMapOvr = Typed(expected_type=ColorMapping, allow_none=True)
145    pivotSource = Typed(expected_type=PivotSource, allow_none=True)
146    protection = Typed(expected_type=Protection, allow_none=True)
147    chart = Typed(expected_type=ChartContainer)
148    spPr = Typed(expected_type=GraphicalProperties, allow_none=True)
149    graphicalProperties = Alias("spPr")
150    txPr = Typed(expected_type=RichText, allow_none=True)
151    textProperties = Alias("txPr")
152    externalData = Typed(expected_type=ExternalData, allow_none=True)
153    printSettings = Typed(expected_type=PrintSettings, allow_none=True)
154    userShapes = Relation()
155    extLst = Typed(expected_type=ExtensionList, allow_none=True)
156
157    __elements__ = ('date1904', 'lang', 'roundedCorners', 'style',
158                    'clrMapOvr', 'pivotSource', 'protection', 'chart', 'spPr', 'txPr',
159                    'externalData', 'printSettings', 'userShapes')
160
161    def __init__(self,
162                 date1904=None,
163                 lang=None,
164                 roundedCorners=None,
165                 style=None,
166                 clrMapOvr=None,
167                 pivotSource=None,
168                 protection=None,
169                 chart=None,
170                 spPr=None,
171                 txPr=None,
172                 externalData=None,
173                 printSettings=None,
174                 userShapes=None,
175                 extLst=None,
176                ):
177        self.date1904 = date1904
178        self.lang = lang
179        self.roundedCorners = roundedCorners
180        self.style = style
181        self.clrMapOvr = clrMapOvr
182        self.pivotSource = pivotSource
183        self.protection = protection
184        self.chart = chart
185        self.spPr = spPr
186        self.txPr = txPr
187        self.externalData = externalData
188        self.printSettings = printSettings
189        self.userShapes = userShapes
190
191
192    def to_tree(self, tagname=None, idx=None, namespace=None):
193        tree = super(ChartSpace, self).to_tree()
194        tree.set("xmlns", CHART_NS)
195        return tree
196