1###############################################################################
2#
3# ChartStock - A class for writing the Excel XLSX Stock charts.
4#
5# SPDX-License-Identifier: BSD-2-Clause
6# Copyright 2013-2024, John McNamara, jmcnamara@cpan.org
7#
8
9from . import chart
10
11
12class ChartStock(chart.Chart):
13 """
14 A class for writing the Excel XLSX Stock charts.
15
16 """
17
18 ###########################################################################
19 #
20 # Public API.
21 #
22 ###########################################################################
23
24 def __init__(self, options=None):
25 """
26 Constructor.
27
28 """
29 super(ChartStock, self).__init__()
30
31 self.show_crosses = False
32 self.hi_low_lines = {}
33 self.date_category = True
34
35 # Override and reset the default axis values.
36 self.x_axis["defaults"]["num_format"] = "dd/mm/yyyy"
37 self.x2_axis["defaults"]["num_format"] = "dd/mm/yyyy"
38
39 # Set the available data label positions for this chart type.
40 self.label_position_default = "right"
41 self.label_positions = {
42 "center": "ctr",
43 "right": "r",
44 "left": "l",
45 "above": "t",
46 "below": "b",
47 # For backward compatibility.
48 "top": "t",
49 "bottom": "b",
50 }
51
52 self.set_x_axis({})
53 self.set_x2_axis({})
54
55 ###########################################################################
56 #
57 # Private API.
58 #
59 ###########################################################################
60
61 def _write_chart_type(self, args):
62 # Override the virtual superclass method with a chart specific method.
63 # Write the c:stockChart element.
64 self._write_stock_chart(args)
65
66 ###########################################################################
67 #
68 # XML methods.
69 #
70 ###########################################################################
71
72 def _write_stock_chart(self, args):
73 # Write the <c:stockChart> element.
74 # Overridden to add hi_low_lines().
75
76 if args["primary_axes"]:
77 series = self._get_primary_axes_series()
78 else:
79 series = self._get_secondary_axes_series()
80
81 if not len(series):
82 return
83
84 # Add default formatting to the series data.
85 self._modify_series_formatting()
86
87 self._xml_start_tag("c:stockChart")
88
89 # Write the series elements.
90 for data in series:
91 self._write_ser(data)
92
93 # Write the c:dropLines element.
94 self._write_drop_lines()
95
96 # Write the c:hiLowLines element.
97 if args.get("primary_axes"):
98 self._write_hi_low_lines()
99
100 # Write the c:upDownBars element.
101 self._write_up_down_bars()
102
103 # Write the c:axId elements
104 self._write_axis_ids(args)
105
106 self._xml_end_tag("c:stockChart")
107
108 def _modify_series_formatting(self):
109 # Add default formatting to the series data.
110
111 index = 0
112
113 for series in self.series:
114 if index % 4 != 3:
115 if not series["line"]["defined"]:
116 series["line"] = {"width": 2.25, "none": 1, "defined": 1}
117
118 if series["marker"] is None:
119 if index % 4 == 2:
120 series["marker"] = {"type": "dot", "size": 3}
121 else:
122 series["marker"] = {"type": "none"}
123
124 index += 1