1###############################################################################
2#
3# ChartLine - A class for writing the Excel XLSX Line 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 ChartLine(chart.Chart):
13 """
14 A class for writing the Excel XLSX Line charts.
15
16
17 """
18
19 ###########################################################################
20 #
21 # Public API.
22 #
23 ###########################################################################
24
25 def __init__(self, options=None):
26 """
27 Constructor.
28
29 """
30 super(ChartLine, self).__init__()
31
32 if options is None:
33 options = {}
34
35 self.subtype = options.get("subtype")
36
37 if not self.subtype:
38 self.subtype = "standard"
39
40 self.default_marker = {"type": "none"}
41 self.smooth_allowed = True
42
43 # Override and reset the default axis values.
44 if self.subtype == "percent_stacked":
45 self.y_axis["defaults"]["num_format"] = "0%"
46
47 # Set the available data label positions for this chart type.
48 self.label_position_default = "right"
49 self.label_positions = {
50 "center": "ctr",
51 "right": "r",
52 "left": "l",
53 "above": "t",
54 "below": "b",
55 # For backward compatibility.
56 "top": "t",
57 "bottom": "b",
58 }
59
60 self.set_y_axis({})
61
62 ###########################################################################
63 #
64 # Private API.
65 #
66 ###########################################################################
67
68 def _write_chart_type(self, args):
69 # Override the virtual superclass method with a chart specific method.
70 # Write the c:lineChart element.
71 self._write_line_chart(args)
72
73 ###########################################################################
74 #
75 # XML methods.
76 #
77 ###########################################################################
78
79 def _write_line_chart(self, args):
80 # Write the <c:lineChart> element.
81
82 if args["primary_axes"]:
83 series = self._get_primary_axes_series()
84 else:
85 series = self._get_secondary_axes_series()
86
87 if not len(series):
88 return
89
90 subtype = self.subtype
91
92 if subtype == "percent_stacked":
93 subtype = "percentStacked"
94
95 self._xml_start_tag("c:lineChart")
96
97 # Write the c:grouping element.
98 self._write_grouping(subtype)
99
100 # Write the series elements.
101 for data in series:
102 self._write_ser(data)
103
104 # Write the c:dropLines element.
105 self._write_drop_lines()
106
107 # Write the c:hiLowLines element.
108 self._write_hi_low_lines()
109
110 # Write the c:upDownBars element.
111 self._write_up_down_bars()
112
113 # Write the c:marker element.
114 self._write_marker_value()
115
116 # Write the c:axId elements
117 self._write_axis_ids(args)
118
119 self._xml_end_tag("c:lineChart")
120
121 def _write_d_pt_point(self, index, point):
122 # Write an individual <c:dPt> element. Override the parent method to
123 # add markers.
124
125 self._xml_start_tag("c:dPt")
126
127 # Write the c:idx element.
128 self._write_idx(index)
129
130 self._xml_start_tag("c:marker")
131
132 # Write the c:spPr element.
133 self._write_sp_pr(point)
134
135 self._xml_end_tag("c:marker")
136
137 self._xml_end_tag("c:dPt")
138
139 def _write_marker_value(self):
140 # Write the <c:marker> element without a sub-element.
141 attributes = [("val", 1)]
142
143 self._xml_empty_tag("c:marker", attributes)