Optimize piectrl.py

OnPaint - Draw timeit results

PieCtrl Demo Colorwheel Benchmark
Before
TIMEIT 0.10100555419921875  Animated
TIMEIT 0.10600614547729492  Colorwheel
After
TIMEIT 0.08300471305847168  Animated
TIMEIT 0.08600497245788574  Colorwheel
This commit is contained in:
Metallicow
2020-08-08 00:49:59 -05:00
parent cca15e4490
commit 038b3e39fe

View File

@@ -356,14 +356,23 @@ class PieCtrlLegend(wx.Window):
mdc.SetTextForeground(self._labelcolour)
maxwidth = 0
for ii in range(len(self._parent._series)):
# local opts
wxBrush = wx.Brush
_parent_series = self._parent._series
_horborder = self._horborder
mdc_GetTextExtent = mdc.GetTextExtent
mdc_SetBrush = mdc.SetBrush
mdc_DrawCircle = mdc.DrawCircle
mdc_DrawText = mdc.DrawText
tw, th = mdc.GetTextExtent(self._parent._series[ii].GetLabel())
mdc.SetBrush(wx.Brush(self._parent._series[ii].GetColour()))
mdc.DrawCircle(self._horborder+5, dy+th//2, 5)
mdc.DrawText(self._parent._series[ii].GetLabel(), self._horborder+15, dy)
for ii in range(len(_parent_series)):
tw, th = mdc_GetTextExtent(_parent_series[ii].GetLabel())
mdc_SetBrush(wxBrush(_parent_series[ii].GetColour()))
mdc_DrawCircle(_horborder+5, dy+th//2, 5)
mdc_DrawText(_parent_series[ii].GetLabel(), _horborder+15, dy)
dy = dy + th + 3
maxwidth = max(maxwidth, int(2*self._horborder+tw+15))
maxwidth = max(maxwidth, int(2*_horborder+tw+15))
dy = dy + self._verborder
if w != maxwidth or h != dy:
@@ -535,15 +544,17 @@ class PieCtrl(wx.Window):
angles = []
total = 0.0
for ii in range(len(self._series)):
total = total + self._series[ii].GetValue()
_series = self._series # local opt
for ii in range(len(_series)):
total = total + _series[ii].GetValue()
current = 0.0
angles.append(current)
for ii in range(len(self._series)):
for ii in range(len(_series)):
current = current + self._series[ii].GetValue()
current = current + _series[ii].GetValue()
angles.append(360.0*current/total)
return angles
@@ -660,38 +671,47 @@ class PieCtrl(wx.Window):
:param `h`: the control's height.
"""
# local opts
_angle = self._angle
_rotationangle = self._rotationangle
wxPen = wx.Pen
wxBrush = wx.Brush
dc_SetPen = dc.SetPen
dc_SetBrush = dc.SetBrush
dc_DrawEllipticArc = dc.DrawEllipticArc
angles = self.GetPartAngles()
oldpen = dc.GetPen()
if self._showedges:
dc.SetPen(wx.BLACK_PEN)
dc_SetPen(wx.BLACK_PEN)
for ii in range(len(angles)):
if ii > 0:
if not self._showedges:
dc.SetPen(wx.Pen(self._series[ii-1].GetColour()))
dc_SetPen(wxPen(self._series[ii-1].GetColour()))
dc.SetBrush(wx.Brush(self._series[ii-1].GetColour()))
dc_SetBrush(wxBrush(self._series[ii-1].GetColour()))
if angles[ii-1] != angles[ii]:
dc.DrawEllipticArc(0, int((1-sin(self._angle))*(h//2)+cy), w,
int(h*sin(self._angle)),
angles[ii-1]+self._rotationangle/pi*180,
angles[ii]+self._rotationangle/pi*180)
dc_DrawEllipticArc(0, int((1-sin(_angle))*(h//2)+cy), w,
int(h*sin(_angle)),
angles[ii-1]+_rotationangle/pi*180,
angles[ii]+_rotationangle/pi*180)
if len(self._series) == 1:
dc.SetBrush(wx.Brush(self._series[0].GetColour()))
dc.DrawEllipticArc(0, int((1-sin(self._angle))*(h//2)+cy), w,
int(h*sin(self._angle)), 0, 360)
dc_SetBrush(wxBrush(self._series[0].GetColour()))
dc_DrawEllipticArc(0, int((1-sin(_angle))*(h//2)+cy), w,
int(h*sin(_angle)), 0, 360)
dc.SetPen(oldpen)
dc_SetPen(oldpen)
def Draw(self, pdc):
def Draw(self, dc):
"""
Draws all the sectors of :class:`PieCtrl`.
@@ -700,41 +720,56 @@ class PieCtrl(wx.Window):
w, h = self.GetSize()
self._canvasDC.SetBackground(wx.WHITE_BRUSH)
self._canvasDC.Clear()
# local opts
_angle = self._angle
_rotationangle = self._rotationangle
_height = self._height
_canvasDC = self._canvasDC
wxBrush = wx.Brush
wxPen = wx.Pen
wxColour = wx.Colour
_canvasDC_SetBrush = _canvasDC.SetBrush
_canvasDC_SetPen = _canvasDC.SetPen
_canvasDC_GetPen = _canvasDC.GetPen
_canvasDC_DrawPolygon = _canvasDC.DrawPolygon
tau = pi * 2
_canvasDC.SetBackground(wx.WHITE_BRUSH)
_canvasDC.Clear()
if self._background != wx.NullBitmap:
for ii in range(0, w, self._background.GetWidth()):
for jj in range(0, h, self._background.GetHeight()):
self._canvasDC.DrawBitmap(self._background, ii, jj)
## for ii in range(0, w, self._background.GetWidth()):
## for jj in range(0, h, self._background.GetHeight()):
## _canvasDC.DrawBitmap(self._background, ii, jj)
_background = self._background
bw, bh = _background.GetSize()
_canvasDC_DrawBitmap = _canvasDC.DrawBitmap
[_canvasDC_DrawBitmap(_background, ii, jj)
for jj in range(0, h, bh)
for ii in range(0, w, bw)]
else:
self._canvasDC.SetBackground(wx.Brush(self._backcolour))
self._canvasDC.Clear()
_canvasDC.SetBackground(wxBrush(self._backcolour))
_canvasDC.Clear()
if len(self._series) > 0:
_series = self._series # local opt
if self._angle <= pi/2:
self.DrawParts(self._canvasDC, 0, int(self._height*cos(self._angle)), w, h)
if _angle <= pi/2:
self.DrawParts(_canvasDC, 0, int(_height*cos(_angle)), w, h)
else:
self.DrawParts(self._canvasDC, 0, 0, w, h)
self.DrawParts(_canvasDC, 0, 0, w, h)
points = [[0, 0]]*4
triangle = [[0, 0]]*3
self._canvasDC.SetPen(wx.Pen(wx.BLACK))
_canvasDC_SetPen(wx.BLACK_PEN)
angles = self.GetPartAngles()
angleindex = 0
self._canvasDC.SetBrush(wx.Brush(wx.Colour(self._series[angleindex].GetColour().Red(),
self._series[angleindex].GetColour().Green(),
self._series[angleindex].GetColour().Blue())))
c = _series[angleindex].GetColour()
_canvasDC_SetBrush(wxBrush(wxColour(c.red, c.green, c.blue)))
changeangle = False
x = 0.0
while x <= 2*pi:
while x <= tau:
changeangle = False
@@ -746,8 +781,8 @@ class PieCtrl(wx.Window):
x = angles[angleindex+1]*pi/180.0
points[0] = points[1]
px = int(w/2.0*(1+cos(x+self._rotationangle)))
py = int(h/2.0-sin(self._angle)*h/2.0*sin(x+self._rotationangle)-1)
px = int(w/2.0*(1+cos(x+_rotationangle)))
py = int(h/2.0-sin(_angle)*h/2.0*sin(x+_rotationangle)-1)
points[1] = [px, py]
triangle[0] = [w // 2, h // 2]
triangle[1] = points[0]
@@ -755,11 +790,11 @@ class PieCtrl(wx.Window):
if x > 0:
self._canvasDC.SetBrush(wx.Brush(self._series[angleindex].GetColour()))
oldPen = self._canvasDC.GetPen()
self._canvasDC.SetPen(wx.Pen(self._series[angleindex].GetColour()))
self._canvasDC.DrawPolygon([wx.Point(pts[0], pts[1]) for pts in triangle])
self._canvasDC.SetPen(oldPen)
_canvasDC_SetBrush(wxBrush(_series[angleindex].GetColour()))
oldPen = _canvasDC_GetPen()
_canvasDC_SetPen(wxPen(_series[angleindex].GetColour()))
_canvasDC_DrawPolygon(triangle)
_canvasDC_SetPen(oldPen)
if changeangle:
@@ -767,26 +802,25 @@ class PieCtrl(wx.Window):
x = x + 0.05
x = 2*pi
points[0] = points[1]
px = int(w/2.0 * (1+cos(x+self._rotationangle)))
py = int(h/2.0-sin(self._angle)*h/2.0*sin(x+self._rotationangle)-1)
px = int(w/2.0 * (1+cos(tau+_rotationangle)))
py = int(h/2.0-sin(_angle)*h/2.0*sin(tau+_rotationangle)-1)
points[1] = [px, py]
triangle[0] = [w // 2, h // 2]
triangle[1] = points[0]
triangle[2] = points[1]
self._canvasDC.SetBrush(wx.Brush(self._series[angleindex].GetColour()))
oldPen = self._canvasDC.GetPen()
self._canvasDC.SetPen(wx.Pen(self._series[angleindex].GetColour()))
self._canvasDC.DrawPolygon([wx.Point(pts[0], pts[1]) for pts in triangle])
_canvasDC_SetBrush(wxBrush(_series[angleindex].GetColour()))
oldPen = _canvasDC_GetPen()
_canvasDC_SetPen(wxPen(_series[angleindex].GetColour()))
_canvasDC_DrawPolygon(triangle)
self._canvasDC.SetPen(oldPen)
_canvasDC_SetPen(oldPen)
angleindex = 0
x = 0.0
while x <= 2*pi:
while x <= tau:
changeangle = False
if angleindex < len(angles):
@@ -798,24 +832,23 @@ class PieCtrl(wx.Window):
points[0] = points[1]
points[3] = points[2]
px = int(w/2.0 * (1+cos(x+self._rotationangle)))
py = int(h/2.0-sin(self._angle)*h/2.0*sin(x+self._rotationangle)-1)
px = int(w/2.0 * (1+cos(x+_rotationangle)))
py = int(h/2.0-sin(_angle)*h/2.0*sin(x+_rotationangle)-1)
points[1] = [px, py]
points[2] = [px, int(py+self._height*cos(self._angle))]
points[2] = [px, int(py+_height*cos(_angle))]
if w > 0:
curColour = wx.Colour(int(self._series[angleindex].GetColour().Red()*(1.0-float(px)/w)),
int(self._series[angleindex].GetColour().Green()*(1.0-float(px)/w)),
int(self._series[angleindex].GetColour().Blue()*(1.0-float(px)/w)))
c = _series[angleindex].GetColour()
v = 1.0-float(px)/w
curColour = wxColour(int(c.red*v), int(c.green*v), int(c.blue*v))
if not self._showedges:
self._canvasDC.SetPen(wx.Pen(curColour))
_canvasDC_SetPen(wxPen(curColour))
self._canvasDC.SetBrush(wx.Brush(curColour))
_canvasDC_SetBrush(wxBrush(curColour))
if sin(x+self._rotationangle) < 0 and sin(x-0.05+self._rotationangle) <= 0 and x > 0:
self._canvasDC.DrawPolygon([wx.Point(pts[0], pts[1]) for pts in points])
if sin(x+_rotationangle) < 0 and sin(x-0.05+_rotationangle) <= 0 and x > 0:
_canvasDC_DrawPolygon(points)
if changeangle:
@@ -823,35 +856,33 @@ class PieCtrl(wx.Window):
x = x + 0.05
x = 2*pi
points[0] = points[1]
points[3] = points[2]
px = int(w/2.0 * (1+cos(x+self._rotationangle)))
py = int(h/2.0-sin(self._angle)*h/2.0*sin(x+self._rotationangle)-1)
px = int(w/2.0 * (1+cos(tau+_rotationangle)))
py = int(h/2.0-sin(_angle)*h/2.0*sin(tau+_rotationangle)-1)
points[1] = [px, py]
points[2] = [px, int(py+self._height*cos(self._angle))]
points[2] = [px, int(py+_height*cos(_angle))]
if w > 0:
curColour = wx.Colour(int(self._series[angleindex].GetColour().Red()*(1.0-float(px)/w)),
int(self._series[angleindex].GetColour().Green()*(1.0-float(px)/w)),
int(self._series[angleindex].GetColour().Blue()*(1.0-float(px)/w)))
c = _series[angleindex].GetColour()
v = 1.0-float(px)/w
curColour = wxColour(int(c.red*v), int(c.green*v), int(c.blue*v))
if not self._showedges:
self._canvasDC.SetPen(wx.Pen(curColour))
_canvasDC_SetPen(wxPen(curColour))
self._canvasDC.SetBrush(wx.Brush(curColour))
_canvasDC_SetBrush(wxBrush(curColour))
if sin(x+self._rotationangle) < 0 and sin(x-0.05+self._rotationangle) <= 0:
self._canvasDC.DrawPolygon([wx.Point(pts[0], pts[1]) for pts in points])
if sin(x+_rotationangle) < 0 and sin(x-0.05+_rotationangle) <= 0:
_canvasDC_DrawPolygon(points)
if self._angle <= pi/2:
self.DrawParts(self._canvasDC, 0, 0, w, h)
if _angle <= pi/2:
self.DrawParts(_canvasDC, 0, 0, w, h)
else:
self.DrawParts(self._canvasDC, 0, int(self._height*cos(self._angle)), w, h)
self.DrawParts(_canvasDC, 0, int(_height*cos(_angle)), w, h)
pdc.Blit(0, 0, w, h, self._canvasDC, 0, 0)
self._legend.RecreateBackground(self._canvasDC)
dc.Blit(0, 0, w, h, _canvasDC, 0, 0)
self._legend.RecreateBackground(_canvasDC)
def OnPaint(self, event):