]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/wxPIA_book/Chapter-12/radargraph.py
5 class RadarGraph(wx
.Window
):
7 A simple radar graph that plots a collection of values in the
8 range of 0-100 onto a polar coordinate system designed to easily
9 show outliers, etc. You might use this kind of graph to monitor
10 some sort of resource allocation metrics, and a quick glance at
11 the graph can tell you when conditions are good (within some
12 accepted tolerance level) or approaching critical levels (total
13 resource consumption).
15 def __init__(self
, parent
, title
, labels
):
16 wx
.Window
.__init
__(self
, parent
)
19 self
.data
= [0.0] * len(labels
)
20 self
.titleFont
= wx
.Font(14, wx
.SWISS
, wx
.NORMAL
, wx
.BOLD
)
21 self
.labelFont
= wx
.Font(10, wx
.SWISS
, wx
.NORMAL
, wx
.NORMAL
)
25 self
.Bind(wx
.EVT_SIZE
, self
.OnSize
)
26 self
.Bind(wx
.EVT_PAINT
, self
.OnPaint
)
29 def OnSize(self
, evt
):
30 # When the window size changes we need a new buffer.
34 def OnPaint(self
, evt
):
35 # This automatically Blits self.buffer to a wx.PaintDC when
36 # the dc is destroyed, and so nothing else needs done.
37 dc
= wx
.BufferedPaintDC(self
, self
.buffer)
41 # Create the buffer bitmap to be the same size as the window,
42 # then draw our graph to it. Since we use wx.BufferedDC
43 # whatever is drawn to the buffer is also drawn to the window.
44 w
, h
= self
.GetClientSize()
45 self
.buffer = wx
.EmptyBitmap(w
, h
)
46 dc
= wx
.BufferedDC(wx
.ClientDC(self
), self
.buffer)
53 def SetData(self
, newData
):
54 assert len(newData
) == len(self
.data
)
55 self
.data
= newData
[:]
57 # The data has changed, so update the buffer and the window
58 dc
= wx
.BufferedDC(wx
.ClientDC(self
), self
.buffer)
62 def PolarToCartesian(self
, radius
, angle
, cx
, cy
):
63 x
= radius
* math
.cos(math
.radians(angle
))
64 y
= radius
* math
.sin(math
.radians(angle
))
68 def DrawGraph(self
, dc
):
72 dc
.SetBackground(wx
.Brush(self
.GetBackgroundColour()))
76 # Find out where to draw the title and do it
77 dc
.SetFont(self
.titleFont
)
78 tw
, th
= dc
.GetTextExtent(self
.title
)
79 dc
.DrawText(self
.title
, (dw
-tw
)/2, spacer
)
81 # find the center of the space below the title
86 # calculate a scale factor to use for drawing the graph based
87 # on the minimum available width or height
88 mindim
= min(cx
, (dh
-th
)/2)
89 scale
= mindim
/scaledmax
91 # draw the graph axis and "bulls-eye" with rings at scaled 25,
92 # 50, 75 and 100 positions
93 dc
.SetPen(wx
.Pen("black", 1))
94 dc
.SetBrush(wx
.TRANSPARENT_BRUSH
)
95 dc
.DrawCircle(cx
,cy
, 25*scale
)
96 dc
.DrawCircle(cx
,cy
, 50*scale
)
97 dc
.DrawCircle(cx
,cy
, 75*scale
)
98 dc
.DrawCircle(cx
,cy
, 100*scale
)
100 dc
.SetPen(wx
.Pen("black", 2))
101 dc
.DrawLine(cx
-110*scale
, cy
, cx
+110*scale
, cy
)
102 dc
.DrawLine(cx
, cy
-110*scale
, cx
, cy
+110*scale
)
104 # Now find the coordinates for each data point, draw the
105 # labels, and find the max data point
106 dc
.SetFont(self
.labelFont
)
110 for i
, label
in enumerate(self
.labels
):
112 point
= self
.PolarToCartesian(val
*scale
, angle
, cx
, cy
)
113 polypoints
.append(point
)
114 x
, y
= self
.PolarToCartesian(125*scale
, angle
, cx
,cy
)
115 dc
.DrawText(label
, x
, y
)
118 angle
= angle
+ 360/len(self
.labels
)
120 # Set the brush color based on the max value (green is good,
128 # Finally, draw the plot data as a filled polygon
129 dc
.SetBrush(wx
.Brush(c
))
130 dc
.SetPen(wx
.Pen("navy", 3))
131 dc
.DrawPolygon(polypoints
)
135 class TestFrame(wx
.Frame
):
137 wx
.Frame
.__init
__(self
, None, title
="Double Buffered Drawing",
139 self
.plot
= RadarGraph(self
, "Sample 'Radar' Plot",
140 ["A", "B", "C", "D", "E", "F", "G", "H"])
142 # Set some random initial data values
144 for d
in self
.plot
.GetData():
145 data
.append(random
.randint(0, 75))
146 self
.plot
.SetData(data
)
148 # Create a timer to update the data values
149 self
.Bind(wx
.EVT_TIMER
, self
.OnTimeout
)
150 self
.timer
= wx
.Timer(self
)
151 self
.timer
.Start(500)
154 def OnTimeout(self
, evt
):
155 # simulate the positive or negative growth of each data value
157 for d
in self
.plot
.GetData():
158 val
= d
+ random
.uniform(-5, 5)
164 self
.plot
.SetData(data
)
167 app
= wx
.PySimpleApp()