xref: /trunk/test/odf-validate/fixtures/chart/make.py (revision 0e16a31d78a652c56c5c0fc79c752f48b9048df9)
1*0e16a31dSJim Jagielski#**************************************************************
2*0e16a31dSJim Jagielski#
3*0e16a31dSJim Jagielski#  Licensed to the Apache Software Foundation (ASF) under one
4*0e16a31dSJim Jagielski#  or more contributor license agreements.  See the NOTICE file
5*0e16a31dSJim Jagielski#  distributed with this work for additional information
6*0e16a31dSJim Jagielski#  regarding copyright ownership.  The ASF licenses this file
7*0e16a31dSJim Jagielski#  to you under the Apache License, Version 2.0 (the
8*0e16a31dSJim Jagielski#  "License"); you may not use this file except in compliance
9*0e16a31dSJim Jagielski#  with the License.  You may obtain a copy of the License at
10*0e16a31dSJim Jagielski#
11*0e16a31dSJim Jagielski#    http://www.apache.org/licenses/LICENSE-2.0
12*0e16a31dSJim Jagielski#
13*0e16a31dSJim Jagielski#  Unless required by applicable law or agreed to in writing,
14*0e16a31dSJim Jagielski#  software distributed under the License is distributed on an
15*0e16a31dSJim Jagielski#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*0e16a31dSJim Jagielski#  KIND, either express or implied.  See the License for the
17*0e16a31dSJim Jagielski#  specific language governing permissions and limitations
18*0e16a31dSJim Jagielski#  under the License.
19*0e16a31dSJim Jagielski#
20*0e16a31dSJim Jagielski#**************************************************************
21*0e16a31dSJim Jagielski# usage: runpy.sh fixtures/chart/make.py <port> <outdir>
22*0e16a31dSJim Jagielski# Charts inside Calc, Writer and Impress/Draw hosts (a standalone chart model crashes the office on store). Saves with the office's configured ODF version.
23*0e16a31dSJim Jagielskiimport sys, os, uno
24*0e16a31dSJim Jagielskifrom unohelp import connect, desktop, pv
25*0e16a31dSJim Jagielskifrom com.sun.star.awt import Rectangle, Size, Point
26*0e16a31dSJim Jagielskifrom com.sun.star.table import CellRangeAddress
27*0e16a31dSJim Jagielskifrom com.sun.star.chart.ChartDataRowSource import COLUMNS, ROWS
28*0e16a31dSJim Jagielski
29*0e16a31dSJim Jagielskiport, out = int(sys.argv[1]), sys.argv[2]
30*0e16a31dSJim Jagielskios.makedirs(out, exist_ok=True)
31*0e16a31dSJim Jagielskictx = connect(port)
32*0e16a31dSJim Jagielskidesk = desktop(ctx)
33*0e16a31dSJim Jagielskifailed = []
34*0e16a31dSJim JagielskiFILTERS = {"ods": "calc8", "odt": "writer8", "odp": "impress8", "odg": "draw8"}
35*0e16a31dSJim JagielskiTPL = "com.sun.star.chart2.template."
36*0e16a31dSJim JagielskiC2 = "com.sun.star.chart2."
37*0e16a31dSJim Jagielski
38*0e16a31dSJim Jagielski
39*0e16a31dSJim Jagielskidef new(factory):
40*0e16a31dSJim Jagielski    return desk.loadComponentFromURL(factory, "_blank", 0, (pv("Hidden", True),))
41*0e16a31dSJim Jagielski
42*0e16a31dSJim Jagielski
43*0e16a31dSJim Jagielskidef save(doc, name):
44*0e16a31dSJim Jagielski    try:
45*0e16a31dSJim Jagielski        doc.storeToURL(uno.systemPathToFileUrl(os.path.join(out, name)),
46*0e16a31dSJim Jagielski                       (pv("FilterName", FILTERS[name.rsplit(".", 1)[1]]),))
47*0e16a31dSJim Jagielski        print("saved", name)
48*0e16a31dSJim Jagielski    except Exception as e:
49*0e16a31dSJim Jagielski        failed.append(name)
50*0e16a31dSJim Jagielski        print("FAIL save", name, repr(e)[:200])
51*0e16a31dSJim Jagielski
52*0e16a31dSJim Jagielski
53*0e16a31dSJim Jagielskidef attempt(label, fn, *a, **kw):
54*0e16a31dSJim Jagielski    try:
55*0e16a31dSJim Jagielski        return fn(*a, **kw)
56*0e16a31dSJim Jagielski    except Exception as e:
57*0e16a31dSJim Jagielski        failed.append(label)
58*0e16a31dSJim Jagielski        print("FAIL", label, repr(e)[:300])
59*0e16a31dSJim Jagielski
60*0e16a31dSJim Jagielski
61*0e16a31dSJim Jagielskidef setp(obj, label="", **kw):
62*0e16a31dSJim Jagielski    for k, v in kw.items():
63*0e16a31dSJim Jagielski        try:
64*0e16a31dSJim Jagielski            try:
65*0e16a31dSJim Jagielski                obj.setPropertyValue(k, v)
66*0e16a31dSJim Jagielski            except AttributeError:
67*0e16a31dSJim Jagielski                setattr(obj, k, v)
68*0e16a31dSJim Jagielski        except Exception as e:
69*0e16a31dSJim Jagielski            print("NOPROP", label, k, repr(e)[:120])
70*0e16a31dSJim Jagielski
71*0e16a31dSJim Jagielski
72*0e16a31dSJim Jagielskidef const(name):
73*0e16a31dSJim Jagielski    return uno.getConstantByName(name)
74*0e16a31dSJim Jagielski
75*0e16a31dSJim Jagielski
76*0e16a31dSJim Jagielskidef enum(typ, val):
77*0e16a31dSJim Jagielski    return uno.Enum(typ, val)
78*0e16a31dSJim Jagielski
79*0e16a31dSJim Jagielski
80*0e16a31dSJim JagielskiCATS = ["Q1", "Q2", "Q3", "Q4", "Q5", "Q6"]
81*0e16a31dSJim JagielskiBLOCKS = {}
82*0e16a31dSJim Jagielski
83*0e16a31dSJim Jagielski
84*0e16a31dSJim Jagielskidef fill_data(sh):
85*0e16a31dSJim Jagielski    def put(col, row, v):
86*0e16a31dSJim Jagielski        c = sh.getCellByPosition(col, row)
87*0e16a31dSJim Jagielski        if isinstance(v, str):
88*0e16a31dSJim Jagielski            c.String = v
89*0e16a31dSJim Jagielski        else:
90*0e16a31dSJim Jagielski            c.Value = v
91*0e16a31dSJim Jagielski
92*0e16a31dSJim Jagielski    def cats(col, hdr=""):
93*0e16a31dSJim Jagielski        put(col, 0, hdr)
94*0e16a31dSJim Jagielski        for r, t in enumerate(CATS):
95*0e16a31dSJim Jagielski            put(col, r + 1, t)
96*0e16a31dSJim Jagielski
97*0e16a31dSJim Jagielski    def block(col, names, gen):
98*0e16a31dSJim Jagielski        for j, n in enumerate(names):
99*0e16a31dSJim Jagielski            put(col + j, 0, n)
100*0e16a31dSJim Jagielski            for r in range(6):
101*0e16a31dSJim Jagielski                put(col + j, r + 1, gen(j, r))
102*0e16a31dSJim Jagielski
103*0e16a31dSJim Jagielski    cats(0)
104*0e16a31dSJim Jagielski    block(1, ["north", "south", "east", "west"], lambda j, r: 3 + ((r * (j + 2) * 5 + j * 3) % 9))
105*0e16a31dSJim Jagielski    block(6, ["x", "y1", "y2"], lambda j, r: (r + 1) * 1.5 if j == 0 else (r + 1) * (j + 1) + (r % 3))
106*0e16a31dSJim Jagielski    block(10, ["bx", "by", "size"], lambda j, r: (r + 1) if j == 0 else ((r * 3 + 2) % 7 + 1 if j == 1 else 2 + (r * 5) % 6))
107*0e16a31dSJim Jagielski    cats(15)
108*0e16a31dSJim Jagielski    for j, n in enumerate(["open", "low", "high", "close"]):
109*0e16a31dSJim Jagielski        put(16 + j, 0, n)
110*0e16a31dSJim Jagielski    for r in range(6):
111*0e16a31dSJim Jagielski        o = 20 + (r * 3) % 5
112*0e16a31dSJim Jagielski        lo, hi = o - 3 - r % 2, o + 4 + r % 3
113*0e16a31dSJim Jagielski        cl = o + (2 if r % 2 else -1)
114*0e16a31dSJim Jagielski        for j, v in enumerate([o, lo, hi, cl]):
115*0e16a31dSJim Jagielski            put(16 + j, r + 1, v)
116*0e16a31dSJim Jagielski    cats(21)
117*0e16a31dSJim Jagielski    for j, n in enumerate(["volume", "open", "low", "high", "close"]):
118*0e16a31dSJim Jagielski        put(22 + j, 0, n)
119*0e16a31dSJim Jagielski    for r in range(6):
120*0e16a31dSJim Jagielski        o = 20 + (r * 3) % 5
121*0e16a31dSJim Jagielski        lo, hi = o - 3 - r % 2, o + 4 + r % 3
122*0e16a31dSJim Jagielski        cl = o + (2 if r % 2 else -1)
123*0e16a31dSJim Jagielski        for j, v in enumerate([100 + 30 * r, o, lo, hi, cl]):
124*0e16a31dSJim Jagielski            put(22 + j, r + 1, v)
125*0e16a31dSJim Jagielski    cats(46)
126*0e16a31dSJim Jagielski    for j, n in enumerate(["volume", "low", "high", "close"]):
127*0e16a31dSJim Jagielski        put(47 + j, 0, n)
128*0e16a31dSJim Jagielski    for r in range(6):
129*0e16a31dSJim Jagielski        o = 20 + (r * 3) % 5
130*0e16a31dSJim Jagielski        for j, v in enumerate([100 + 30 * r, o - 3, o + 4, o + 1 + r % 2]):
131*0e16a31dSJim Jagielski            put(47 + j, r + 1, v)
132*0e16a31dSJim Jagielski    cats(28)
133*0e16a31dSJim Jagielski    for j, n in enumerate(["low", "high", "close"]):
134*0e16a31dSJim Jagielski        put(29 + j, 0, n)
135*0e16a31dSJim Jagielski    for r in range(6):
136*0e16a31dSJim Jagielski        o = 20 + (r * 3) % 5
137*0e16a31dSJim Jagielski        for j, v in enumerate([o - 3, o + 4, o + 1 + r % 2]):
138*0e16a31dSJim Jagielski            put(29 + j, r + 1, v)
139*0e16a31dSJim Jagielski    put(33, 0, "date")
140*0e16a31dSJim Jagielski    for j, n in enumerate(["d1", "d2"]):
141*0e16a31dSJim Jagielski        put(34 + j, 0, n)
142*0e16a31dSJim Jagielski    for r in range(6):
143*0e16a31dSJim Jagielski        c = sh.getCellByPosition(33, r + 1)
144*0e16a31dSJim Jagielski        c.Value = 40000 + (0, 1, 3, 4, 9, 15)[r]
145*0e16a31dSJim Jagielski        put(34, r + 1, 5 + (r * 3) % 7)
146*0e16a31dSJim Jagielski        put(35, r + 1, 9 - (r * 2) % 5)
147*0e16a31dSJim Jagielski    sh.getCellRangeByName("AH2:AH7").NumberFormat = date_format(sh)
148*0e16a31dSJim Jagielski    put(37, 0, "gaps")
149*0e16a31dSJim Jagielski    for j, n in enumerate(["g1", "g2"]):
150*0e16a31dSJim Jagielski        put(38 + j, 0, n)
151*0e16a31dSJim Jagielski    for r in range(6):
152*0e16a31dSJim Jagielski        put(37, r + 1, CATS[r])
153*0e16a31dSJim Jagielski        if r != 2:
154*0e16a31dSJim Jagielski            put(38, r + 1, 4 + r)
155*0e16a31dSJim Jagielski        if r != 4:
156*0e16a31dSJim Jagielski            put(39, r + 1, 9 - r)
157*0e16a31dSJim Jagielski    put(41, 0, "err")
158*0e16a31dSJim Jagielski    for j, n in enumerate(["e1", "ep", "en"]):
159*0e16a31dSJim Jagielski        put(42 + j, 0, n)
160*0e16a31dSJim Jagielski    for r in range(6):
161*0e16a31dSJim Jagielski        put(41, r + 1, CATS[r])
162*0e16a31dSJim Jagielski        put(42, r + 1, 6 + (r * 4) % 7)
163*0e16a31dSJim Jagielski        put(43, r + 1, 0.5 + r * 0.25)
164*0e16a31dSJim Jagielski        put(44, r + 1, 0.3 + r * 0.1)
165*0e16a31dSJim Jagielski
166*0e16a31dSJim Jagielski
167*0e16a31dSJim Jagielskidef date_format(sh):
168*0e16a31dSJim Jagielski    fm = CURRENT[0].NumberFormats
169*0e16a31dSJim Jagielski    loc = uno.createUnoStruct("com.sun.star.lang.Locale", "en", "US", "")
170*0e16a31dSJim Jagielski    k = fm.queryKey("YYYY-MM-DD", loc, False)
171*0e16a31dSJim Jagielski    return fm.addNew("YYYY-MM-DD", loc) if k == -1 else k
172*0e16a31dSJim Jagielski
173*0e16a31dSJim Jagielski
174*0e16a31dSJim JagielskiCURRENT = [None]
175*0e16a31dSJim JagielskiCHART_CLSID = "12dcae26-281f-416f-a234-c3086127382e"
176*0e16a31dSJim Jagielski
177*0e16a31dSJim Jagielski
178*0e16a31dSJim Jagielskidef set_data(ch, data):
179*0e16a31dSJim Jagielski    d = ch.getData()
180*0e16a31dSJim Jagielski    d.setData(tuple(tuple(float(v) for v in row) for row in data["rows"]))
181*0e16a31dSJim Jagielski    d.setRowDescriptions(tuple(data["cats"]))
182*0e16a31dSJim Jagielski    d.setColumnDescriptions(tuple(data["names"]))
183*0e16a31dSJim JagielskiRANGES = {
184*0e16a31dSJim Jagielski    "cat": "Sheet1.A1:E7", "cat1": "Sheet1.A1:B7", "cat2": "Sheet1.A1:C7", "xy": "Sheet1.G1:I7",
185*0e16a31dSJim Jagielski    "bub": "Sheet1.K1:M7", "olhc": "Sheet1.P1:T7", "vol": "Sheet1.V1:AA7", "lhc": "Sheet1.AC1:AF7",
186*0e16a31dSJim Jagielski    "vlhc": "Sheet1.AU1:AY7", "date": "Sheet1.AH1:AJ7", "gap": "Sheet1.AL1:AN7", "err": "Sheet1.AP1:AS7",
187*0e16a31dSJim Jagielski}
188*0e16a31dSJim Jagielski
189*0e16a31dSJim Jagielski
190*0e16a31dSJim Jagielskidef a1(sh, ref):
191*0e16a31dSJim Jagielski    return sh.getCellRangeByName(ref.split(".", 1)[1]).RangeAddress
192*0e16a31dSJim Jagielski
193*0e16a31dSJim Jagielski
194*0e16a31dSJim Jagielskiclass Host:
195*0e16a31dSJim Jagielski    def __init__(self, name, kind="ods"):
196*0e16a31dSJim Jagielski        self.name, self.kind, self.n = name, kind, 0
197*0e16a31dSJim Jagielski        self.doc = new({"ods": "private:factory/scalc", "odt": "private:factory/swriter",
198*0e16a31dSJim Jagielski                        "odp": "private:factory/simpress", "odg": "private:factory/sdraw"}[kind])
199*0e16a31dSJim Jagielski        CURRENT[0] = self.doc
200*0e16a31dSJim Jagielski        if kind == "ods":
201*0e16a31dSJim Jagielski            self.sh = self.doc.Sheets.getByIndex(0)
202*0e16a31dSJim Jagielski            fill_data(self.sh)
203*0e16a31dSJim Jagielski
204*0e16a31dSJim Jagielski    def chart(self, cname, rng, tpl=None, cfg=None, rows=False, cats=True, labels=True, data=None):
205*0e16a31dSJim Jagielski        i = self.n
206*0e16a31dSJim Jagielski        self.n += 1
207*0e16a31dSJim Jagielski        label = "%s/%s" % (self.name, cname)
208*0e16a31dSJim Jagielski        if self.kind == "ods":
209*0e16a31dSJim Jagielski            rect = Rectangle(500 + (i % 3) * 9500, 8000 + (i // 3) * 7200, 9000, 6800)
210*0e16a31dSJim Jagielski            self.sh.Charts.addNewByName(cname, rect, (a1(self.sh, RANGES[rng]),), cats, labels)
211*0e16a31dSJim Jagielski            ch = self.sh.Charts.getByName(cname).EmbeddedObject
212*0e16a31dSJim Jagielski            if tpl:
213*0e16a31dSJim Jagielski                dp = ch.getDataProvider()
214*0e16a31dSJim Jagielski                args = (pv("CellRangeRepresentation", RANGES[rng]), pv("DataRowSource", ROWS if rows else COLUMNS),
215*0e16a31dSJim Jagielski                        pv("FirstCellAsLabel", labels), pv("HasCategories", cats))
216*0e16a31dSJim Jagielski                t = ch.ChartTypeManager.createInstance(TPL + tpl)
217*0e16a31dSJim Jagielski                dia = t.createDiagramByDataSource(dp.createDataSource(args), args)
218*0e16a31dSJim Jagielski                ch.setFirstDiagram(dia)
219*0e16a31dSJim Jagielski        else:
220*0e16a31dSJim Jagielski            ch = self.embed(cname, i)
221*0e16a31dSJim Jagielski            if data:
222*0e16a31dSJim Jagielski                set_data(ch, data)
223*0e16a31dSJim Jagielski            if tpl:
224*0e16a31dSJim Jagielski                t = ch.ChartTypeManager.createInstance(TPL + tpl)
225*0e16a31dSJim Jagielski                t.changeDiagram(ch.getFirstDiagram())
226*0e16a31dSJim Jagielski        if cfg:
227*0e16a31dSJim Jagielski            cfg(ch)
228*0e16a31dSJim Jagielski        return ch
229*0e16a31dSJim Jagielski
230*0e16a31dSJim Jagielski    def embed(self, cname, i):
231*0e16a31dSJim Jagielski        if self.kind == "odt":
232*0e16a31dSJim Jagielski            shape = self.doc.createInstance("com.sun.star.text.TextEmbeddedObject")
233*0e16a31dSJim Jagielski            shape.CLSID = CHART_CLSID
234*0e16a31dSJim Jagielski            shape.Name = cname
235*0e16a31dSJim Jagielski            self.doc.Text.insertTextContent(self.doc.Text.getEnd(), shape, False)
236*0e16a31dSJim Jagielski            return shape.getEmbeddedObject()
237*0e16a31dSJim Jagielski        shape = self.doc.createInstance("com.sun.star.drawing.OLE2Shape")
238*0e16a31dSJim Jagielski        shape.CLSID = CHART_CLSID
239*0e16a31dSJim Jagielski        shape.Position = Point(500 + (i % 2) * 11000, 500 + (i // 2) * 8000)
240*0e16a31dSJim Jagielski        shape.Size = Size(10000, 7000)
241*0e16a31dSJim Jagielski        page = self.doc.DrawPages.getByIndex(0)
242*0e16a31dSJim Jagielski        page.add(shape)
243*0e16a31dSJim Jagielski        return shape.Model
244*0e16a31dSJim Jagielski
245*0e16a31dSJim Jagielski    def done(self):
246*0e16a31dSJim Jagielski        save(self.doc, "%s.%s" % (self.name, self.kind))
247*0e16a31dSJim Jagielski        self.doc.close(True)
248*0e16a31dSJim Jagielski
249*0e16a31dSJim Jagielski
250*0e16a31dSJim Jagielskidef series_of(ch):
251*0e16a31dSJim Jagielski    res = []
252*0e16a31dSJim Jagielski    for cs in ch.getFirstDiagram().getCoordinateSystems():
253*0e16a31dSJim Jagielski        for ct in cs.getChartTypes():
254*0e16a31dSJim Jagielski            res.extend(ct.getDataSeries())
255*0e16a31dSJim Jagielski    return res
256*0e16a31dSJim Jagielski
257*0e16a31dSJim Jagielski
258*0e16a31dSJim Jagielskidef title(text, sub=None):
259*0e16a31dSJim Jagielski    def f(ch):
260*0e16a31dSJim Jagielski        ch.HasMainTitle = True
261*0e16a31dSJim Jagielski        ch.Title.String = text
262*0e16a31dSJim Jagielski        if sub:
263*0e16a31dSJim Jagielski            ch.HasSubTitle = True
264*0e16a31dSJim Jagielski            ch.SubTitle.String = sub
265*0e16a31dSJim Jagielski    return f
266*0e16a31dSJim Jagielski
267*0e16a31dSJim Jagielski
268*0e16a31dSJim Jagielskidef combine(*fs):
269*0e16a31dSJim Jagielski    def f(ch):
270*0e16a31dSJim Jagielski        for g in fs:
271*0e16a31dSJim Jagielski            if g:
272*0e16a31dSJim Jagielski                attempt("cfg " + getattr(g, "__name__", "?"), g, ch)
273*0e16a31dSJim Jagielski    return f
274*0e16a31dSJim Jagielski
275*0e16a31dSJim Jagielski
276*0e16a31dSJim Jagielskidef legacy(**kw):
277*0e16a31dSJim Jagielski    def f(ch):
278*0e16a31dSJim Jagielski        setp(ch.getDiagram(), "diagram", **kw)
279*0e16a31dSJim Jagielski    return f
280*0e16a31dSJim Jagielski
281*0e16a31dSJim Jagielski
282*0e16a31dSJim Jagielskidef axis(which, **kw):
283*0e16a31dSJim Jagielski    def f(ch):
284*0e16a31dSJim Jagielski        d = ch.getDiagram()
285*0e16a31dSJim Jagielski        setp(getattr(d, which), which, **kw)
286*0e16a31dSJim Jagielski    return f
287*0e16a31dSJim Jagielski
288*0e16a31dSJim Jagielski
289*0e16a31dSJim Jagielskidef sprops(idx=None, **kw):
290*0e16a31dSJim Jagielski    def f(ch):
291*0e16a31dSJim Jagielski        for i, s in enumerate(series_of(ch)):
292*0e16a31dSJim Jagielski            if idx is None or i == idx:
293*0e16a31dSJim Jagielski                setp(s, "series%d" % i, **kw)
294*0e16a31dSJim Jagielski    return f
295*0e16a31dSJim Jagielski
296*0e16a31dSJim Jagielski
297*0e16a31dSJim Jagielskidef types_doc(name, rng, names, extra=None, kind="ods", data=None):
298*0e16a31dSJim Jagielski    h = Host(name, kind)
299*0e16a31dSJim Jagielski    for n in names:
300*0e16a31dSJim Jagielski        attempt("%s/%s" % (name, n), h.chart, n, rng, n, combine(title(n), extra), False, True, True, data)
301*0e16a31dSJim Jagielski    h.done()
302*0e16a31dSJim Jagielski
303*0e16a31dSJim Jagielski
304*0e16a31dSJim Jagielskidef topic_types():
305*0e16a31dSJim Jagielski    types_doc("types-column", "cat", ["Column", "StackedColumn", "PercentStackedColumn", "Bar", "StackedBar",
306*0e16a31dSJim Jagielski              "PercentStackedBar", "ThreeDColumnDeep", "ThreeDColumnFlat", "StackedThreeDColumnFlat",
307*0e16a31dSJim Jagielski              "PercentStackedThreeDColumnFlat", "ThreeDBarDeep", "ThreeDBarFlat", "StackedThreeDBarFlat",
308*0e16a31dSJim Jagielski              "PercentStackedThreeDBarFlat", "ColumnWithLine", "StackedColumnWithLine"])
309*0e16a31dSJim Jagielski    types_doc("types-line", "cat", ["Symbol", "StackedSymbol", "PercentStackedSymbol", "Line", "StackedLine",
310*0e16a31dSJim Jagielski              "PercentStackedLine", "LineSymbol", "StackedLineSymbol", "PercentStackedLineSymbol", "ThreeDLine",
311*0e16a31dSJim Jagielski              "StackedThreeDLine", "PercentStackedThreeDLine", "ThreeDLineDeep"])
312*0e16a31dSJim Jagielski    types_doc("types-area", "cat", ["Area", "StackedArea", "PercentStackedArea", "ThreeDArea", "StackedThreeDArea",
313*0e16a31dSJim Jagielski              "PercentStackedThreeDArea"])
314*0e16a31dSJim Jagielski    types_doc("types-net", "cat", ["Net", "NetSymbol", "NetLine", "StackedNet", "StackedNetSymbol", "StackedNetLine",
315*0e16a31dSJim Jagielski              "PercentStackedNet", "PercentStackedNetSymbol", "PercentStackedNetLine", "FilledNet",
316*0e16a31dSJim Jagielski              "StackedFilledNet", "PercentStackedFilledNet"])
317*0e16a31dSJim Jagielski    types_doc("types-pie", "cat1", ["Pie", "PieAllExploded", "Donut", "DonutAllExploded", "ThreeDPie",
318*0e16a31dSJim Jagielski              "ThreeDPieAllExploded", "ThreeDDonut", "ThreeDDonutAllExploded"])
319*0e16a31dSJim Jagielski    h = Host("types-xy")
320*0e16a31dSJim Jagielski    for n in ["ScatterLineSymbol", "ScatterLine", "ScatterSymbol", "ThreeDScatter"]:
321*0e16a31dSJim Jagielski        attempt("types-xy/" + n, h.chart, n, "xy", n, title(n))
322*0e16a31dSJim Jagielski    attempt("types-xy/Bubble", h.chart, "Bubble", "bub", "Bubble", title("Bubble"))
323*0e16a31dSJim Jagielski    h.done()
324*0e16a31dSJim Jagielski    h = Host("types-stock")
325*0e16a31dSJim Jagielski    attempt("stock/lhc", h.chart, "lhc", "lhc", "StockLowHighClose", title("lhc"))
326*0e16a31dSJim Jagielski    attempt("stock/olhc", h.chart, "olhc", "olhc", "StockOpenLowHighClose", title("olhc"))
327*0e16a31dSJim Jagielski    attempt("stock/vlhc", h.chart, "vlhc", "vlhc", "StockVolumeLowHighClose", title("vlhc"))
328*0e16a31dSJim Jagielski    attempt("stock/volhc", h.chart, "volhc", "vol", "StockVolumeOpenLowHighClose", title("volhc"))
329*0e16a31dSJim Jagielski    h.done()
330*0e16a31dSJim Jagielski
331*0e16a31dSJim Jagielski
332*0e16a31dSJim Jagielskidef topic_stock():
333*0e16a31dSJim Jagielski    def markers(ch):
334*0e16a31dSJim Jagielski        d = ch.getDiagram()
335*0e16a31dSJim Jagielski        setp(d.getUpBar(), "upbar", FillColor=0x00ff00, LineColor=0x006600, LineWidth=30, FillStyle=enum("com.sun.star.drawing.FillStyle", "SOLID"))
336*0e16a31dSJim Jagielski        setp(d.getDownBar(), "downbar", FillColor=0xff0000, LineColor=0x660000, LineStyle=enum("com.sun.star.drawing.LineStyle", "DASH"))
337*0e16a31dSJim Jagielski        setp(d.getMinMaxLine(), "minmax", LineColor=0x0000ff, LineWidth=50)
338*0e16a31dSJim Jagielski    h = Host("stock-variants")
339*0e16a31dSJim Jagielski    attempt("stock/markers", h.chart, "m1", "olhc", "StockOpenLowHighClose", combine(title("markers"), markers))
340*0e16a31dSJim Jagielski    attempt("stock/lhc-style", h.chart, "m2", "lhc", "StockLowHighClose", combine(title("lhc styled"), markers))
341*0e16a31dSJim Jagielski    attempt("stock/vol-style", h.chart, "m3", "vol", "StockVolumeOpenLowHighClose", combine(title("vol styled"), markers))
342*0e16a31dSJim Jagielski    attempt("stock/vol2", h.chart, "m4", "vlhc", "StockVolumeLowHighClose", combine(title("vlhc styled"), markers, axis("YAxis", Logarithmic=True)))
343*0e16a31dSJim Jagielski    attempt("stock/updown-off", h.chart, "m5", "olhc", "StockOpenLowHighClose", combine(title("updown off"), legacy(UpDown=False)))
344*0e16a31dSJim Jagielski    h.done()
345*0e16a31dSJim Jagielski
346*0e16a31dSJim Jagielski
347*0e16a31dSJim Jagielskidef topic_threed():
348*0e16a31dSJim Jagielski    PM = "com.sun.star.drawing.ProjectionMode"
349*0e16a31dSJim Jagielski    SM = "com.sun.star.drawing.ShadeMode"
350*0e16a31dSJim Jagielski    h = Host("three-d")
351*0e16a31dSJim Jagielski    cases = [
352*0e16a31dSJim Jagielski        ("flat", dict(D3DSceneShadeMode=enum(SM, "FLAT"), D3DScenePerspective=enum(PM, "PARALLEL"))),
353*0e16a31dSJim Jagielski        ("phong", dict(D3DSceneShadeMode=enum(SM, "PHONG"), D3DSceneTwoSidedLighting=True)),
354*0e16a31dSJim Jagielski        ("smooth", dict(D3DSceneShadeMode=enum(SM, "SMOOTH"), D3DSceneTwoSidedLighting=False)),
355*0e16a31dSJim Jagielski        ("draft", dict(D3DSceneShadeMode=enum(SM, "DRAFT"), D3DSceneTwoSidedLighting=True)),
356*0e16a31dSJim Jagielski        ("rot", dict(RightAngledAxes=False, RotationHorizontal=30, RotationVertical=-20, Perspective=40)),
357*0e16a31dSJim Jagielski        ("rot2", dict(RightAngledAxes=True, RotationHorizontal=-45, RotationVertical=10, Perspective=80)),
358*0e16a31dSJim Jagielski    ]
359*0e16a31dSJim Jagielski    for n, kw in cases:
360*0e16a31dSJim Jagielski        attempt("3d/" + n, h.chart, n, "cat", "ThreeDColumnDeep", combine(title("3d " + n), legacy(**kw)))
361*0e16a31dSJim Jagielski    attempt("3d/lights", h.chart, "lights", "cat", "ThreeDColumnFlat", combine(title("lights"), legacy(
362*0e16a31dSJim Jagielski        D3DSceneAmbientColor=0x404040, D3DSceneLightOn1=True, D3DSceneLightColor1=0xffffff, D3DSceneLightOn2=True,
363*0e16a31dSJim Jagielski        D3DSceneLightColor2=0xff0000, D3DSceneLightOn3=True, D3DSceneLightColor3=0x00ff00, D3DSceneLightOn4=True,
364*0e16a31dSJim Jagielski        D3DSceneLightColor4=0x0000ff)))
365*0e16a31dSJim Jagielski    h.done()
366*0e16a31dSJim Jagielski    h = Host("solid-types")
367*0e16a31dSJim Jagielski    for n, v in (("cylinder", 0), ("cone", 1), ("cuboid", 2), ("pyramid", 3)):
368*0e16a31dSJim Jagielski        attempt("solid/" + n, h.chart, n, "cat", "ThreeDColumnDeep", combine(title(n), legacy(SolidType=v)))
369*0e16a31dSJim Jagielski        attempt("solid/bar-" + n, h.chart, "b" + n, "cat", "ThreeDBarDeep", combine(title("bar " + n), legacy(SolidType=v)))
370*0e16a31dSJim Jagielski    attempt("solid/flat-cone", h.chart, "flatcone", "cat", "ThreeDColumnFlat", combine(title("flat cone"), legacy(SolidType=1)))
371*0e16a31dSJim Jagielski    attempt("solid/stacked-cyl", h.chart, "stcyl", "cat", "StackedThreeDColumnFlat", combine(title("stacked cyl"), legacy(SolidType=0)))
372*0e16a31dSJim Jagielski    h.done()
373*0e16a31dSJim Jagielski
374*0e16a31dSJim Jagielski
375*0e16a31dSJim Jagielskidef topic_pie():
376*0e16a31dSJim Jagielski    h = Host("pie-variants")
377*0e16a31dSJim Jagielski    attempt("pie/offset", h.chart, "off", "cat1", "Pie", combine(title("offset"), sprops(0, Offset=0.3)))
378*0e16a31dSJim Jagielski    attempt("pie/angle", h.chart, "ang", "cat1", "Pie", combine(title("angle"), legacy(StartingAngle=90)))
379*0e16a31dSJim Jagielski    attempt("pie/donut-angle", h.chart, "dang", "cat1", "Donut", combine(title("donut angle"), legacy(StartingAngle=270)))
380*0e16a31dSJim Jagielski    attempt("pie/2series-donut", h.chart, "d2", "cat", "Donut", title("two rings"))
381*0e16a31dSJim Jagielski
382*0e16a31dSJim Jagielski    def pt(ch):
383*0e16a31dSJim Jagielski        s = series_of(ch)[0]
384*0e16a31dSJim Jagielski        for i in range(3):
385*0e16a31dSJim Jagielski            p = s.getDataPointByIndex(i)
386*0e16a31dSJim Jagielski            setp(p, "pt%d" % i, Offset=0.1 * (i + 1), Color=0x336699 + i * 0x2000)
387*0e16a31dSJim Jagielski    attempt("pie/point-offset", h.chart, "ptoff", "cat1", "Pie", combine(title("point offset"), pt))
388*0e16a31dSJim Jagielski    h.done()
389*0e16a31dSJim Jagielski
390*0e16a31dSJim Jagielski
391*0e16a31dSJim JagielskiAX = "com.sun.star.chart.ChartAxis"
392*0e16a31dSJim Jagielski
393*0e16a31dSJim Jagielski
394*0e16a31dSJim Jagielskidef axis_titles(ch):
395*0e16a31dSJim Jagielski    d = ch.getDiagram()
396*0e16a31dSJim Jagielski    for flag, getter, text in (("HasXAxisTitle", d.getXAxisTitle, "x title"), ("HasYAxisTitle", d.getYAxisTitle, "y title")):
397*0e16a31dSJim Jagielski        setp(d, "diagram", **{flag: True})
398*0e16a31dSJim Jagielski        getter().String = text
399*0e16a31dSJim Jagielski
400*0e16a31dSJim Jagielski
401*0e16a31dSJim Jagielskidef topic_axes():
402*0e16a31dSJim Jagielski    CP = "com.sun.star.chart.ChartAxisPosition"
403*0e16a31dSJim Jagielski    LP = "com.sun.star.chart.ChartAxisLabelPosition"
404*0e16a31dSJim Jagielski    MP = "com.sun.star.chart.ChartAxisMarkPosition"
405*0e16a31dSJim Jagielski    AO = "com.sun.star.chart.ChartAxisArrangeOrderType"
406*0e16a31dSJim Jagielski    h = Host("axes")
407*0e16a31dSJim Jagielski    A = lambda n, rng, tpl, *fs: attempt("axes/" + n, h.chart, n, rng, tpl, combine(title(n), *fs))
408*0e16a31dSJim Jagielski    A("scale", "cat", "Column", axis("YAxis", Min=1.0, Max=14.0, StepMain=2.0, StepHelpCount=4, Origin=1.0,
409*0e16a31dSJim Jagielski                                       Marks=3, HelpMarks=3))
410*0e16a31dSJim Jagielski    A("marks-none", "cat", "Column", axis("YAxis", Marks=0, HelpMarks=0), axis("XAxis", Marks=1, HelpMarks=2))
411*0e16a31dSJim Jagielski    A("marks-in", "cat", "Column", axis("YAxis", Marks=1, HelpMarks=1), axis("XAxis", Marks=2, HelpMarks=0))
412*0e16a31dSJim Jagielski    A("log", "cat", "Line", axis("YAxis", Logarithmic=True))
413*0e16a31dSJim Jagielski    A("reverse", "cat", "Column", axis("YAxis", ReverseDirection=True), axis("XAxis", ReverseDirection=True))
414*0e16a31dSJim Jagielski    A("grids", "cat", "Column", legacy(HasXAxisGrid=True, HasXAxisHelpGrid=True, HasYAxisGrid=True, HasYAxisHelpGrid=True))
415*0e16a31dSJim Jagielski    A("nogrid", "cat", "Column", legacy(HasYAxisGrid=False, HasXAxisGrid=False))
416*0e16a31dSJim Jagielski    A("hidden-labels", "cat", "Column", axis("XAxis", DisplayLabels=False), axis("YAxis", DisplayLabels=False))
417*0e16a31dSJim Jagielski    A("hidden-axes", "cat", "Column", legacy(HasXAxis=False, HasYAxis=False))
418*0e16a31dSJim Jagielski    A("titles", "cat", "Column", axis_titles)
419*0e16a31dSJim Jagielski    A("rotation", "cat", "Column", axis("XAxis", TextRotation=4500), axis("YAxis", TextRotation=9000))
420*0e16a31dSJim Jagielski    A("stacked-text", "cat", "Column", axis("XAxis", StackedText=True))
421*0e16a31dSJim Jagielski    A("text-break", "cat", "Column", axis("XAxis", TextBreak=True, TextOverlap=True))
422*0e16a31dSJim Jagielski    A("arrange-odd", "cat", "Column", axis("XAxis", ArrangeOrder=enum(AO, "STAGGER_ODD")))
423*0e16a31dSJim Jagielski    A("arrange-even", "cat", "Column", axis("XAxis", ArrangeOrder=enum(AO, "STAGGER_EVEN")))
424*0e16a31dSJim Jagielski    A("arrange-side", "cat", "Column", axis("XAxis", ArrangeOrder=enum(AO, "SIDE_BY_SIDE")))
425*0e16a31dSJim Jagielski    for p in ("START", "END", "VALUE", "ZERO"):
426*0e16a31dSJim Jagielski        A("cross-" + p, "cat", "Column", axis("XAxis", CrossoverPosition=enum(CP, p), CrossoverValue=3.0),
427*0e16a31dSJim Jagielski          axis("YAxis", CrossoverPosition=enum(CP, p), CrossoverValue=2.0))
428*0e16a31dSJim Jagielski    for p in ("NEAR_AXIS", "NEAR_AXIS_OTHER_SIDE", "OUTSIDE_START", "OUTSIDE_END"):
429*0e16a31dSJim Jagielski        A("labelpos-" + p, "cat", "Column", axis("XAxis", LabelPosition=enum(LP, p)), axis("YAxis", LabelPosition=enum(LP, p)))
430*0e16a31dSJim Jagielski    for p in ("AT_LABELS", "AT_AXIS", "AT_LABELS_AND_AXIS"):
431*0e16a31dSJim Jagielski        A("markpos-" + p, "cat", "Column", axis("XAxis", MarkPosition=enum(MP, p)), axis("YAxis", MarkPosition=enum(MP, p)))
432*0e16a31dSJim Jagielski    A("numfmt-link", "cat", "Column", axis("YAxis", LinkNumberFormatToSource=True))
433*0e16a31dSJim Jagielski    A("numfmt-own", "cat", "Column", axis("YAxis", LinkNumberFormatToSource=False, NumberFormat=1))
434*0e16a31dSJim Jagielski    h.done()
435*0e16a31dSJim Jagielski
436*0e16a31dSJim Jagielski    h = Host("axes2")
437*0e16a31dSJim Jagielski    A = lambda n, rng, tpl, *fs: attempt("axes2/" + n, h.chart, n, rng, tpl, combine(title(n), *fs))
438*0e16a31dSJim Jagielski
439*0e16a31dSJim Jagielski    def second(ch):
440*0e16a31dSJim Jagielski        d = ch.getDiagram()
441*0e16a31dSJim Jagielski        d.HasSecondaryYAxis = True
442*0e16a31dSJim Jagielski        d.HasSecondaryXAxis = True
443*0e16a31dSJim Jagielski        series_of(ch)[1].setPropertyValue("AttachedAxisIndex", 1)
444*0e16a31dSJim Jagielski        series_of(ch)[3].setPropertyValue("AttachedAxisIndex", 1)
445*0e16a31dSJim Jagielski        setp(d.SecondaryYAxis, "sec", Min=0.0, Max=20.0)
446*0e16a31dSJim Jagielski    A("secondary", "cat", "Column", second)
447*0e16a31dSJim Jagielski    A("secondary-line", "cat", "Line", second)
448*0e16a31dSJim Jagielski    A("secondary-bar", "cat", "Bar", second)
449*0e16a31dSJim Jagielski    A("xy-axes", "xy", "ScatterLineSymbol", axis("XAxis", Min=0.0, Max=10.0, StepMain=2.0, Logarithmic=False),
450*0e16a31dSJim Jagielski      axis("YAxis", Min=0.0, Max=30.0, StepMain=5.0))
451*0e16a31dSJim Jagielski    A("xy-log", "xy", "ScatterSymbol", axis("XAxis", Logarithmic=True), axis("YAxis", Logarithmic=True))
452*0e16a31dSJim Jagielski    A("zaxis", "cat", "ThreeDColumnDeep", axis("ZAxis", DisplayLabels=True, Marks=3))
453*0e16a31dSJim Jagielski    A("zaxis-title", "cat", "ThreeDColumnDeep", legacy(HasZAxisTitle=True, HasZAxisGrid=True, HasZAxisHelpGrid=True))
454*0e16a31dSJim Jagielski    A("net-axes", "cat", "Net", axis("YAxis", Min=0.0, Max=12.0, StepMain=3.0))
455*0e16a31dSJim Jagielski    A("hidden-cat", "cat", "Column", legacy(HasXAxis=False))
456*0e16a31dSJim Jagielski
457*0e16a31dSJim Jagielski    def dates(ch):
458*0e16a31dSJim Jagielski        ax = ch.getFirstDiagram().getCoordinateSystems()[0].getAxisByDimension(0, 0)
459*0e16a31dSJim Jagielski        sd = ax.getScaleData()
460*0e16a31dSJim Jagielski        sd.AxisType = const("com.sun.star.chart2.AxisType.DATE")
461*0e16a31dSJim Jagielski        sd.AutoDateAxis = False
462*0e16a31dSJim Jagielski        ti = uno.createUnoStruct("com.sun.star.chart.TimeIncrement")
463*0e16a31dSJim Jagielski        ti.TimeResolution = const("com.sun.star.chart.TimeUnit.DAY")
464*0e16a31dSJim Jagielski        ti.MajorTimeInterval = uno.createUnoStruct("com.sun.star.chart.TimeInterval", 2, const("com.sun.star.chart.TimeUnit.DAY"))
465*0e16a31dSJim Jagielski        ti.MinorTimeInterval = uno.createUnoStruct("com.sun.star.chart.TimeInterval", 1, const("com.sun.star.chart.TimeUnit.DAY"))
466*0e16a31dSJim Jagielski        sd.TimeIncrement = ti
467*0e16a31dSJim Jagielski        ax.setScaleData(sd)
468*0e16a31dSJim Jagielski
469*0e16a31dSJim Jagielski    def dates_month(ch):
470*0e16a31dSJim Jagielski        ax = ch.getFirstDiagram().getCoordinateSystems()[0].getAxisByDimension(0, 0)
471*0e16a31dSJim Jagielski        sd = ax.getScaleData()
472*0e16a31dSJim Jagielski        sd.AxisType = const("com.sun.star.chart2.AxisType.DATE")
473*0e16a31dSJim Jagielski        sd.AutoDateAxis = True
474*0e16a31dSJim Jagielski        ti = uno.createUnoStruct("com.sun.star.chart.TimeIncrement")
475*0e16a31dSJim Jagielski        ti.TimeResolution = const("com.sun.star.chart.TimeUnit.MONTH")
476*0e16a31dSJim Jagielski        ti.MajorTimeInterval = uno.createUnoStruct("com.sun.star.chart.TimeInterval", 1, const("com.sun.star.chart.TimeUnit.YEAR"))
477*0e16a31dSJim Jagielski        ti.MinorTimeInterval = uno.createUnoStruct("com.sun.star.chart.TimeInterval", 3, const("com.sun.star.chart.TimeUnit.MONTH"))
478*0e16a31dSJim Jagielski        sd.TimeIncrement = ti
479*0e16a31dSJim Jagielski        ax.setScaleData(sd)
480*0e16a31dSJim Jagielski
481*0e16a31dSJim Jagielski    def real_axis(ch):
482*0e16a31dSJim Jagielski        ax = ch.getFirstDiagram().getCoordinateSystems()[0].getAxisByDimension(0, 0)
483*0e16a31dSJim Jagielski        sd = ax.getScaleData()
484*0e16a31dSJim Jagielski        sd.AxisType = const("com.sun.star.chart2.AxisType.REALNUMBER")
485*0e16a31dSJim Jagielski        ax.setScaleData(sd)
486*0e16a31dSJim Jagielski    A("date-day", "date", "Line", dates)
487*0e16a31dSJim Jagielski    A("date-month", "date", "LineSymbol", dates_month)
488*0e16a31dSJim Jagielski    A("date-col", "date", "Column", dates)
489*0e16a31dSJim Jagielski    A("date-auto", "date", "Line")
490*0e16a31dSJim Jagielski    A("xy-date", "date", "ScatterLineSymbol", dates)
491*0e16a31dSJim Jagielski    A("cat-as-real", "cat", "Line", real_axis)
492*0e16a31dSJim Jagielski    h.done()
493*0e16a31dSJim Jagielski
494*0e16a31dSJim Jagielski
495*0e16a31dSJim Jagielskidef label(num=False, pct=False, cat=False, sym=False):
496*0e16a31dSJim Jagielski    return uno.createUnoStruct("com.sun.star.chart2.DataPointLabel", num, pct, cat, sym)
497*0e16a31dSJim Jagielski
498*0e16a31dSJim Jagielski
499*0e16a31dSJim Jagielskidef topic_labels():
500*0e16a31dSJim Jagielski    h = Host("labels")
501*0e16a31dSJim Jagielski    combos = [("value", label(num=True)), ("pct", label(pct=True)), ("value-pct", label(num=True, pct=True)),
502*0e16a31dSJim Jagielski              ("cat", label(cat=True)), ("sym", label(sym=True)), ("all", label(True, True, True, True)),
503*0e16a31dSJim Jagielski              ("cat-value", label(num=True, cat=True)), ("sym-value", label(num=True, sym=True)),
504*0e16a31dSJim Jagielski              ("pct-cat-sym", label(pct=True, cat=True, sym=True)), ("none", label())]
505*0e16a31dSJim Jagielski    for n, lab in combos:
506*0e16a31dSJim Jagielski        for tpl, rng in (("Column", "cat"), ("Pie", "cat1")):
507*0e16a31dSJim Jagielski            attempt("labels/%s-%s" % (n, tpl), h.chart, n + tpl, rng, tpl, combine(title(n + " " + tpl), sprops(None, Label=lab)))
508*0e16a31dSJim Jagielski    h.done()
509*0e16a31dSJim Jagielski
510*0e16a31dSJim Jagielski    h = Host("label-opts")
511*0e16a31dSJim Jagielski    seps = [" ", "; ", "\n", ", "]
512*0e16a31dSJim Jagielski    for i, sp in enumerate(seps):
513*0e16a31dSJim Jagielski        attempt("labsep/%d" % i, h.chart, "sep%d" % i, "cat", "Column",
514*0e16a31dSJim Jagielski                combine(title("sep %d" % i), sprops(None, Label=label(num=True, cat=True, pct=True), LabelSeparator=sp)))
515*0e16a31dSJim Jagielski    PL = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
516*0e16a31dSJim Jagielski    for k in range(0, len(PL), 4):
517*0e16a31dSJim Jagielski        vals = PL[k:k + 4]
518*0e16a31dSJim Jagielski
519*0e16a31dSJim Jagielski        def f(ch, vals=vals):
520*0e16a31dSJim Jagielski            for i, s in enumerate(series_of(ch)):
521*0e16a31dSJim Jagielski                if i < len(vals):
522*0e16a31dSJim Jagielski                    setp(s, "place", Label=label(num=True), LabelPlacement=vals[i])
523*0e16a31dSJim Jagielski        attempt("labplace/%d" % k, h.chart, "place%d" % k, "cat", "LineSymbol", combine(title("placement %d" % k), f))
524*0e16a31dSJim Jagielski    attempt("labfmt/own", h.chart, "fmt", "cat", "Column", sprops(None, Label=label(num=True, pct=True), NumberFormat=3, PercentageNumberFormat=10))
525*0e16a31dSJim Jagielski    attempt("labrot", h.chart, "rot", "cat", "Column", sprops(None, Label=label(num=True), TextRotation=90.0))
526*0e16a31dSJim Jagielski
527*0e16a31dSJim Jagielski    def pointlabels(ch):
528*0e16a31dSJim Jagielski        s = series_of(ch)[0]
529*0e16a31dSJim Jagielski        for i in range(3):
530*0e16a31dSJim Jagielski            p = ch.getDiagram().getDataPointProperties(i, 0)
531*0e16a31dSJim Jagielski            setp(p, "pt%d" % i, DataCaption=(1, 2, 3)[i])
532*0e16a31dSJim Jagielski    attempt("labpoint", h.chart, "pt", "cat", "Column", combine(title("point labels"), pointlabels))
533*0e16a31dSJim Jagielski    h.done()
534*0e16a31dSJim Jagielski
535*0e16a31dSJim Jagielski
536*0e16a31dSJim Jagielskidef topic_stats():
537*0e16a31dSJim Jagielski    EI = "com.sun.star.chart.ChartErrorIndicatorType"
538*0e16a31dSJim Jagielski    RC = "com.sun.star.chart.ChartRegressionCurveType"
539*0e16a31dSJim Jagielski    h = Host("stats-error")
540*0e16a31dSJim Jagielski    styles = [(1, "variance"), (2, "stddev"), (3, "constant"), (4, "percent"), (5, "margin"), (6, "stderr"), (7, "range")]
541*0e16a31dSJim Jagielski    inds = ["TOP_AND_BOTTOM", "UPPER", "LOWER"]
542*0e16a31dSJim Jagielski    for st, n in styles:
543*0e16a31dSJim Jagielski        for ind in inds:
544*0e16a31dSJim Jagielski            def f(ch, st=st, ind=ind):
545*0e16a31dSJim Jagielski                d = ch.getDiagram()
546*0e16a31dSJim Jagielski                for i in range(2):
547*0e16a31dSJim Jagielski                    p = d.getDataRowProperties(i)
548*0e16a31dSJim Jagielski                    setp(p, "row", ErrorBarStyle=st, ErrorIndicator=enum(EI, ind), ConstantErrorHigh=1.5,
549*0e16a31dSJim Jagielski                         ConstantErrorLow=0.5, PercentageError=12.0, ErrorMargin=8.0)
550*0e16a31dSJim Jagielski                    if st == 7:
551*0e16a31dSJim Jagielski                        setp(p, "range", ErrorBarRangePositive="Sheet1.AR2:AR7", ErrorBarRangeNegative="Sheet1.AS2:AS7")
552*0e16a31dSJim Jagielski            kind = "Column" if ind != "LOWER" else "LineSymbol"
553*0e16a31dSJim Jagielski            attempt("err/%s-%s" % (n, ind), h.chart, "e%d%s" % (st, ind), "cat", kind, combine(title("%s %s" % (n, ind)), f))
554*0e16a31dSJim Jagielski    h.done()
555*0e16a31dSJim Jagielski
556*0e16a31dSJim Jagielski    h = Host("stats-regression")
557*0e16a31dSJim Jagielski    for rc in ("LINEAR", "LOGARITHM", "EXPONENTIAL", "POWER"):
558*0e16a31dSJim Jagielski        def f(ch, rc=rc):
559*0e16a31dSJim Jagielski            d = ch.getDiagram()
560*0e16a31dSJim Jagielski            for i in range(2):
561*0e16a31dSJim Jagielski                setp(d.getDataRowProperties(i), "row", RegressionCurves=enum(RC, rc))
562*0e16a31dSJim Jagielski        attempt("reg/" + rc, h.chart, "r" + rc, "xy", "ScatterSymbol", combine(title(rc), f))
563*0e16a31dSJim Jagielski        attempt("reg/line/" + rc, h.chart, "l" + rc, "cat", "LineSymbol", combine(title("line " + rc), f))
564*0e16a31dSJim Jagielski
565*0e16a31dSJim Jagielski    def equation(ch, rc, show_eq, show_r2, pos):
566*0e16a31dSJim Jagielski        for s in series_of(ch)[:2]:
567*0e16a31dSJim Jagielski            for c in s.getRegressionCurves():
568*0e16a31dSJim Jagielski                e = c.getEquationProperties()
569*0e16a31dSJim Jagielski                setp(e, "eq", ShowEquation=show_eq, ShowCorrelationCoefficient=show_r2,
570*0e16a31dSJim Jagielski                     RelativePosition=uno.createUnoStruct("com.sun.star.chart2.RelativePosition", pos, 0.2,
571*0e16a31dSJim Jagielski                                                           uno.Enum("com.sun.star.drawing.Alignment", "TOP_LEFT")),
572*0e16a31dSJim Jagielski                     NumberFormat=1)
573*0e16a31dSJim Jagielski    for rc in ("LINEAR", "LOGARITHM", "EXPONENTIAL", "POWER"):
574*0e16a31dSJim Jagielski        for sh_eq, sh_r in ((True, False), (False, True), (True, True)):
575*0e16a31dSJim Jagielski            def f(ch, rc=rc, a=sh_eq, b=sh_r):
576*0e16a31dSJim Jagielski                d = ch.getDiagram()
577*0e16a31dSJim Jagielski                for i in range(2):
578*0e16a31dSJim Jagielski                    setp(d.getDataRowProperties(i), "row", RegressionCurves=enum(RC, rc))
579*0e16a31dSJim Jagielski                equation(ch, rc, a, b, 0.3)
580*0e16a31dSJim Jagielski            attempt("eq/%s%s%s" % (rc, sh_eq, sh_r), h.chart, "q%s%d%d" % (rc, sh_eq, sh_r), "xy", "ScatterSymbol",
581*0e16a31dSJim Jagielski                    combine(title("%s eq=%s r2=%s" % (rc, sh_eq, sh_r)), f))
582*0e16a31dSJim Jagielski
583*0e16a31dSJim Jagielski    def curve_style(ch):
584*0e16a31dSJim Jagielski        for s in series_of(ch)[:2]:
585*0e16a31dSJim Jagielski            for c in s.getRegressionCurves():
586*0e16a31dSJim Jagielski                setp(c, "curve", LineColor=0xff0000, LineWidth=60, LineStyle=enum("com.sun.star.drawing.LineStyle", "DASH"))
587*0e16a31dSJim Jagielski        setp(ch.getDiagram().getDataRowProperties(0), "row", RegressionCurves=enum(RC, "LINEAR"))
588*0e16a31dSJim Jagielski    attempt("reg/style", h.chart, "style", "xy", "ScatterLineSymbol", combine(title("curve style"), curve_style))
589*0e16a31dSJim Jagielski    h.done()
590*0e16a31dSJim Jagielski
591*0e16a31dSJim Jagielski    h = Host("stats-mean")
592*0e16a31dSJim Jagielski    for tpl, rng in (("Column", "cat"), ("Line", "cat"), ("ScatterSymbol", "xy"), ("Bar", "cat"), ("Area", "cat")):
593*0e16a31dSJim Jagielski        def f(ch):
594*0e16a31dSJim Jagielski            d = ch.getDiagram()
595*0e16a31dSJim Jagielski            for i in range(2):
596*0e16a31dSJim Jagielski                setp(d.getDataRowProperties(i), "row", MeanValue=True)
597*0e16a31dSJim Jagielski        attempt("mean/" + tpl, h.chart, "m" + tpl, rng, tpl, combine(title("mean " + tpl), f))
598*0e16a31dSJim Jagielski
599*0e16a31dSJim Jagielski    def mean_style(ch):
600*0e16a31dSJim Jagielski        d = ch.getDiagram()
601*0e16a31dSJim Jagielski        for i in range(3):
602*0e16a31dSJim Jagielski            p = d.getDataRowProperties(i)
603*0e16a31dSJim Jagielski            setp(p, "row", MeanValue=True)
604*0e16a31dSJim Jagielski            mp = p.getPropertyValue("DataMeanValueProperties")
605*0e16a31dSJim Jagielski            setp(mp, "mean", LineColor=0x00aa00 + i * 0x1000, LineWidth=40 * (i + 1))
606*0e16a31dSJim Jagielski    attempt("mean/style", h.chart, "mstyle", "cat", "Column", combine(title("mean styled"), mean_style))
607*0e16a31dSJim Jagielski
608*0e16a31dSJim Jagielski    def all_stats(ch):
609*0e16a31dSJim Jagielski        d = ch.getDiagram()
610*0e16a31dSJim Jagielski        p = d.getDataRowProperties(0)
611*0e16a31dSJim Jagielski        setp(p, "row", MeanValue=True, RegressionCurves=enum(RC, "LINEAR"), ErrorBarStyle=3,
612*0e16a31dSJim Jagielski             ErrorIndicator=enum(EI, "TOP_AND_BOTTOM"), ConstantErrorHigh=1.0, ConstantErrorLow=1.0)
613*0e16a31dSJim Jagielski        equation(ch, "LINEAR", True, True, 0.5)
614*0e16a31dSJim Jagielski    attempt("stats/all", h.chart, "all", "xy", "ScatterLineSymbol", combine(title("all stats"), all_stats))
615*0e16a31dSJim Jagielski    h.done()
616*0e16a31dSJim Jagielski
617*0e16a31dSJim Jagielski
618*0e16a31dSJim Jagielskidef chart_types(ch):
619*0e16a31dSJim Jagielski    return [ct for cs in ch.getFirstDiagram().getCoordinateSystems() for ct in cs.getChartTypes()]
620*0e16a31dSJim Jagielski
621*0e16a31dSJim Jagielski
622*0e16a31dSJim Jagielskidef topic_legend():
623*0e16a31dSJim Jagielski    LP = "com.sun.star.chart.ChartLegendPosition"
624*0e16a31dSJim Jagielski    LE = "com.sun.star.chart.ChartLegendExpansion"
625*0e16a31dSJim Jagielski    h = Host("legend")
626*0e16a31dSJim Jagielski    for p in ("LEFT", "TOP", "RIGHT", "BOTTOM", "NONE"):
627*0e16a31dSJim Jagielski        def f(ch, p=p):
628*0e16a31dSJim Jagielski            ch.HasLegend = True
629*0e16a31dSJim Jagielski            setp(ch.Legend, "legend", Alignment=enum(LP, p))
630*0e16a31dSJim Jagielski        attempt("legend/" + p, h.chart, "L" + p, "cat", "Column", combine(title("legend " + p, "sub " + p), f))
631*0e16a31dSJim Jagielski    for e in ("WIDE", "HIGH", "CUSTOM"):
632*0e16a31dSJim Jagielski        def f(ch, e=e):
633*0e16a31dSJim Jagielski            ch.HasLegend = True
634*0e16a31dSJim Jagielski            setp(ch.Legend, "legend", Expansion=enum(LE, e), Alignment=enum(LP, "TOP"))
635*0e16a31dSJim Jagielski            if e == "CUSTOM":
636*0e16a31dSJim Jagielski                ch.Legend.Size = Size(5000, 2500)
637*0e16a31dSJim Jagielski        attempt("legend/exp" + e, h.chart, "E" + e, "cat", "Line", combine(title("expansion " + e), f))
638*0e16a31dSJim Jagielski
639*0e16a31dSJim Jagielski    def nolegend(ch):
640*0e16a31dSJim Jagielski        ch.HasLegend = False
641*0e16a31dSJim Jagielski    attempt("legend/off", h.chart, "off", "cat", "Column", combine(title("no legend"), nolegend))
642*0e16a31dSJim Jagielski
643*0e16a31dSJim Jagielski    def legend_style(ch):
644*0e16a31dSJim Jagielski        ch.HasLegend = True
645*0e16a31dSJim Jagielski        setp(ch.Legend, "legend", FillStyle=enum("com.sun.star.drawing.FillStyle", "SOLID"), FillColor=0xffffcc,
646*0e16a31dSJim Jagielski             LineStyle=enum("com.sun.star.drawing.LineStyle", "SOLID"), LineColor=0x333333, CharHeight=14.0,
647*0e16a31dSJim Jagielski             CharColor=0x990000, CharWeight=150.0, CharPosture=enum("com.sun.star.awt.FontSlant", "ITALIC"))
648*0e16a31dSJim Jagielski    attempt("legend/style", h.chart, "style", "cat", "Column", combine(title("legend style"), legend_style))
649*0e16a31dSJim Jagielski
650*0e16a31dSJim Jagielski    def titles(ch):
651*0e16a31dSJim Jagielski        ch.HasMainTitle = True
652*0e16a31dSJim Jagielski        ch.HasSubTitle = True
653*0e16a31dSJim Jagielski        ch.Title.String = "Main\nTwo lines"
654*0e16a31dSJim Jagielski        ch.SubTitle.String = "Subtitle text"
655*0e16a31dSJim Jagielski        setp(ch.Title, "title", CharHeight=18.0, CharColor=0x0000ff, CharFontName="Arial", CharWeight=150.0,
656*0e16a31dSJim Jagielski             TextRotation=0, CharUnderline=1)
657*0e16a31dSJim Jagielski        setp(ch.SubTitle, "sub", CharHeight=11.0, CharPosture=enum("com.sun.star.awt.FontSlant", "ITALIC"), TextRotation=90)
658*0e16a31dSJim Jagielski        ch.Title.Position = Point(2000, 100)
659*0e16a31dSJim Jagielski        ch.SubTitle.Position = Point(2000, 1200)
660*0e16a31dSJim Jagielski    attempt("legend/titles", h.chart, "titles", "cat", "Column", titles)
661*0e16a31dSJim Jagielski
662*0e16a31dSJim Jagielski    def rotated(ch):
663*0e16a31dSJim Jagielski        ch.HasMainTitle = True
664*0e16a31dSJim Jagielski        ch.Title.String = "rot"
665*0e16a31dSJim Jagielski        setp(ch.Title, "title", TextRotation=45)
666*0e16a31dSJim Jagielski        axis_titles(ch)
667*0e16a31dSJim Jagielski        d = ch.getDiagram()
668*0e16a31dSJim Jagielski        setp(d.getXAxisTitle(), "xt", TextRotation=90)
669*0e16a31dSJim Jagielski        setp(d.getYAxisTitle(), "yt", TextRotation=270)
670*0e16a31dSJim Jagielski    attempt("legend/rot", h.chart, "rot", "cat", "Column", rotated)
671*0e16a31dSJim Jagielski
672*0e16a31dSJim Jagielski    def wall(ch):
673*0e16a31dSJim Jagielski        d = ch.getDiagram()
674*0e16a31dSJim Jagielski        setp(d.getWall(), "wall", FillStyle=enum("com.sun.star.drawing.FillStyle", "SOLID"), FillColor=0xeeeeff,
675*0e16a31dSJim Jagielski             LineStyle=enum("com.sun.star.drawing.LineStyle", "SOLID"), LineColor=0x888888, LineWidth=30)
676*0e16a31dSJim Jagielski        setp(d.getFloor(), "floor", FillStyle=enum("com.sun.star.drawing.FillStyle", "SOLID"), FillColor=0xccffcc)
677*0e16a31dSJim Jagielski        setp(ch.getPageBackground(), "page", FillStyle=enum("com.sun.star.drawing.FillStyle", "SOLID"), FillColor=0xffeeee)
678*0e16a31dSJim Jagielski    attempt("legend/wall", h.chart, "wall", "cat", "Column", combine(title("wall floor"), wall))
679*0e16a31dSJim Jagielski    attempt("legend/wall3d", h.chart, "wall3d", "cat", "ThreeDColumnDeep", combine(title("3d wall floor"), wall))
680*0e16a31dSJim Jagielski    h.done()
681*0e16a31dSJim Jagielski
682*0e16a31dSJim Jagielski
683*0e16a31dSJim Jagielskidef png_file():
684*0e16a31dSJim Jagielski    import zlib, struct, tempfile
685*0e16a31dSJim Jagielski    w = h = 8
686*0e16a31dSJim Jagielski    raw = b"".join(b"\x00" + b"".join(bytes((30 * x, 30 * y, 160)) for x in range(w)) for y in range(h))
687*0e16a31dSJim Jagielski
688*0e16a31dSJim Jagielski    def chunk(t, d):
689*0e16a31dSJim Jagielski        c = struct.pack(">I", len(d)) + t + d
690*0e16a31dSJim Jagielski        return c + struct.pack(">I", zlib.crc32(t + d) & 0xffffffff)
691*0e16a31dSJim Jagielski    data = b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", w, h, 8, 2, 0, 0, 0)) + chunk(b"IDAT", zlib.compress(raw)) + chunk(b"IEND", b"")
692*0e16a31dSJim Jagielski    fd, path = tempfile.mkstemp(suffix=".png")
693*0e16a31dSJim Jagielski    os.write(fd, data)
694*0e16a31dSJim Jagielski    os.close(fd)
695*0e16a31dSJim Jagielski    return path
696*0e16a31dSJim Jagielski
697*0e16a31dSJim Jagielski
698*0e16a31dSJim Jagielskidef topic_symbols():
699*0e16a31dSJim Jagielski    global PNG
700*0e16a31dSJim Jagielski    PNG = png_file()
701*0e16a31dSJim Jagielski    SS = "com.sun.star.chart2.SymbolStyle"
702*0e16a31dSJim Jagielski    h = Host("symbols")
703*0e16a31dSJim Jagielski
704*0e16a31dSJim Jagielski    def sym(style, n=0, size=300, fill=0xff6600, border=0x003366):
705*0e16a31dSJim Jagielski        s = uno.createUnoStruct("com.sun.star.chart2.Symbol")
706*0e16a31dSJim Jagielski        s.Style = enum(SS, style)
707*0e16a31dSJim Jagielski        s.StandardSymbol = n
708*0e16a31dSJim Jagielski        s.Size = Size(size, size)
709*0e16a31dSJim Jagielski        s.FillColor = fill
710*0e16a31dSJim Jagielski        s.BorderColor = border
711*0e16a31dSJim Jagielski        return s
712*0e16a31dSJim Jagielski
713*0e16a31dSJim Jagielski    for k in range(0, 15, 4):
714*0e16a31dSJim Jagielski        def f(ch, k=k):
715*0e16a31dSJim Jagielski            for i, s in enumerate(series_of(ch)):
716*0e16a31dSJim Jagielski                setp(s, "sym", Symbol=sym("STANDARD", k + i if k + i < 15 else 0, 200 + 100 * i))
717*0e16a31dSJim Jagielski        attempt("sym/%d" % k, h.chart, "s%d" % k, "cat", "LineSymbol", combine(title("symbols %d.." % k), f))
718*0e16a31dSJim Jagielski
719*0e16a31dSJim Jagielski    def none_auto(ch):
720*0e16a31dSJim Jagielski        ss = series_of(ch)
721*0e16a31dSJim Jagielski        setp(ss[0], "s", Symbol=sym("NONE"))
722*0e16a31dSJim Jagielski        setp(ss[1], "s", Symbol=sym("AUTO"))
723*0e16a31dSJim Jagielski    attempt("sym/none-auto", h.chart, "na", "cat", "LineSymbol", combine(title("none auto"), none_auto))
724*0e16a31dSJim Jagielski
725*0e16a31dSJim Jagielski    def graphic(ch):
726*0e16a31dSJim Jagielski        gp = ctx.ServiceManager.createInstanceWithContext("com.sun.star.graphic.GraphicProvider", ctx)
727*0e16a31dSJim Jagielski        g = gp.queryGraphic((pv("URL", uno.systemPathToFileUrl(PNG)),))
728*0e16a31dSJim Jagielski        s = sym("GRAPHIC")
729*0e16a31dSJim Jagielski        s.Graphic = g
730*0e16a31dSJim Jagielski        setp(series_of(ch)[0], "s", Symbol=s)
731*0e16a31dSJim Jagielski    attempt("sym/graphic", h.chart, "gr", "cat", "LineSymbol", combine(title("graphic"), graphic))
732*0e16a31dSJim Jagielski    attempt("sym/scatter", h.chart, "sc", "xy", "ScatterSymbol", combine(title("scatter sym"), sprops(0, Symbol=sym("STANDARD", 5, 400))))
733*0e16a31dSJim Jagielski    for n, v in (("none", 0), ("cubic", 1), ("bspline", 2)):
734*0e16a31dSJim Jagielski        def f(ch, v=v):
735*0e16a31dSJim Jagielski            setp(ch.getDiagram(), "d", SplineType=v, SplineOrder=3 + v, SplineResolution=20 + 10 * v)
736*0e16a31dSJim Jagielski        attempt("interp/" + n, h.chart, "i" + n, "cat", "LineSymbol", combine(title("spline " + n), f))
737*0e16a31dSJim Jagielski        attempt("interp/xy-" + n, h.chart, "x" + n, "xy", "ScatterLineSymbol", combine(title("xy spline " + n), f))
738*0e16a31dSJim Jagielski    attempt("sym/lines-off", h.chart, "nolines", "xy", "ScatterSymbol", combine(title("lines off"), legacy(Lines=False)))
739*0e16a31dSJim Jagielski    attempt("sym/lines-on", h.chart, "lines", "cat", "Symbol", combine(title("lines on"), legacy(Lines=True)))
740*0e16a31dSJim Jagielski    h.done()
741*0e16a31dSJim Jagielski
742*0e16a31dSJim Jagielski
743*0e16a31dSJim Jagielskidef topic_data():
744*0e16a31dSJim Jagielski    h = Host("data")
745*0e16a31dSJim Jagielski    A = lambda n, rng, tpl, cats, labels, *fs, rows=False: attempt("data/" + n, h.chart, n, rng, tpl,
746*0e16a31dSJim Jagielski        combine(title(n), *fs), rows, cats, labels)
747*0e16a31dSJim Jagielski    A("no-labels", "cat", "Column", False, False)
748*0e16a31dSJim Jagielski    A("col-labels", "cat", "Column", False, True)
749*0e16a31dSJim Jagielski    A("row-labels", "cat", "Column", True, False)
750*0e16a31dSJim Jagielski    A("both", "cat", "Column", True, True)
751*0e16a31dSJim Jagielski    A("rows", "cat", "Column", True, True, rows=True)
752*0e16a31dSJim Jagielski    A("rows-nolabels", "cat", "Line", False, False, rows=True)
753*0e16a31dSJim Jagielski    for n, v in (("gap", 0), ("zero", 1), ("cont", 2)):
754*0e16a31dSJim Jagielski        A("missing-" + n, "gap", "LineSymbol", True, True, legacy(MissingValueTreatment=v))
755*0e16a31dSJim Jagielski        A("missing-col-" + n, "gap", "Column", True, True, legacy(MissingValueTreatment=v))
756*0e16a31dSJim Jagielski        A("missing-area-" + n, "gap", "Area", True, True, legacy(MissingValueTreatment=v))
757*0e16a31dSJim Jagielski    A("hidden-on", "cat", "Column", True, True, legacy(IncludeHiddenCells=True))
758*0e16a31dSJim Jagielski    A("hidden-off", "cat", "Column", True, True, legacy(IncludeHiddenCells=False))
759*0e16a31dSJim Jagielski    A("sort-x", "xy", "ScatterLineSymbol", True, True, legacy(SortByXValues=True))
760*0e16a31dSJim Jagielski    A("gapwidth", "cat", "Column", True, True, axis("YAxis", GapWidth=150, Overlap=-30))
761*0e16a31dSJim Jagielski    A("gapwidth-bar", "cat", "Bar", True, True, axis("YAxis", GapWidth=20, Overlap=100))
762*0e16a31dSJim Jagielski    A("gapwidth-2axes", "cat", "Column", True, True, lambda ch: [
763*0e16a31dSJim Jagielski        setp(ch.getDiagram(), "d", HasSecondaryYAxis=True), series_of(ch)[1].setPropertyValue("AttachedAxisIndex", 1),
764*0e16a31dSJim Jagielski        setp(ch.getDiagram().SecondaryYAxis, "y2", GapWidth=70, Overlap=20)])
765*0e16a31dSJim Jagielski    A("connect", "cat", "StackedColumn", True, True, legacy(StackedBarsConnected=True))
766*0e16a31dSJim Jagielski    A("connect-bar", "cat", "StackedBar", True, True, legacy(StackedBarsConnected=True))
767*0e16a31dSJim Jagielski
768*0e16a31dSJim Jagielski    def group(ch):
769*0e16a31dSJim Jagielski        d = ch.getDiagram()
770*0e16a31dSJim Jagielski        d.HasSecondaryYAxis = True
771*0e16a31dSJim Jagielski        series_of(ch)[1].setPropertyValue("AttachedAxisIndex", 1)
772*0e16a31dSJim Jagielski        setp(d, "d", GroupBarsPerAxis=False)
773*0e16a31dSJim Jagielski    A("group-bars", "cat", "Column", True, True, group)
774*0e16a31dSJim Jagielski    A("group-bars-on", "cat", "Column", True, True, lambda ch: [setp(ch.getDiagram(), "d", GroupBarsPerAxis=True), group(ch)])
775*0e16a31dSJim Jagielski    A("scale-text", "cat", "Column", True, True, axis("XAxis", ScaleText=True), axis("YAxis", ScaleText=True),
776*0e16a31dSJim Jagielski      lambda ch: setp(ch.Title, "t", ScaleText=True))
777*0e16a31dSJim Jagielski    A("lineseries", "cat", "ColumnWithLine", True, True, legacy(NumberOfLines=2))
778*0e16a31dSJim Jagielski    A("lineseries-stacked", "cat", "StackedColumnWithLine", True, True, legacy(NumberOfLines=3))
779*0e16a31dSJim Jagielski    A("percent-off", "cat", "StackedColumn", True, True, legacy(Percent=False, Stacked=True))
780*0e16a31dSJim Jagielski    A("stack-off", "cat", "Column", True, True, legacy(Stacked=False, Percent=False))
781*0e16a31dSJim Jagielski    A("vertical-on", "cat", "Column", True, True, legacy(Vertical=True))
782*0e16a31dSJim Jagielski    A("area-deep", "cat", "ThreeDArea", True, True, legacy(Deep=True))
783*0e16a31dSJim Jagielski    A("area-flat", "cat", "ThreeDArea", True, True, legacy(Deep=False))
784*0e16a31dSJim Jagielski    A("line3d-flat", "cat", "ThreeDLine", True, True, legacy(Deep=False))
785*0e16a31dSJim Jagielski    A("dim3d-off", "cat", "ThreeDColumnDeep", True, True, legacy(Dim3D=False))
786*0e16a31dSJim Jagielski    A("bubble-hdr", "bub", "Bubble", True, False)
787*0e16a31dSJim Jagielski    A("scatter-nocats", "xy", "ScatterSymbol", False, True)
788*0e16a31dSJim Jagielski    A("pie-rows", "cat", "Pie", True, True, rows=True)
789*0e16a31dSJim Jagielski    h.done()
790*0e16a31dSJim Jagielski
791*0e16a31dSJim Jagielski    h = Host("point-props")
792*0e16a31dSJim Jagielski
793*0e16a31dSJim Jagielski    def points(ch):
794*0e16a31dSJim Jagielski        d = ch.getDiagram()
795*0e16a31dSJim Jagielski        for i in range(4):
796*0e16a31dSJim Jagielski            p = d.getDataPointProperties(i, 0)
797*0e16a31dSJim Jagielski            setp(p, "pt", FillColor=0x203060 + i * 0x302010, LineColor=0x101010, LineWidth=20 * i,
798*0e16a31dSJim Jagielski                 FillStyle=enum("com.sun.star.drawing.FillStyle", "SOLID"), DataCaption=i % 4,
799*0e16a31dSJim Jagielski                 LineStyle=enum("com.sun.star.drawing.LineStyle", ("SOLID", "DASH", "NONE", "SOLID")[i]),
800*0e16a31dSJim Jagielski                 FillTransparence=10 * i, LineTransparence=5 * i)
801*0e16a31dSJim Jagielski    for t in ("Column", "Line", "Area", "Bar", "StackedColumn"):
802*0e16a31dSJim Jagielski        attempt("pts/" + t, h.chart, "pts" + t, "cat", t, combine(title("points " + t), points))
803*0e16a31dSJim Jagielski
804*0e16a31dSJim Jagielski    def series_style(ch):
805*0e16a31dSJim Jagielski        for i, s in enumerate(series_of(ch)):
806*0e16a31dSJim Jagielski            setp(s, "s", Color=0x113355 + i * 0x303030, FillStyle=enum("com.sun.star.drawing.FillStyle", ("SOLID", "GRADIENT", "HATCH", "SOLID")[i]),
807*0e16a31dSJim Jagielski                 LineStyle=enum("com.sun.star.drawing.LineStyle", "SOLID"), LineWidth=30 * (i + 1), Transparency=20 * i,
808*0e16a31dSJim Jagielski                 CharHeight=9.0 + i, CharColor=0x000000 + i * 0x101010, CharFontName="Helvetica",
809*0e16a31dSJim Jagielski                 CharWeight=100.0 + 20 * i, CharUnderline=i)
810*0e16a31dSJim Jagielski    attempt("series/style", h.chart, "ss", "cat", "Column", combine(title("series style"), series_style))
811*0e16a31dSJim Jagielski    attempt("series/style-line", h.chart, "ssl", "cat", "LineSymbol", combine(title("series style line"), series_style))
812*0e16a31dSJim Jagielski
813*0e16a31dSJim Jagielski    def fills(ch):
814*0e16a31dSJim Jagielski        ss = series_of(ch)
815*0e16a31dSJim Jagielski        g = uno.createUnoStruct("com.sun.star.awt.Gradient")
816*0e16a31dSJim Jagielski        g.Style = enum("com.sun.star.awt.GradientStyle", "LINEAR")
817*0e16a31dSJim Jagielski        g.StartColor = 0xff0000
818*0e16a31dSJim Jagielski        g.EndColor = 0x0000ff
819*0e16a31dSJim Jagielski        g.Angle = 300
820*0e16a31dSJim Jagielski        g.Border = 5
821*0e16a31dSJim Jagielski        g.XOffset = 50
822*0e16a31dSJim Jagielski        g.YOffset = 50
823*0e16a31dSJim Jagielski        g.StartIntensity = 100
824*0e16a31dSJim Jagielski        g.EndIntensity = 100
825*0e16a31dSJim Jagielski        g.StepCount = 0
826*0e16a31dSJim Jagielski        ch.createInstance("com.sun.star.drawing.GradientTable").insertByName("grad1", g)
827*0e16a31dSJim Jagielski        setp(ss[0], "g", FillStyle=enum("com.sun.star.drawing.FillStyle", "GRADIENT"), GradientName="grad1")
828*0e16a31dSJim Jagielski        hs = uno.createUnoStruct("com.sun.star.drawing.Hatch")
829*0e16a31dSJim Jagielski        hs.Style = enum("com.sun.star.drawing.HatchStyle", "DOUBLE")
830*0e16a31dSJim Jagielski        hs.Color = 0x00aa00
831*0e16a31dSJim Jagielski        hs.Distance = 100
832*0e16a31dSJim Jagielski        hs.Angle = 450
833*0e16a31dSJim Jagielski        ch.createInstance("com.sun.star.drawing.HatchTable").insertByName("hatch1", hs)
834*0e16a31dSJim Jagielski        setp(ss[1], "h", FillStyle=enum("com.sun.star.drawing.FillStyle", "HATCH"), HatchName="hatch1", FillBackground=True,
835*0e16a31dSJim Jagielski             Color=0xffffaa)
836*0e16a31dSJim Jagielski    attempt("series/gradient-hatch", h.chart, "grad", "cat", "Column", combine(title("gradient hatch"), fills))
837*0e16a31dSJim Jagielski    h.done()
838*0e16a31dSJim Jagielski
839*0e16a31dSJim Jagielski
840*0e16a31dSJim JagielskiD5 = {"cats": CATS[:5], "names": ["north", "south", "east"],
841*0e16a31dSJim Jagielski      "rows": [(4, 7, 5), (6, 3, 8), (5, 9, 4), (8, 6, 7), (3, 5, 9)]}
842*0e16a31dSJim JagielskiDX = {"cats": ["1", "2", "3", "4", "5"], "names": ["y1", "y2"], "rows": [(2, 3), (4, 3.5), (5, 6), (7, 5.5), (9, 8)]}
843*0e16a31dSJim JagielskiDS = {"cats": CATS[:5], "names": ["open", "low", "high", "close"],
844*0e16a31dSJim Jagielski      "rows": [(20, 17, 24, 22), (21, 18, 26, 20), (22, 19, 25, 24), (23, 18, 27, 25), (21, 17, 26, 19)]}
845*0e16a31dSJim JagielskiDV = {"cats": CATS[:5], "names": ["volume", "open", "low", "high", "close"],
846*0e16a31dSJim Jagielski      "rows": [(120, 20, 17, 24, 22), (90, 21, 18, 26, 20), (150, 22, 19, 25, 24), (80, 23, 18, 27, 25), (110, 21, 17, 26, 19)]}
847*0e16a31dSJim JagielskiEMBED = [
848*0e16a31dSJim Jagielski    ("Column", D5), ("StackedColumn", D5), ("PercentStackedBar", D5), ("Line", D5), ("LineSymbol", D5), ("Area", D5),
849*0e16a31dSJim Jagielski    ("StackedArea", D5), ("Pie", {"cats": CATS[:5], "names": ["share"], "rows": [(4,), (6,), (5,), (8,), (3,)]}),
850*0e16a31dSJim Jagielski    ("Donut", D5), ("ScatterLineSymbol", DX), ("Net", D5), ("FilledNet", D5), ("StockOpenLowHighClose", DS),
851*0e16a31dSJim Jagielski    ("StockVolumeOpenLowHighClose", DV), ("StockLowHighClose", {"cats": CATS[:5], "names": ["low", "high", "close"],
852*0e16a31dSJim Jagielski        "rows": [(17, 24, 22), (18, 26, 20), (19, 25, 24), (18, 27, 25), (17, 26, 19)]}),
853*0e16a31dSJim Jagielski    ("ThreeDColumnDeep", D5), ("ThreeDPie", {"cats": CATS[:5], "names": ["share"], "rows": [(4,), (6,), (5,), (8,), (3,)]}),
854*0e16a31dSJim Jagielski    ("ThreeDArea", D5), ("ColumnWithLine", D5), ("Bar", D5),
855*0e16a31dSJim Jagielski]
856*0e16a31dSJim Jagielski
857*0e16a31dSJim Jagielski
858*0e16a31dSJim Jagielskidef embedded_doc(name, kind, items, extra=None):
859*0e16a31dSJim Jagielski    h = Host(name, kind)
860*0e16a31dSJim Jagielski    for i, (tpl, data) in enumerate(items):
861*0e16a31dSJim Jagielski        attempt("%s/%s" % (name, tpl), h.chart, "%s%d" % (tpl, i), None, tpl, combine(title(tpl, "sub " + tpl), extra), data=data)
862*0e16a31dSJim Jagielski    h.done()
863*0e16a31dSJim Jagielski
864*0e16a31dSJim Jagielski
865*0e16a31dSJim Jagielskidef topic_hosts():
866*0e16a31dSJim Jagielski    def legend_labels(ch):
867*0e16a31dSJim Jagielski        ch.HasLegend = True
868*0e16a31dSJim Jagielski        sprops(None, Label=label(num=True))(ch)
869*0e16a31dSJim Jagielski    embedded_doc("embed-writer", "odt", EMBED[:10], legend_labels)
870*0e16a31dSJim Jagielski    embedded_doc("embed-writer2", "odt", EMBED[10:], axis_titles)
871*0e16a31dSJim Jagielski    embedded_doc("embed-impress", "odp", EMBED[:10], legend_labels)
872*0e16a31dSJim Jagielski    embedded_doc("embed-impress2", "odp", EMBED[10:], None)
873*0e16a31dSJim Jagielski    embedded_doc("embed-draw", "odg", EMBED[:8])
874*0e16a31dSJim Jagielski    embedded_doc("embed-draw2", "odg", EMBED[8:])
875*0e16a31dSJim Jagielski
876*0e16a31dSJim Jagielski
877*0e16a31dSJim Jagielskidef topic_writer_table():
878*0e16a31dSJim Jagielski    doc = new("private:factory/swriter")
879*0e16a31dSJim Jagielski    CURRENT[0] = doc
880*0e16a31dSJim Jagielski    try:
881*0e16a31dSJim Jagielski        for rows in (5, 5):
882*0e16a31dSJim Jagielski            t = doc.createInstance("com.sun.star.text.TextTable")
883*0e16a31dSJim Jagielski            t.initialize(rows, 4)
884*0e16a31dSJim Jagielski            doc.Text.insertTextContent(doc.Text.getEnd(), t, False)
885*0e16a31dSJim Jagielski            for c in "BCD":
886*0e16a31dSJim Jagielski                t.getCellByName(c + "1").String = "s" + c
887*0e16a31dSJim Jagielski            for r in range(2, rows + 1):
888*0e16a31dSJim Jagielski                t.getCellByName("A%d" % r).String = "c%d" % r
889*0e16a31dSJim Jagielski                for j, c in enumerate("BCD"):
890*0e16a31dSJim Jagielski                    t.getCellByName("%s%d" % (c, r)).Value = (r * (j + 2) * 3) % 9 + 1
891*0e16a31dSJim Jagielski            doc.Text.insertControlCharacter(doc.Text.getEnd(), uno.getConstantByName("com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK"), False)
892*0e16a31dSJim Jagielski    except Exception as e:
893*0e16a31dSJim Jagielski        failed.append("writer-table")
894*0e16a31dSJim Jagielski        import traceback
895*0e16a31dSJim Jagielski        traceback.print_exc()
896*0e16a31dSJim Jagielski        print("FAIL writer table", repr(e)[:200])
897*0e16a31dSJim Jagielski    dp = doc.createInstance("com.sun.star.chart2.data.DataProvider")
898*0e16a31dSJim Jagielski    print("writer dp", dp is not None)
899*0e16a31dSJim Jagielski    for i, (tn, tpl) in enumerate((("Table1", "Column"), ("Table1", "Line"), ("Table2", "Pie"), ("Table2", "StockOpenLowHighClose"),
900*0e16a31dSJim Jagielski                                   ("Table1", "Bar"), ("Table2", "Area"))):
901*0e16a31dSJim Jagielski        def mk(tn=tn, tpl=tpl, i=i):
902*0e16a31dSJim Jagielski            shape = doc.createInstance("com.sun.star.text.TextEmbeddedObject")
903*0e16a31dSJim Jagielski            shape.CLSID = CHART_CLSID
904*0e16a31dSJim Jagielski            shape.Name = "wc%d" % i
905*0e16a31dSJim Jagielski            doc.Text.insertTextContent(doc.Text.getEnd(), shape, False)
906*0e16a31dSJim Jagielski            ch = shape.getEmbeddedObject()
907*0e16a31dSJim Jagielski            ch.attachDataProvider(doc.createInstance("com.sun.star.chart2.data.DataProvider"))
908*0e16a31dSJim Jagielski            rng = tn + ".A1:D5" if tpl != "Pie" else tn + ".A1:B5"
909*0e16a31dSJim Jagielski            args = (pv("CellRangeRepresentation", rng), pv("DataRowSource", COLUMNS), pv("FirstCellAsLabel", True), pv("HasCategories", True))
910*0e16a31dSJim Jagielski            ch.setArguments(args)
911*0e16a31dSJim Jagielski            t = ch.ChartTypeManager.createInstance(TPL + tpl)
912*0e16a31dSJim Jagielski            ch.setFirstDiagram(t.createDiagramByDataSource(ch.getDataProvider().createDataSource(args), args))
913*0e16a31dSJim Jagielski            title("table chart %s %s" % (tn, tpl))(ch)
914*0e16a31dSJim Jagielski            ch.HasLegend = True
915*0e16a31dSJim Jagielski        attempt("writer-table/%s-%s" % (tn, tpl), mk)
916*0e16a31dSJim Jagielski    save(doc, "embed-writer-table.odt")
917*0e16a31dSJim Jagielski    doc.close(True)
918*0e16a31dSJim Jagielski
919*0e16a31dSJim Jagielski
920*0e16a31dSJim Jagielskifor _t in (topic_types, topic_stock, topic_threed, topic_pie, topic_axes, topic_labels, topic_stats, topic_legend,
921*0e16a31dSJim Jagielski           topic_symbols, topic_data, topic_hosts, topic_writer_table):
922*0e16a31dSJim Jagielski    attempt(_t.__name__, _t)
923*0e16a31dSJim Jagielskitry:
924*0e16a31dSJim Jagielski    os.remove(PNG)
925*0e16a31dSJim Jagielskiexcept Exception:
926*0e16a31dSJim Jagielski    pass
927*0e16a31dSJim Jagielskiprint("failed:", failed)
928*0e16a31dSJim Jagielskisys.exit(1 if failed else 0)
929