Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/xlsxwriter/chart_bar.py: 13%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

68 statements  

1############################################################################### 

2# 

3# ChartBar - A class for writing the Excel XLSX Bar charts. 

4# 

5# SPDX-License-Identifier: BSD-2-Clause 

6# 

7# Copyright (c) 2013-2025, John McNamara, jmcnamara@cpan.org 

8# 

9 

10from warnings import warn 

11 

12from . import chart 

13 

14 

15class ChartBar(chart.Chart): 

16 """ 

17 A class for writing the Excel XLSX Bar charts. 

18 

19 

20 """ 

21 

22 ########################################################################### 

23 # 

24 # Public API. 

25 # 

26 ########################################################################### 

27 

28 def __init__(self, options=None): 

29 """ 

30 Constructor. 

31 

32 """ 

33 super().__init__() 

34 

35 if options is None: 

36 options = {} 

37 

38 self.subtype = options.get("subtype") 

39 

40 if not self.subtype: 

41 self.subtype = "clustered" 

42 

43 self.cat_axis_position = "l" 

44 self.val_axis_position = "b" 

45 self.horiz_val_axis = 0 

46 self.horiz_cat_axis = 1 

47 self.show_crosses = False 

48 

49 # Override and reset the default axis values. 

50 self.x_axis["defaults"]["major_gridlines"] = {"visible": 1} 

51 self.y_axis["defaults"]["major_gridlines"] = {"visible": 0} 

52 

53 if self.subtype == "percent_stacked": 

54 self.x_axis["defaults"]["num_format"] = "0%" 

55 

56 # Set the available data label positions for this chart type. 

57 self.label_position_default = "outside_end" 

58 self.label_positions = { 

59 "center": "ctr", 

60 "inside_base": "inBase", 

61 "inside_end": "inEnd", 

62 "outside_end": "outEnd", 

63 } 

64 

65 self.set_x_axis({}) 

66 self.set_y_axis({}) 

67 

68 def combine(self, chart=None): 

69 # pylint: disable=redefined-outer-name 

70 """ 

71 Create a combination chart with a secondary chart. 

72 

73 Note: Override parent method to add an extra check that is required 

74 for Bar charts to ensure that their combined chart is on a secondary 

75 axis. 

76 

77 Args: 

78 chart: The secondary chart to combine with the primary chart. 

79 

80 Returns: 

81 Nothing. 

82 

83 """ 

84 if chart is None: 

85 return 

86 

87 if not chart.is_secondary: 

88 warn("Charts combined with Bar charts must be on a secondary axis") 

89 

90 self.combined = chart 

91 

92 ########################################################################### 

93 # 

94 # Private API. 

95 # 

96 ########################################################################### 

97 

98 def _write_chart_type(self, args): 

99 # Override the virtual superclass method with a chart specific method. 

100 if args["primary_axes"]: 

101 # Reverse X and Y axes for Bar charts. 

102 tmp = self.y_axis 

103 self.y_axis = self.x_axis 

104 self.x_axis = tmp 

105 

106 if self.y2_axis["position"] == "r": 

107 self.y2_axis["position"] = "t" 

108 

109 # Write the c:barChart element. 

110 self._write_bar_chart(args) 

111 

112 def _write_bar_chart(self, args): 

113 # Write the <c:barChart> element. 

114 

115 if args["primary_axes"]: 

116 series = self._get_primary_axes_series() 

117 else: 

118 series = self._get_secondary_axes_series() 

119 

120 if not series: 

121 return 

122 

123 subtype = self.subtype 

124 if subtype == "percent_stacked": 

125 subtype = "percentStacked" 

126 

127 # Set a default overlap for stacked charts. 

128 if "stacked" in self.subtype and self.series_overlap_1 is None: 

129 self.series_overlap_1 = 100 

130 

131 self._xml_start_tag("c:barChart") 

132 

133 # Write the c:barDir element. 

134 self._write_bar_dir() 

135 

136 # Write the c:grouping element. 

137 self._write_grouping(subtype) 

138 

139 # Write the c:ser elements. 

140 for data in series: 

141 self._write_ser(data) 

142 

143 # Write the c:gapWidth element. 

144 if args["primary_axes"]: 

145 self._write_gap_width(self.series_gap_1) 

146 else: 

147 self._write_gap_width(self.series_gap_2) 

148 

149 # Write the c:overlap element. 

150 if args["primary_axes"]: 

151 self._write_overlap(self.series_overlap_1) 

152 else: 

153 self._write_overlap(self.series_overlap_2) 

154 

155 # Write the c:axId elements 

156 self._write_axis_ids(args) 

157 

158 self._xml_end_tag("c:barChart") 

159 

160 ########################################################################### 

161 # 

162 # XML methods. 

163 # 

164 ########################################################################### 

165 

166 def _write_bar_dir(self): 

167 # Write the <c:barDir> element. 

168 val = "bar" 

169 

170 attributes = [("val", val)] 

171 

172 self._xml_empty_tag("c:barDir", attributes) 

173 

174 def _write_err_dir(self, val): 

175 # Overridden from Chart class since it is not used in Bar charts. 

176 pass