1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
5 # Jockey is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2, or (at your option) any
10 # Jockey is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 from pychart_types import *
29 class T(chart_object.T):
30 __doc__ = pie_plot_doc.doc
32 "start_angle" : (NumType, 90,
33 """The angle at which the first item is drawn."""),
34 "center" : (CoordType, None, "The location of the center of the pie."),
35 "radius" : (UnitType, None, "The radius of the pie."),
36 "line_style" : (line_style.T, line_style.default, "The style of the outer edge of each pie slice."),
38 "fill_styles" : (ListType, fill_style.standards.list(),
39 """The fill style of each item. The length of the
40 list should be equal to the length of the data.
42 "arc_offsets" : (ListType, None,
43 """You can draw each pie "slice" shifted off-center.
44 This attribute, if non-None,
45 must be a number sequence whose length is equal to
46 the number of pie slices. The Nth value in arc_offsets
47 specify the amount of offset
48 (from the center of the circle)
50 The value of None will draw all the slices
51 anchored at the center.
54 "data" : (AnyType, None, pychart_util.data_desc),
55 "label_format" : (FormatType, "%s",
56 "Format string of the label"),
57 "label_col" : (IntType, 0,
58 """The column, within "data", from which the labels of items are retrieved."""),
59 "data_col": (IntType, 1,
60 """ The column, within "data", from which the data values are retrieved."""),
61 "label_offset": (UnitType, None, "The distance from the center of each label."),
62 "arrow_style": (arrow.T, None,
63 """The style of arrow that connects a label
64 to the corresponding "pie"."""),
65 "label_line_style": (line_style.T, None, "The style of the frame surrounding each label."),
66 "label_fill_style": (fill_style.T, fill_style.default, "The fill style of the frame surrounding each label."),
67 "shadow": (ShadowType, None, pychart_util.shadow_desc)
69 ##AUTOMATICALLY GENERATED
71 ##END AUTOMATICALLY GENERATED
75 v += val[self.data_col]
78 def check_integrity(self):
80 def get_data_range(self, which):
82 def get_legend_entry(self):
86 fill = self.fill_styles[i]
87 i = (i + 1) % len(self.fill_styles)
88 legends.append(legend.Entry(line_style=self.line_style,
90 label=val[self.label_col]))
93 def draw(self, ar, can):
96 center = (ar.loc[0] + ar.size[0]/2.0,
97 ar.loc[1] + ar.size[1]/2.0)
100 radius = min(ar.size[0]/2.0, ar.size[1]/2.0) * 0.5
102 label_offset = radius + (self.label_offset or radius * 0.1)
104 total = self._total()
106 cur_angle = self.start_angle
107 for val in self.data:
108 fill = self.fill_styles[i]
109 degree = 360 * float(val[self.data_col]) / float(total)
112 if len(self.arc_offsets) > i:
113 off = pychart_util.rotate(self.arc_offsets[i], 0, cur_angle - degree/2.0)
114 x_center = center[0]+ off[0]
115 y_center = center[1]+ off[1]
117 can.ellipsis(self.line_style, fill,
118 x_center, y_center, radius, 1,
119 cur_angle - degree, cur_angle,
122 label = pychart_util.apply_format(self.label_format, val,
125 (x_label, y_label) = pychart_util.rotate(label_offset, 0, cur_angle - degree/2.0)
126 (x_arrowtip, y_arrowtip) = pychart_util.rotate(radius, 0, cur_angle - degree/2.0)
127 # Labels on left side of pie need
128 # their text to avoid obscuring the pie
130 x_label = x_label - font.text_width(label)
132 t = text_box.T(loc = (x_label + x_center, y_label + y_center),
134 line_style = self.label_line_style,
135 fill_style = self.label_fill_style)
137 t.add_arrow((x_arrowtip + x_center, y_arrowtip + y_center),
138 None, self.arrow_style)
141 cur_angle = (cur_angle - degree) % 360
142 i = (i + 1) % len(self.fill_styles)
146 old_val = T.keys["fill_styles"]
147 T.keys["fill_styles"] = (old_val[0], fill_style.standards.list(),
149 theme.add_reinitialization_hook(init)