def makeSectors(self): # normalize slice data data = self.data multi = isListOfListOfNoneOrNumber(data) if multi: #it's a nested list, more than one sequence normData = [] n = [] for l in data: t = self.normalizeData(l) normData.append(t) n.append(len(t)) self._seriesCount = max(n) else: normData = self.normalizeData(data) n = len(normData) self._seriesCount = n #labels checkLabelOverlap = self.checkLabelOverlap L = [] L_add = L.append labels = self.labels if labels is None: labels = [] if not multi: labels = [''] * n else: for m in n: labels = list(labels) + [''] * m else: #there's no point in raising errors for less than enough labels if #we silently create all for the extreme case of no labels. if not multi: i = n - len(labels) if i > 0: labels = list(labels) + [''] * i else: tlab = 0 for m in n: tlab += m i = tlab - len(labels) if i > 0: labels = list(labels) + [''] * i self.labels = labels xradius = self.width / 2.0 yradius = self.height / 2.0 centerx = self.x + xradius centery = self.y + yradius if self.direction == "anticlockwise": whichWay = 1 else: whichWay = -1 g = Group() startAngle = self.startAngle #% 360 styleCount = len(self.slices) irf = self.innerRadiusFraction if multi: #multi-series doughnut ndata = len(data) if irf is None: yir = (yradius / 2.5) / ndata xir = (xradius / 2.5) / ndata else: yir = yradius * irf xir = xradius * irf ydr = (yradius - yir) / ndata xdr = (xradius - xir) / ndata for sn, series in enumerate(normData): for i, angle in enumerate(series): endAngle = (startAngle + (angle * whichWay)) #% 360 aa = abs(startAngle - endAngle) if aa < 1e-5: startAngle = endAngle continue if startAngle < endAngle: a1 = startAngle a2 = endAngle else: a1 = endAngle a2 = startAngle startAngle = endAngle #if we didn't use %stylecount here we'd end up with the later sectors #all having the default style sectorStyle = self.slices[sn, i % styleCount] # is it a popout? cx, cy = centerx, centery if sectorStyle.popout != 0: # pop out the sector averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 popdistance = sectorStyle.popout cx = centerx + popdistance * cos(aveAngleRadians) cy = centery + popdistance * sin(aveAngleRadians) yr1 = yir + sn * ydr yr = yr1 + ydr xr1 = xir + sn * xdr xr = xr1 + xdr if len(series) > 1: theSector = Wedge(cx, cy, xr, a1, a2, yradius=yr, radius1=xr1, yradius1=yr1) else: theSector = Wedge(cx, cy, xr, a1, a2, yradius=yr, radius1=xr1, yradius1=yr1, annular=True) theSector.fillColor = sectorStyle.fillColor theSector.strokeColor = sectorStyle.strokeColor theSector.strokeWidth = sectorStyle.strokeWidth theSector.strokeDashArray = sectorStyle.strokeDashArray shader = sectorStyle.shadingKind if shader: nshades = aa / float(sectorStyle.shadingAngle) if nshades > 1: shader = colors.Whiter if shader == 'lighten' else colors.Blacker nshades = 1 + int(nshades) shadingAmount = 1 - sectorStyle.shadingAmount if sectorStyle.shadingDirection == 'normal': dsh = (1 - shadingAmount) / float(nshades - 1) shf1 = shadingAmount else: dsh = (shadingAmount - 1) / float(nshades - 1) shf1 = 1 shda = (a2 - a1) / float(nshades) shsc = sectorStyle.fillColor theSector.fillColor = None for ish in range(nshades): sha1 = a1 + ish * shda sha2 = a1 + (ish + 1) * shda shc = shader(shsc, shf1 + dsh * ish) if len(series) > 1: shSector = Wedge(cx, cy, xr, sha1, sha2, yradius=yr, radius1=xr1, yradius1=yr1) else: shSector = Wedge(cx, cy, xr, sha1, sha2, yradius=yr, radius1=xr1, yradius1=yr1, annular=True) shSector.fillColor = shc shSector.strokeColor = None shSector.strokeWidth = 0 g.add(shSector) g.add(theSector) if sn == 0 and sectorStyle.visible and sectorStyle.label_visible: text = self.getSeriesName(i, '') if text: averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 labelRadius = sectorStyle.labelRadius rx = xradius * labelRadius ry = yradius * labelRadius labelX = centerx + (0.5 * self.width * cos(aveAngleRadians) * labelRadius) labelY = centery + (0.5 * self.height * sin(aveAngleRadians) * labelRadius) l = _addWedgeLabel(self, text, averageAngle, labelX, labelY, sectorStyle) if checkLabelOverlap: l._origdata = { 'x': labelX, 'y': labelY, 'angle': averageAngle, 'rx': rx, 'ry': ry, 'cx': cx, 'cy': cy, 'bounds': l.getBounds(), } L_add(l) else: #single series doughnut if irf is None: yir = yradius / 2.5 xir = xradius / 2.5 else: yir = yradius * irf xir = xradius * irf for i, angle in enumerate(normData): endAngle = (startAngle + (angle * whichWay)) #% 360 aa = abs(startAngle - endAngle) if aa < 1e-5: startAngle = endAngle continue if startAngle < endAngle: a1 = startAngle a2 = endAngle else: a1 = endAngle a2 = startAngle startAngle = endAngle #if we didn't use %stylecount here we'd end up with the later sectors #all having the default style sectorStyle = self.slices[i % styleCount] # is it a popout? cx, cy = centerx, centery if sectorStyle.popout != 0: # pop out the sector averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 popdistance = sectorStyle.popout cx = centerx + popdistance * cos(aveAngleRadians) cy = centery + popdistance * sin(aveAngleRadians) if n > 1: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, radius1=xir, yradius1=yir) elif n == 1: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, radius1=xir, yradius1=yir, annular=True) theSector.fillColor = sectorStyle.fillColor theSector.strokeColor = sectorStyle.strokeColor theSector.strokeWidth = sectorStyle.strokeWidth theSector.strokeDashArray = sectorStyle.strokeDashArray shader = sectorStyle.shadingKind if shader: nshades = aa / float(sectorStyle.shadingAngle) if nshades > 1: shader = colors.Whiter if shader == 'lighten' else colors.Blacker nshades = 1 + int(nshades) shadingAmount = 1 - sectorStyle.shadingAmount if sectorStyle.shadingDirection == 'normal': dsh = (1 - shadingAmount) / float(nshades - 1) shf1 = shadingAmount else: dsh = (shadingAmount - 1) / float(nshades - 1) shf1 = 1 shda = (a2 - a1) / float(nshades) shsc = sectorStyle.fillColor theSector.fillColor = None for ish in range(nshades): sha1 = a1 + ish * shda sha2 = a1 + (ish + 1) * shda shc = shader(shsc, shf1 + dsh * ish) if n > 1: shSector = Wedge(cx, cy, xradius, sha1, sha2, yradius=yradius, radius1=xir, yradius1=yir) elif n == 1: shSector = Wedge(cx, cy, xradius, sha1, sha2, yradius=yradius, radius1=xir, yradius1=yir, annular=True) shSector.fillColor = shc shSector.strokeColor = None shSector.strokeWidth = 0 g.add(shSector) g.add(theSector) # now draw a label if labels[ i] and sectorStyle.visible and sectorStyle.label_visible: averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 labelRadius = sectorStyle.labelRadius labelX = centerx + (0.5 * self.width * cos(aveAngleRadians) * labelRadius) labelY = centery + (0.5 * self.height * sin(aveAngleRadians) * labelRadius) rx = xradius * labelRadius ry = yradius * labelRadius l = _addWedgeLabel(self, labels[i], averageAngle, labelX, labelY, sectorStyle) if checkLabelOverlap: l._origdata = { 'x': labelX, 'y': labelY, 'angle': averageAngle, 'rx': rx, 'ry': ry, 'cx': cx, 'cy': cy, 'bounds': l.getBounds(), } L_add(l) if checkLabelOverlap and L: fixLabelOverlaps(L) for l in L: g.add(l) return g
def makeSectors(self): # normalize slice data if type(self.data) in (ListType, TupleType) and type( self.data[0]) in (ListType, TupleType): #it's a nested list, more than one sequence normData = [] n = [] for l in self.data: t = self.normalizeData(l) normData.append(t) n.append(len(t)) self._seriesCount = max(n) else: normData = self.normalizeData(self.data) n = len(normData) self._seriesCount = n #labels checkLabelOverlap = self.checkLabelOverlap L = [] L_add = L.append if self.labels is None: labels = [] if type(n) not in (ListType, TupleType): labels = [''] * n else: for m in n: labels = list(labels) + [''] * m else: labels = self.labels #there's no point in raising errors for less than enough labels if #we silently create all for the extreme case of no labels. if type(n) not in (ListType, TupleType): i = n - len(labels) if i > 0: labels = list(labels) + [''] * i else: tlab = 0 for m in n: tlab += m i = tlab - len(labels) if i > 0: labels = list(labels) + [''] * i xradius = self.width / 2.0 yradius = self.height / 2.0 centerx = self.x + xradius centery = self.y + yradius if self.direction == "anticlockwise": whichWay = 1 else: whichWay = -1 g = Group() startAngle = self.startAngle #% 360 styleCount = len(self.slices) if type(self.data[0]) in (ListType, TupleType): #multi-series doughnut iradius = (self.height / 5.0) / len(self.data) for sn, series in enumerate(normData): for i, angle in enumerate(series): endAngle = (startAngle + (angle * whichWay)) #% 360 if abs(startAngle - endAngle) < 1e-5: startAngle = endAngle continue if startAngle < endAngle: a1 = startAngle a2 = endAngle else: a1 = endAngle a2 = startAngle startAngle = endAngle #if we didn't use %stylecount here we'd end up with the later sectors #all having the default style sectorStyle = self.slices[i % styleCount] # is it a popout? cx, cy = centerx, centery if sectorStyle.popout != 0: # pop out the sector averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 popdistance = sectorStyle.popout cx = centerx + popdistance * cos(aveAngleRadians) cy = centery + popdistance * sin(aveAngleRadians) if type(n) in (ListType, TupleType): theSector = Wedge( cx, cy, xradius + (sn * iradius) - iradius, a1, a2, yradius=yradius + (sn * iradius) - iradius, radius1=yradius + (sn * iradius) - (2 * iradius)) else: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, radius1=iradius) theSector.fillColor = sectorStyle.fillColor theSector.strokeColor = sectorStyle.strokeColor theSector.strokeWidth = sectorStyle.strokeWidth theSector.strokeDashArray = sectorStyle.strokeDashArray g.add(theSector) if sn == 0: text = self.getSeriesName(i, '') if text: averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 labelRadius = sectorStyle.labelRadius rx = xradius * labelRadius ry = yradius * labelRadius labelX = centerx + (0.5 * self.width * cos(aveAngleRadians) * labelRadius) labelY = centery + (0.5 * self.height * sin(aveAngleRadians) * labelRadius) l = _addWedgeLabel(self, text, averageAngle, labelX, labelY, sectorStyle) if checkLabelOverlap: l._origdata = { 'x': labelX, 'y': labelY, 'angle': averageAngle, 'rx': rx, 'ry': ry, 'cx': cx, 'cy': cy, 'bounds': l.getBounds(), } L_add(l) else: #single series doughnut iradius = self.height / 5.0 for i, angle in enumerate(normData): endAngle = (startAngle + (angle * whichWay)) #% 360 if abs(startAngle - endAngle) < 1e-5: startAngle = endAngle continue if startAngle < endAngle: a1 = startAngle a2 = endAngle else: a1 = endAngle a2 = startAngle startAngle = endAngle #if we didn't use %stylecount here we'd end up with the later sectors #all having the default style sectorStyle = self.slices[i % styleCount] # is it a popout? cx, cy = centerx, centery if sectorStyle.popout != 0: # pop out the sector averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 popdistance = sectorStyle.popout cx = centerx + popdistance * cos(aveAngleRadians) cy = centery + popdistance * sin(aveAngleRadians) if n > 1: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, radius1=iradius) elif n == 1: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, iradius=iradius) theSector.fillColor = sectorStyle.fillColor theSector.strokeColor = sectorStyle.strokeColor theSector.strokeWidth = sectorStyle.strokeWidth theSector.strokeDashArray = sectorStyle.strokeDashArray g.add(theSector) # now draw a label if labels[i] != "": averageAngle = (a1 + a2) / 2.0 aveAngleRadians = averageAngle * pi / 180.0 labelRadius = sectorStyle.labelRadius labelX = centerx + (0.5 * self.width * cos(aveAngleRadians) * labelRadius) labelY = centery + (0.5 * self.height * sin(aveAngleRadians) * labelRadius) rx = xradius * labelRadius ry = yradius * labelRadius l = _addWedgeLabel(self, labels[i], averageAngle, labelX, labelY, sectorStyle) if checkLabelOverlap: l._origdata = { 'x': labelX, 'y': labelY, 'angle': averageAngle, 'rx': rx, 'ry': ry, 'cx': cx, 'cy': cy, 'bounds': l.getBounds(), } L_add(l) if checkLabelOverlap and L: fixLabelOverlaps(L) for l in L: g.add(l) return g
def makeSectors(self): # normalize slice data if type(self.data) in (ListType, TupleType) and type(self.data[0]) in (ListType, TupleType): #it's a nested list, more than one sequence normData = [] n = [] for l in self.data: t = self.normalizeData(l) normData.append(t) n.append(len(t)) self._seriesCount = max(n) else: normData = self.normalizeData(self.data) n = len(normData) self._seriesCount = n #labels checkLabelOverlap = self.checkLabelOverlap L = [] L_add = L.append if self.labels is None: labels = [] if type(n) not in (ListType,TupleType): labels = [''] * n else: for m in n: labels = list(labels) + [''] * m else: labels = self.labels #there's no point in raising errors for less than enough labels if #we silently create all for the extreme case of no labels. if type(n) not in (ListType,TupleType): i = n-len(labels) if i>0: labels = list(labels) + [''] * i else: tlab = 0 for m in n: tlab += m i = tlab-len(labels) if i>0: labels = list(labels) + [''] * i xradius = self.width/2.0 yradius = self.height/2.0 centerx = self.x + xradius centery = self.y + yradius if self.direction == "anticlockwise": whichWay = 1 else: whichWay = -1 g = Group() startAngle = self.startAngle #% 360 styleCount = len(self.slices) if type(self.data[0]) in (ListType, TupleType): #multi-series doughnut iradius = (self.height/5.0)/len(self.data) for sn,series in enumerate(normData): for i,angle in enumerate(series): endAngle = (startAngle + (angle * whichWay)) #% 360 if abs(startAngle-endAngle)<1e-5: startAngle = endAngle continue if startAngle < endAngle: a1 = startAngle a2 = endAngle else: a1 = endAngle a2 = startAngle startAngle = endAngle #if we didn't use %stylecount here we'd end up with the later sectors #all having the default style sectorStyle = self.slices[i%styleCount] # is it a popout? cx, cy = centerx, centery if sectorStyle.popout != 0: # pop out the sector averageAngle = (a1+a2)/2.0 aveAngleRadians = averageAngle * pi/180.0 popdistance = sectorStyle.popout cx = centerx + popdistance * cos(aveAngleRadians) cy = centery + popdistance * sin(aveAngleRadians) if type(n) in (ListType,TupleType): theSector = Wedge(cx, cy, xradius+(sn*iradius)-iradius, a1, a2, yradius=yradius+(sn*iradius)-iradius, radius1=yradius+(sn*iradius)-(2*iradius)) else: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, radius1=iradius) theSector.fillColor = sectorStyle.fillColor theSector.strokeColor = sectorStyle.strokeColor theSector.strokeWidth = sectorStyle.strokeWidth theSector.strokeDashArray = sectorStyle.strokeDashArray g.add(theSector) if sn == 0: text = self.getSeriesName(i,'') if text: averageAngle = (a1+a2)/2.0 aveAngleRadians = averageAngle*pi/180.0 labelRadius = sectorStyle.labelRadius rx = xradius*labelRadius ry = yradius*labelRadius labelX = centerx + (0.5 * self.width * cos(aveAngleRadians) * labelRadius) labelY = centery + (0.5 * self.height * sin(aveAngleRadians) * labelRadius) l = _addWedgeLabel(self,text,averageAngle,labelX,labelY,sectorStyle) if checkLabelOverlap: l._origdata = { 'x': labelX, 'y':labelY, 'angle': averageAngle, 'rx': rx, 'ry':ry, 'cx':cx, 'cy':cy, 'bounds': l.getBounds(), } L_add(l) else: #single series doughnut iradius = self.height/5.0 for i,angle in enumerate(normData): endAngle = (startAngle + (angle * whichWay)) #% 360 if abs(startAngle-endAngle)<1e-5: startAngle = endAngle continue if startAngle < endAngle: a1 = startAngle a2 = endAngle else: a1 = endAngle a2 = startAngle startAngle = endAngle #if we didn't use %stylecount here we'd end up with the later sectors #all having the default style sectorStyle = self.slices[i%styleCount] # is it a popout? cx, cy = centerx, centery if sectorStyle.popout != 0: # pop out the sector averageAngle = (a1+a2)/2.0 aveAngleRadians = averageAngle * pi/180.0 popdistance = sectorStyle.popout cx = centerx + popdistance * cos(aveAngleRadians) cy = centery + popdistance * sin(aveAngleRadians) if n > 1: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, radius1=iradius) elif n==1: theSector = Wedge(cx, cy, xradius, a1, a2, yradius=yradius, iradius=iradius) theSector.fillColor = sectorStyle.fillColor theSector.strokeColor = sectorStyle.strokeColor theSector.strokeWidth = sectorStyle.strokeWidth theSector.strokeDashArray = sectorStyle.strokeDashArray g.add(theSector) # now draw a label if labels[i] != "": averageAngle = (a1+a2)/2.0 aveAngleRadians = averageAngle*pi/180.0 labelRadius = sectorStyle.labelRadius labelX = centerx + (0.5 * self.width * cos(aveAngleRadians) * labelRadius) labelY = centery + (0.5 * self.height * sin(aveAngleRadians) * labelRadius) rx = xradius*labelRadius ry = yradius*labelRadius l = _addWedgeLabel(self,labels[i],averageAngle,labelX,labelY,sectorStyle) if checkLabelOverlap: l._origdata = { 'x': labelX, 'y':labelY, 'angle': averageAngle, 'rx': rx, 'ry':ry, 'cx':cx, 'cy':cy, 'bounds': l.getBounds(), } L_add(l) if checkLabelOverlap and L: fixLabelOverlaps(L) for l in L: g.add(l) return g