def OX(self,i,o,d): return self.CX(i,d)+self._radiusx*cos(_2rad(o))
def OY(self,i,o,d): return self.CY(i,d)+self._radiusy*sin(_2rad(o))
def CX(self, i,d ): return self._cx+(d and self._xdepth_3d or 0)+self._popout(i)*cos(_2rad(self._sl3d[i].mid))
def CY(self,i,d): return self._cy+(d and self._ydepth_3d or 0)+self._popout(i)*sin(_2rad(self._sl3d[i].mid))
self.label_textAnchor = 'start' self.label_visible = 1 class _SL3D: def __init__(self,lo,hi): if lo<0: lo += 360 hi += 360 self.lo = lo self.hi = hi self.mid = (lo+hi)*0.5 def __str__(self): return '_SL3D(%.2f,%.2f)' % (self.lo,self.hi) _270r = _2rad(270) class Pie3d(Pie): _attrMap = AttrMap(BASE=Pie, perspective = AttrMapValue(isNumber, desc='A flattening parameter.'), depth_3d = AttrMapValue(isNumber, desc='depth of the pie.'), angle_3d = AttrMapValue(isNumber, desc='The view angle.'), ) perspective = 70 depth_3d = 25 angle_3d = 180 def _popout(self,i): return self.slices[i].popout or 0 def CX(self, i,d ): return self._cx+(d and self._xdepth_3d or 0)+self._popout(i)*cos(_2rad(self._sl3d[i].mid))
def draw(self): slices = self.slices _3d_angle = self.angle_3d _3dva = self._3dva = _360(_3d_angle+90) a0 = _2rad(_3dva) self._xdepth_3d = cos(a0)*self.depth_3d self._ydepth_3d = sin(a0)*self.depth_3d self._cx = self.x+self.width/2.0 self._cy = self.y+(self.height - self._ydepth_3d)/2.0 radiusx = radiusy = self._cx-self.x if self.xradius: radiusx = self.xradius if self.yradius: radiusy = self.yradius self._radiusx = radiusx self._radiusy = radiusy = (1.0 - self.perspective/100.0)*radiusy data = self.normalizeData() sum = self._sum CX = self.CX CY = self.CY OX = self.OX OY = self.OY rad_dist = self.rad_dist _fillSide = self._fillSide self._seriesCount = n = len(data) _sl3d = self._sl3d = [] g = Group() last = _360(self.startAngle) a0 = self.direction=='clockwise' and -1 or 1 for v in data: v *= a0 angle1, angle0 = last, v+last last = angle0 if a0>0: angle0, angle1 = angle1, angle0 _sl3d.append(_SL3D(angle0,angle1)) labels = _fixLabels(self.labels,n) a0 = _3d_angle a1 = _3d_angle+180 T = [] S = [] L = [] class WedgeLabel3d(WedgeLabel): _ydepth_3d = self._ydepth_3d def _checkDXY(self,ba): if ba[0]=='n': if not hasattr(self,'_ody'): self._ody = self.dy self.dy = -self._ody + self._ydepth_3d checkLabelOverlap = self.checkLabelOverlap for i in xrange(n): style = slices[i] if not style.visible: continue sl = _sl3d[i] lo = angle0 = sl.lo hi = angle1 = sl.hi if abs(hi-lo)<=1e-7: continue fillColor = _getShaded(style.fillColor,style.fillColorShaded,style.shading) strokeColor = _getShaded(style.strokeColor,style.strokeColorShaded,style.shading) or fillColor strokeWidth = style.strokeWidth cx0 = CX(i,0) cy0 = CY(i,0) cx1 = CX(i,1) cy1 = CY(i,1) #background shaded pie bottom g.add(Wedge(cx1,cy1,radiusx, lo, hi,yradius=radiusy, strokeColor=strokeColor,strokeWidth=strokeWidth,fillColor=fillColor, strokeLineJoin=1)) #connect to top if lo < a0 < hi: angle0 = a0 if lo < a1 < hi: angle1 = a1 if 1: p = ArcPath(strokeColor=strokeColor, fillColor=fillColor,strokeWidth=strokeWidth,strokeLineJoin=1) p.addArc(cx1,cy1,radiusx,angle0,angle1,yradius=radiusy,moveTo=1) p.lineTo(OX(i,angle1,0),OY(i,angle1,0)) p.addArc(cx0,cy0,radiusx,angle0,angle1,yradius=radiusy,reverse=1) p.closePath() if angle0<=_3dva and angle1>=_3dva: rd = 0 else: rd = min(rad_dist(angle0),rad_dist(angle1)) S.append((rd,p)) _fillSide(S,i,lo,strokeColor,strokeWidth,fillColor) _fillSide(S,i,hi,strokeColor,strokeWidth,fillColor) #bright shaded top fillColor = style.fillColor strokeColor = style.strokeColor or fillColor T.append(Wedge(cx0,cy0,radiusx,lo,hi,yradius=radiusy, strokeColor=strokeColor,strokeWidth=strokeWidth,fillColor=fillColor,strokeLineJoin=1)) text = labels[i] if style.label_visible and text: rat = style.labelRadius self._radiusx *= rat self._radiusy *= rat mid = sl.mid labelX = OX(i,mid,0) labelY = OY(i,mid,0) _addWedgeLabel(self,text,L.append,mid,labelX,labelY,style,labelClass=WedgeLabel3d) if checkLabelOverlap: l = L[-1] l._origdata = { 'x': labelX, 'y':labelY, 'angle': mid, 'rx': self._radiusx, 'ry':self._radiusy, 'cx':CX(i,0), 'cy':CY(i,0), 'bounds': l.getBounds(), } self._radiusx = radiusx self._radiusy = radiusy S.sort(lambda a,b: -cmp(a[0],b[0])) if checkLabelOverlap and L: fixLabelOverlaps(L) map(g.add,map(lambda x:x[1],S)+T+L) return g
def draw(self): slices = self.slices _3d_angle = self.angle_3d _3dva = self._3dva = _360(_3d_angle+90) a0 = _2rad(_3dva) self._xdepth_3d = cos(a0)*self.depth_3d self._ydepth_3d = sin(a0)*self.depth_3d self._cx = self.x+self.width/2.0 self._cy = self.y+(self.height - self._ydepth_3d)/2.0 radius = self._radius = self._cx-self.x self._radiusx = radiusx = radius self._radiusy = radiusy = (1.0 - self.perspective/100.0)*radius data = self.normalizeData() sum = self._sum CX = self.CX CY = self.CY OX = self.OX OY = self.OY rad_dist = self.rad_dist _fillSide = self._fillSide n = len(data) _sl3d = self._sl3d = [] g = Group() last = _360(self.startAngle) a0 = self.direction=='clockwise' and -1 or 1 for v in data: v *= a0 angle1, angle0 = last, v+last last = angle0 if a0>0: angle0, angle1 = angle1, angle0 _sl3d.append(_SL3D(angle0,angle1)) #print '%d: %.2f %.2f --> %s' %(len(_sl3d)-1,angle0,angle1,_sl3d[-1]) labels = _fixLabels(self.labels,n) a0 = _3d_angle a1 = _3d_angle+180 T = [] S = [] L = [] class WedgeLabel3d(WedgeLabel): def _checkDXY(self,ba): if ba[0]=='n': if not hasattr(self,'_ody'): self._ody = self.dy self.dy = -self._ody + self._ydepth_3d WedgeLabel3d._ydepth_3d = self._ydepth_3d for i in xrange(n): style = slices[i] if not style.visible: continue sl = _sl3d[i] lo = angle0 = sl.lo hi = angle1 = sl.hi if abs(hi-lo)<=1e-7: continue fillColor = _getShaded(style.fillColor,style.fillColorShaded,style.shading) strokeColor = _getShaded(style.strokeColor,style.strokeColorShaded,style.shading) or fillColor strokeWidth = style.strokeWidth cx0 = CX(i,0) cy0 = CY(i,0) cx1 = CX(i,1) cy1 = CY(i,1) #background shaded pie bottom g.add(Wedge(cx1,cy1,radiusx, lo, hi,yradius=radiusy, strokeColor=strokeColor,strokeWidth=strokeWidth,fillColor=fillColor, strokeLineJoin=1)) #connect to top if lo < a0 < hi: angle0 = a0 if lo < a1 < hi: angle1 = a1 if 1: p = ArcPath(strokeColor=strokeColor, fillColor=fillColor,strokeWidth=strokeWidth,strokeLineJoin=1) p.addArc(cx1,cy1,radiusx,angle0,angle1,yradius=radiusy,moveTo=1) p.lineTo(OX(i,angle1,0),OY(i,angle1,0)) p.addArc(cx0,cy0,radiusx,angle0,angle1,yradius=radiusy,reverse=1) p.closePath() if angle0<=_3dva and angle1>=_3dva: rd = 0 else: rd = min(rad_dist(angle0),rad_dist(angle1)) S.append((rd,p)) _fillSide(S,i,lo,strokeColor,strokeWidth,fillColor) _fillSide(S,i,hi,strokeColor,strokeWidth,fillColor) #bright shaded top fillColor = style.fillColor strokeColor = style.strokeColor or fillColor T.append(Wedge(cx0,cy0,radiusx,lo,hi,yradius=radiusy, strokeColor=strokeColor,strokeWidth=strokeWidth,fillColor=fillColor,strokeLineJoin=1)) text = labels[i] if text: rat = style.labelRadius self._radiusx *= rat self._radiusy *= rat mid = sl.mid _addWedgeLabel(self,text,L.append,mid,OX(i,mid,0),OY(i,mid,0),style,labelClass=WedgeLabel3d) self._radiusx = radiusx self._radiusy = radiusy S.sort(lambda a,b: -cmp(a[0],b[0])) map(g.add,map(lambda x:x[1],S)+T+L) return g
def draw(self): slices = self.slices _3d_angle = self.angle_3d _3dva = self._3dva = _360(_3d_angle+90) a0 = _2rad(_3dva) self._xdepth_3d = cos(a0)*self.depth_3d self._ydepth_3d = sin(a0)*self.depth_3d self._cx = self.x+self.width/2.0 self._cy = self.y+(self.height - self._ydepth_3d)/2.0 radiusx = radiusy = self._cx-self.x if self.xradius: radiusx = self.xradius if self.yradius: radiusy = self.yradius self._radiusx = radiusx self._radiusy = radiusy = (1.0 - self.perspective/100.0)*radiusy data = self.normalizeData() sum = self._sum CX = self.CX CY = self.CY OX = self.OX OY = self.OY rad_dist = self.rad_dist _fillSide = self._fillSide self._seriesCount = n = len(data) _sl3d = self._sl3d = [] g = Group() last = _360(self.startAngle) a0 = self.direction=='clockwise' and -1 or 1 for v in data: v *= a0 angle1, angle0 = last, v+last last = angle0 if a0>0: angle0, angle1 = angle1, angle0 _sl3d.append(_SL3D(angle0,angle1)) labels = _fixLabels(self.labels,n) a0 = _3d_angle a1 = _3d_angle+180 T = [] S = [] L = [] class WedgeLabel3d(WedgeLabel): _ydepth_3d = self._ydepth_3d def _checkDXY(self,ba): if ba[0]=='n': if not hasattr(self,'_ody'): self._ody = self.dy self.dy = -self._ody + self._ydepth_3d checkLabelOverlap = self.checkLabelOverlap for i in xrange(n): style = slices[i] if not style.visible: continue sl = _sl3d[i] lo = angle0 = sl.lo hi = angle1 = sl.hi if abs(hi-lo)<=1e-7: continue fillColor = _getShaded(style.fillColor,style.fillColorShaded,style.shading) strokeColor = _getShaded(style.strokeColor,style.strokeColorShaded,style.shading) or fillColor strokeWidth = style.strokeWidth cx0 = CX(i,0) cy0 = CY(i,0) cx1 = CX(i,1) cy1 = CY(i,1) #background shaded pie bottom g.add(Wedge(cx1,cy1,radiusx, lo, hi,yradius=radiusy, strokeColor=strokeColor,strokeWidth=strokeWidth,fillColor=fillColor, strokeLineJoin=1)) #connect to top if lo < a0 < hi: angle0 = a0 if lo < a1 < hi: angle1 = a1 if 1: p = ArcPath(strokeColor=strokeColor, fillColor=fillColor,strokeWidth=strokeWidth,strokeLineJoin=1) p.addArc(cx1,cy1,radiusx,angle0,angle1,yradius=radiusy,moveTo=1) p.lineTo(OX(i,angle1,0),OY(i,angle1,0)) p.addArc(cx0,cy0,radiusx,angle0,angle1,yradius=radiusy,reverse=1) p.closePath() if angle0<=_3dva and angle1>=_3dva: rd = 0 else: rd = min(rad_dist(angle0),rad_dist(angle1)) S.append((rd,p)) _fillSide(S,i,lo,strokeColor,strokeWidth,fillColor) _fillSide(S,i,hi,strokeColor,strokeWidth,fillColor) #bright shaded top fillColor = style.fillColor strokeColor = style.strokeColor or fillColor T.append(Wedge(cx0,cy0,radiusx,lo,hi,yradius=radiusy, strokeColor=strokeColor,strokeWidth=strokeWidth,fillColor=fillColor,strokeLineJoin=1)) text = labels[i] if style.label_visible and text: rat = style.labelRadius self._radiusx *= rat self._radiusy *= rat mid = sl.mid labelX = OX(i,mid,0) labelY = OY(i,mid,0) l=_addWedgeLabel(self,text,mid,labelX,labelY,style,labelClass=WedgeLabel3d) L.append(l) if checkLabelOverlap: l._origdata = { 'x': labelX, 'y':labelY, 'angle': mid, 'rx': self._radiusx, 'ry':self._radiusy, 'cx':CX(i,0), 'cy':CY(i,0), 'bounds': l.getBounds(), } self._radiusx = radiusx self._radiusy = radiusy S.sort(lambda a,b: -cmp(a[0],b[0])) if checkLabelOverlap and L: fixLabelOverlaps(L) for x in ([s[1] for s in S]+T+L): g.add(x) return g