Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/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

67 statements  

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

2# 

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

4# 

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

6# Copyright 2013-2024, John McNamara, jmcnamara@cpan.org 

7# 

8 

9from . import chart 

10from warnings import warn 

11 

12 

13class ChartBar(chart.Chart): 

14 """ 

15 A class for writing the Excel XLSX Bar charts. 

16 

17 

18 """ 

19 

20 ########################################################################### 

21 # 

22 # Public API. 

23 # 

24 ########################################################################### 

25 

26 def __init__(self, options=None): 

27 """ 

28 Constructor. 

29 

30 """ 

31 super(ChartBar, self).__init__() 

32 

33 if options is None: 

34 options = {} 

35 

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

37 

38 if not self.subtype: 

39 self.subtype = "clustered" 

40 

41 self.cat_axis_position = "l" 

42 self.val_axis_position = "b" 

43 self.horiz_val_axis = 0 

44 self.horiz_cat_axis = 1 

45 self.show_crosses = False 

46 

47 # Override and reset the default axis values. 

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

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

50 

51 if self.subtype == "percent_stacked": 

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

53 

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

55 self.label_position_default = "outside_end" 

56 self.label_positions = { 

57 "center": "ctr", 

58 "inside_base": "inBase", 

59 "inside_end": "inEnd", 

60 "outside_end": "outEnd", 

61 } 

62 

63 self.set_x_axis({}) 

64 self.set_y_axis({}) 

65 

66 def combine(self, chart=None): 

67 """ 

68 Create a combination chart with a secondary chart. 

69 

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

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

72 axis. 

73 

74 Args: 

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

76 

77 Returns: 

78 Nothing. 

79 

80 """ 

81 if chart is None: 

82 return 

83 

84 if not chart.is_secondary: 

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

86 

87 self.combined = chart 

88 

89 ########################################################################### 

90 # 

91 # Private API. 

92 # 

93 ########################################################################### 

94 

95 def _write_chart_type(self, args): 

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

97 if args["primary_axes"]: 

98 # Reverse X and Y axes for Bar charts. 

99 tmp = self.y_axis 

100 self.y_axis = self.x_axis 

101 self.x_axis = tmp 

102 

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

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

105 

106 # Write the c:barChart element. 

107 self._write_bar_chart(args) 

108 

109 def _write_bar_chart(self, args): 

110 # Write the <c:barChart> element. 

111 

112 if args["primary_axes"]: 

113 series = self._get_primary_axes_series() 

114 else: 

115 series = self._get_secondary_axes_series() 

116 

117 if not len(series): 

118 return 

119 

120 subtype = self.subtype 

121 if subtype == "percent_stacked": 

122 subtype = "percentStacked" 

123 

124 # Set a default overlap for stacked charts. 

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

126 self.series_overlap_1 = 100 

127 

128 self._xml_start_tag("c:barChart") 

129 

130 # Write the c:barDir element. 

131 self._write_bar_dir() 

132 

133 # Write the c:grouping element. 

134 self._write_grouping(subtype) 

135 

136 # Write the c:ser elements. 

137 for data in series: 

138 self._write_ser(data) 

139 

140 # Write the c:gapWidth element. 

141 if args["primary_axes"]: 

142 self._write_gap_width(self.series_gap_1) 

143 else: 

144 self._write_gap_width(self.series_gap_2) 

145 

146 # Write the c:overlap element. 

147 if args["primary_axes"]: 

148 self._write_overlap(self.series_overlap_1) 

149 else: 

150 self._write_overlap(self.series_overlap_2) 

151 

152 # Write the c:axId elements 

153 self._write_axis_ids(args) 

154 

155 self._xml_end_tag("c:barChart") 

156 

157 ########################################################################### 

158 # 

159 # XML methods. 

160 # 

161 ########################################################################### 

162 

163 def _write_bar_dir(self): 

164 # Write the <c:barDir> element. 

165 val = "bar" 

166 

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

168 

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

170 

171 def _write_err_dir(self, val): 

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

173 pass