mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-19 10:17:08 +01:00
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@73909 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
139 lines
5.1 KiB
Python
139 lines
5.1 KiB
Python
import wx
|
|
|
|
## import a local version of FloatCanvas
|
|
|
|
|
|
from wx.lib.floatcanvas import FloatCanvas
|
|
from wx.lib.floatcanvas.Utilities import BBox
|
|
from wx.lib.floatcanvas.Utilities import Colors
|
|
|
|
import numpy as N
|
|
|
|
XYObjectMixin = FloatCanvas.XYObjectMixin
|
|
LineOnlyMixin = FloatCanvas.LineOnlyMixin
|
|
DrawObject = FloatCanvas.DrawObject
|
|
|
|
class PieChart(XYObjectMixin, LineOnlyMixin, DrawObject):
|
|
"""
|
|
This is DrawObject for a pie chart
|
|
|
|
You can pass in a bunch of values, and it will draw a pie chart for
|
|
you, and it will make the chart, scaling the size of each "slice" to
|
|
match your values.
|
|
|
|
The parameters are:
|
|
|
|
XY : The (x,y) coords of the center of the chart
|
|
Diameter : The diamter of the chart in worls coords, unless you set
|
|
"Scaled" to False, in which case it's in pixel coords.
|
|
Values : sequence of values you want to make the chart of.
|
|
FillColors=None : sequence of colors you want the slices. If
|
|
None, it will choose (no guarantee youll like them!)
|
|
FillStyles=None : Fill style you want ("Solid", "Hash", etc)
|
|
LineColor = None : Color of lines separating the slices
|
|
LineStyle = "Solid" : style of lines separating the slices
|
|
LineWidth = 1 : With of lines separating the slices
|
|
Scaled = True : Do you want the pie to scale when zooming? or stay the same size in pixels?
|
|
InForeground = False: Should it be on the foreground?
|
|
|
|
|
|
"""
|
|
|
|
|
|
##fixme: this should be a longer and better designed set.
|
|
## Maybe one from: http://geography.uoregon.edu/datagraphics/color_scales.htm
|
|
DefaultColorList = Colors.CategoricalColor1
|
|
#["Red", "Green", "Blue", "Purple", "Yellow", "Cyan"]
|
|
|
|
def __init__(self,
|
|
XY,
|
|
Diameter,
|
|
Values,
|
|
FillColors=None,
|
|
FillStyles=None,
|
|
LineColor = None,
|
|
LineStyle = "Solid",
|
|
LineWidth = 1,
|
|
Scaled = True,
|
|
InForeground = False):
|
|
DrawObject.__init__(self, InForeground)
|
|
|
|
self.XY = N.asarray(XY, N.float).reshape( (2,) )
|
|
self.Diameter = Diameter
|
|
self.Values = N.asarray(Values, dtype=N.float).reshape((-1,1))
|
|
if FillColors is None:
|
|
FillColors = self.DefaultColorList[:len(Values)]
|
|
if FillStyles is None:
|
|
FillStyles = ['Solid'] * len(FillColors)
|
|
self.FillColors = FillColors
|
|
self.FillStyles = FillStyles
|
|
self.LineColor = LineColor
|
|
self.LineStyle = LineStyle
|
|
|
|
self.Scaled = Scaled
|
|
self.InForeground = InForeground
|
|
|
|
self.SetPen(LineColor, LineStyle, LineWidth)
|
|
self.SetBrushes()
|
|
self.CalculatePoints()
|
|
|
|
def SetFillColors(self, FillColors):
|
|
self.FillColors = FillColors
|
|
self.SetBrushes()
|
|
|
|
def SetFillStyles(self, FillStyles):
|
|
self.FillStyles = FillStyles
|
|
self.SetBrushed()
|
|
|
|
def SetValues(self, Values):
|
|
Values = N.asarray(Values, dtype=N.float).reshape((-1,1))
|
|
self.Values = Values
|
|
self.CalculatePoints()
|
|
|
|
def CalculatePoints(self):
|
|
# add the zero point to start
|
|
Values = N.vstack( ( (0,), self.Values) )
|
|
self.Angles = 360. * Values.cumsum()/Values.sum()
|
|
self.CalcBoundingBox()
|
|
|
|
def SetBrushes(self):
|
|
self.Brushes = []
|
|
for FillColor, FillStyle in zip(self.FillColors, self.FillStyles):
|
|
if FillColor is None or FillStyle is None:
|
|
self.Brush = wx.TRANSPARENT_BRUSH
|
|
else:
|
|
self.Brushes.append(self.BrushList.setdefault( (FillColor, FillStyle),
|
|
wx.Brush( FillColor, self.FillStyleList[FillStyle] )
|
|
)
|
|
)
|
|
def CalcBoundingBox(self):
|
|
if self.Scaled:
|
|
self.BoundingBox = BBox.asBBox( ((self.XY-self.Diameter),(self.XY+self.Diameter)) )
|
|
else:
|
|
self.BoundingBox = BBox.asBBox((self.XY, self.XY))
|
|
if self._Canvas:
|
|
self._Canvas.BoundingBoxDirty = True
|
|
|
|
def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
|
|
CenterXY = WorldToPixel(self.XY)
|
|
if self.Scaled:
|
|
Diameter = ScaleWorldToPixel( (self.Diameter,self.Diameter) )[0]
|
|
else:
|
|
Diameter = self.Diameter
|
|
WH = N.array((Diameter,Diameter), dtype = N.float)
|
|
Corner = CenterXY - (WH / 2)
|
|
dc.SetPen(self.Pen)
|
|
for i, brush in enumerate(self.Brushes):
|
|
dc.SetBrush( brush )
|
|
dc.DrawEllipticArc(Corner[0], Corner[1], WH[0], WH[1], self.Angles[i], self.Angles[i+1])
|
|
if HTdc and self.HitAble:
|
|
if self.Scaled:
|
|
radius = (ScaleWorldToPixel(self.Diameter)/2)[0]# just the x-coord
|
|
else:
|
|
radius = self.Diameter/2
|
|
HTdc.SetPen(self.HitPen)
|
|
HTdc.SetBrush(self.HitBrush)
|
|
HTdc.DrawCircle(CenterXY, radius)
|
|
|
|
|