summaryrefslogtreecommitdiff
path: root/bin/pychart/pie_plot.py
diff options
context:
space:
mode:
Diffstat (limited to 'bin/pychart/pie_plot.py')
-rw-r--r--bin/pychart/pie_plot.py148
1 files changed, 148 insertions, 0 deletions
diff --git a/bin/pychart/pie_plot.py b/bin/pychart/pie_plot.py
new file mode 100644
index 00000000000..c6f405a7ae9
--- /dev/null
+++ b/bin/pychart/pie_plot.py
@@ -0,0 +1,148 @@
+#
+# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
+#
+# Jockey is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+#
+# Jockey is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+import text_box
+import fill_style
+import line_style
+import pychart_util
+import chart_object
+import arrow
+import legend
+import font
+import pie_plot_doc
+import theme
+
+from pychart_types import *
+from types import *
+
+class T(chart_object.T):
+ __doc__ = pie_plot_doc.doc
+ keys = {
+ "start_angle" : (NumType, 90,
+ """The angle at which the first item is drawn."""),
+ "center" : (CoordType, None, "The location of the center of the pie."),
+ "radius" : (UnitType, None, "The radius of the pie."),
+ "line_style" : (line_style.T, line_style.default, "The style of the outer edge of each pie slice."),
+
+ "fill_styles" : (ListType, fill_style.standards.list(),
+ """The fill style of each item. The length of the
+ list should be equal to the length of the data.
+ """),
+ "arc_offsets" : (ListType, None,
+ """You can draw each pie "slice" shifted off-center.
+ This attribute, if non-None,
+ must be a number sequence whose length is equal to
+ the number of pie slices. The Nth value in arc_offsets
+ specify the amount of offset
+ (from the center of the circle)
+ for the Nth slice.
+ The value of None will draw all the slices
+ anchored at the center.
+ """
+ ),
+ "data" : (AnyType, None, pychart_util.data_desc),
+ "label_format" : (FormatType, "%s",
+ "Format string of the label"),
+ "label_col" : (IntType, 0,
+ """The column, within "data", from which the labels of items are retrieved."""),
+ "data_col": (IntType, 1,
+ """ The column, within "data", from which the data values are retrieved."""),
+ "label_offset": (UnitType, None, "The distance from the center of each label."),
+ "arrow_style": (arrow.T, None,
+ """The style of arrow that connects a label
+ to the corresponding "pie"."""),
+ "label_line_style": (line_style.T, None, "The style of the frame surrounding each label."),
+ "label_fill_style": (fill_style.T, fill_style.default, "The fill style of the frame surrounding each label."),
+ "shadow": (ShadowType, None, pychart_util.shadow_desc)
+ }
+##AUTOMATICALLY GENERATED
+
+##END AUTOMATICALLY GENERATED
+ def _total(self):
+ v = 0
+ for val in self.data:
+ v += val[self.data_col]
+ return v
+
+ def check_integrity(self):
+ self.type_check()
+ def get_data_range(self, which):
+ return (0, 1)
+ def get_legend_entry(self):
+ legends = []
+ i = 0
+ for val in self.data:
+ fill = self.fill_styles[i]
+ i = (i + 1) % len(self.fill_styles)
+ legends.append(legend.Entry(line_style=self.line_style,
+ fill_style=fill,
+ label=val[self.label_col]))
+ return legends
+
+ def draw(self, ar, can):
+ center = self.center
+ if not center:
+ center = (ar.loc[0] + ar.size[0]/2.0,
+ ar.loc[1] + ar.size[1]/2.0)
+ radius = self.radius
+ if not radius:
+ radius = min(ar.size[0]/2.0, ar.size[1]/2.0) * 0.5
+
+ label_offset = radius + (self.label_offset or radius * 0.1)
+
+ total = self._total()
+ i = 0
+ cur_angle = self.start_angle
+ for val in self.data:
+ fill = self.fill_styles[i]
+ degree = 360 * float(val[self.data_col]) / float(total)
+
+ off = (0, 0)
+ if len(self.arc_offsets) > i:
+ off = pychart_util.rotate(self.arc_offsets[i], 0, cur_angle - degree/2.0)
+ x_center = center[0]+ off[0]
+ y_center = center[1]+ off[1]
+
+ can.ellipsis(self.line_style, fill,
+ x_center, y_center, radius, 1,
+ cur_angle - degree, cur_angle,
+ self.shadow)
+
+ label = pychart_util.apply_format(self.label_format, val,
+ self.label_col)
+ if label != None:
+ (x_label, y_label) = pychart_util.rotate(label_offset, 0, cur_angle - degree/2.0)
+ (x_arrowtip, y_arrowtip) = pychart_util.rotate(radius, 0, cur_angle - degree/2.0)
+ # Labels on left side of pie need
+ # their text to avoid obscuring the pie
+ if x_label < 0:
+ x_label = x_label - font.text_width(label)
+
+ t = text_box.T(loc = (x_label + x_center, y_label + y_center),
+ text = label,
+ line_style = self.label_line_style,
+ fill_style = self.label_fill_style)
+ if self.arrow_style:
+ t.add_arrow((x_arrowtip + x_center, y_arrowtip + y_center),
+ None, self.arrow_style)
+
+ t.draw(can)
+ cur_angle = (cur_angle - degree) % 360
+ i = (i + 1) % len(self.fill_styles)
+
+
+def init():
+ old_val = T.keys["fill_styles"]
+ T.keys["fill_styles"] = (old_val[0], fill_style.standards.list(),
+ old_val[2])
+theme.add_reinitialization_hook(init)