/usr/lib/python3/dist-packages/xlsxwriter/chart_pie.py is in python3-xlsxwriter 0.7.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | ###############################################################################
#
# ChartPie - A class for writing the Excel XLSX Pie charts.
#
# Copyright 2013-2015, John McNamara, jmcnamara@cpan.org
#
from warnings import warn
from . import chart
class ChartPie(chart.Chart):
"""
A class for writing the Excel XLSX Pie charts.
"""
###########################################################################
#
# Public API.
#
###########################################################################
def __init__(self, options=None):
"""
Constructor.
"""
super(ChartPie, self).__init__()
if options is None:
options = {}
self.vary_data_color = 1
self.rotation = 0
# Set the available data label positions for this chart type.
self.label_position_default = 'best_fit'
self.label_positions = {
'center': 'ctr',
'inside_end': 'inEnd',
'outside_end': 'outEnd',
'best_fit': 'bestFit'}
def set_rotation(self, rotation):
"""
Set the Pie/Doughnut chart rotation: the angle of the first slice.
Args:
rotation: First segment angle: 0 <= rotation <= 360.
Returns:
Nothing.
"""
if rotation is None:
return
# Ensure the rotation is in Excel's range.
if rotation < 0 or rotation > 360:
warn("Chart rotation %d outside Excel range: 0 <= rotation <= 360"
% rotation)
return
self.rotation = int(rotation)
###########################################################################
#
# Private API.
#
###########################################################################
def _write_chart_type(self, args):
# Override the virtual superclass method with a chart specific method.
# Write the c:pieChart element.
self._write_pie_chart(args)
###########################################################################
#
# XML methods.
#
###########################################################################
def _write_pie_chart(self, args):
# Write the <c:pieChart> element. Over-ridden method to remove
# axis_id code since Pie charts don't require val and cat axes.
self._xml_start_tag('c:pieChart')
# Write the c:varyColors element.
self._write_vary_colors()
# Write the series elements.
for data in self.series:
self._write_ser(data)
# Write the c:firstSliceAng element.
self._write_first_slice_ang()
self._xml_end_tag('c:pieChart')
def _write_plot_area(self):
# Over-ridden method to remove the cat_axis() and val_axis() code
# since Pie charts don't require those axes.
#
# Write the <c:plotArea> element.
self._xml_start_tag('c:plotArea')
# Write the c:layout element.
self._write_layout(self.plotarea.get('layout'), 'plot')
# Write the subclass chart type element.
self._write_chart_type(None)
self._xml_end_tag('c:plotArea')
def _write_legend(self):
# Over-ridden method to add <c:txPr> to legend.
# Write the <c:legend> element.
position = self.legend_position
font = self.legend_font
delete_series = []
overlay = 0
if (self.legend_delete_series is not None
and type(self.legend_delete_series) is list):
delete_series = self.legend_delete_series
if position.startswith('overlay_'):
position = position.replace('overlay_', '')
overlay = 1
allowed = {
'right': 'r',
'left': 'l',
'top': 't',
'bottom': 'b',
}
if position == 'none':
return
if position not in allowed:
return
position = allowed[position]
self._xml_start_tag('c:legend')
# Write the c:legendPos element.
self._write_legend_pos(position)
# Remove series labels from the legend.
for index in delete_series:
# Write the c:legendEntry element.
self._write_legend_entry(index)
# Write the c:layout element.
self._write_layout(self.legend_layout, 'legend')
# Write the c:overlay element.
if overlay:
self._write_overlay()
# Write the c:txPr element. Over-ridden.
self._write_tx_pr_legend(None, font)
self._xml_end_tag('c:legend')
def _write_tx_pr_legend(self, horiz, font):
# Write the <c:txPr> element for legends.
if font and font.get('rotation'):
rotation = font['rotation']
else:
rotation = None
self._xml_start_tag('c:txPr')
# Write the a:bodyPr element.
self._write_a_body_pr(rotation, horiz)
# Write the a:lstStyle element.
self._write_a_lst_style()
# Write the a:p element.
self._write_a_p_legend(font)
self._xml_end_tag('c:txPr')
def _write_a_p_legend(self, font):
# Write the <a:p> element for legends.
self._xml_start_tag('a:p')
# Write the a:pPr element.
self._write_a_p_pr_legend(font)
# Write the a:endParaRPr element.
self._write_a_end_para_rpr()
self._xml_end_tag('a:p')
def _write_a_p_pr_legend(self, font):
# Write the <a:pPr> element for legends.
attributes = [('rtl', 0)]
self._xml_start_tag('a:pPr', attributes)
# Write the a:defRPr element.
self._write_a_def_rpr(font)
self._xml_end_tag('a:pPr')
def _write_vary_colors(self):
# Write the <c:varyColors> element.
attributes = [('val', 1)]
self._xml_empty_tag('c:varyColors', attributes)
def _write_first_slice_ang(self):
# Write the <c:firstSliceAng> element.
attributes = [('val', self.rotation)]
self._xml_empty_tag('c:firstSliceAng', attributes)
|