class SubColProperty(PropHolder): dividerLines = 0 _attrMap = AttrMap( minWidth=AttrMapValue(isNumber, desc="minimum width for this subcol"), rpad=AttrMapValue(isNumber, desc="right padding for this subcol"), align=AttrMapValue(OneOf('left', 'right', 'center', 'centre', 'numeric'), desc='alignment in subCol'), fontName=AttrMapValue(isString, desc="Font name of the strings"), fontSize=AttrMapValue(isNumber, desc="Font size of the strings"), leading=AttrMapValue(isNumber, desc="leading for the strings"), fillColor=AttrMapValue(isColorOrNone, desc="fontColor"), underlines=AttrMapValue(EitherOr((NoneOr(isInstanceOf(Line)), SequenceOf(isInstanceOf(Line), emptyOK=0, lo=0, hi=0x7fffffff))), desc="underline definitions"), overlines=AttrMapValue(EitherOr((NoneOr(isInstanceOf(Line)), SequenceOf(isInstanceOf(Line), emptyOK=0, lo=0, hi=0x7fffffff))), desc="overline definitions"), )
class StrandLabel(SpokeLabel): _attrMap = AttrMap(BASE=SpokeLabel, format = AttrMapValue(EitherOr((isStringOrNone,isCallable)),"Format for the label"), dR = AttrMapValue(isNumberOrNone,"radial shift for label"), ) def __init__(self,**kw): self.format = '' self.dR = 0 SpokeLabel.__init__(self,**kw)
class _BarcodeWidget(PlotArea): _attrMap = AttrMap(BASE=PlotArea, barStrokeColor = AttrMapValue(isColorOrNone, desc='Color of bar borders.'), barFillColor = AttrMapValue(isColorOrNone, desc='Color of bar interior areas.'), barStrokeWidth = AttrMapValue(isNumber, desc='Width of bar borders.'), value = AttrMapValue(EitherOr((isString,isNumber)), desc='Value.'), textColor = AttrMapValue(isColorOrNone, desc='Color of human readable text.'), valid = AttrMapValue(isBoolean), validated = AttrMapValue(isString,desc="validated form of input"), encoded = AttrMapValue(None,desc="encoded form of input"), decomposed = AttrMapValue(isString,desc="decomposed form of input"), canv = AttrMapValue(None,desc="temporarily used for internal methods"), gap = AttrMapValue(isNumberOrNone, desc='Width of inter character gaps.'), ) textColor = barFillColor = black barStrokeColor = None barStrokeWidth = 0 _BCC = None def __init__(self,BCC=None,_value='',**kw): self._BCC = BCC class Combiner(self.__class__,BCC): __name__ = self.__class__.__name__ self.__class__ = Combiner PlotArea.__init__(self) del self.width, self.height self.x = self.y = 0 kw.setdefault('value',_value) BCC.__init__(self,**kw) def rect(self,x,y,w,h,**kw): self._Gadd(Rect(self.x+x,self.y+y,w,h, strokeColor=self.barStrokeColor,strokeWidth=self.barStrokeWidth, fillColor=self.barFillColor)) def draw(self): if not self._BCC: raise NotImplementedError("Abstract class %s cannot be drawn" % self.__class__.__name__) self.canv = self G = Group() self._Gadd = G.add self._Gadd(Rect(self.x,self.y,self.width,self.height,fillColor=None,strokeColor=None,strokeWidth=0.0001)) self._BCC.draw(self) del self.canv, self._Gadd return G def annotate(self,x,y,text,fontName,fontSize,anchor='middle'): self._Gadd(String(self.x+x,self.y+y,text,fontName=fontName,fontSize=fontSize, textAnchor=anchor,fillColor=self.textColor))
class StrandProperty(PropHolder): _attrMap = AttrMap( strokeWidth = AttrMapValue(isNumber), fillColor = AttrMapValue(isColorOrNone), strokeColor = AttrMapValue(isColorOrNone), strokeDashArray = AttrMapValue(isListOfNumbersOrNone), symbol = AttrMapValue(EitherOr((isStringOrNone,isSymbol)), desc='Widget placed at data points.'), symbolSize= AttrMapValue(isNumber, desc='Symbol size.'), name = AttrMapValue(isStringOrNone, desc='Name of the strand.'), ) def __init__(self): self.strokeWidth = 1 self.fillColor = None self.strokeColor = STATE_DEFAULTS["strokeColor"] self.strokeDashArray = STATE_DEFAULTS["strokeDashArray"] self.symbol = None self.symbolSize = 5 self.name = None
class Doughnut(AbstractPieChart): _attrMap = AttrMap( x=AttrMapValue(isNumber, desc='X position of the chart within its container.'), y=AttrMapValue(isNumber, desc='Y position of the chart within its container.'), width=AttrMapValue( isNumber, desc='width of doughnut bounding box. Need not be same as width.'), height=AttrMapValue( isNumber, desc='height of doughnut bounding box. Need not be same as height.' ), data=AttrMapValue( EitherOr((isListOfNoneOrNumber, isListOfListOfNoneOrNumber)), desc='list of numbers defining sector sizes; need not sum to 1'), labels=AttrMapValue( isListOfStringsOrNone, desc="optional list of labels to use for each data point"), startAngle=AttrMapValue( isNumber, desc="angle of first slice; like the compass, 0 is due North"), direction=AttrMapValue(OneOf('clockwise', 'anticlockwise'), desc="'clockwise' or 'anticlockwise'"), slices=AttrMapValue(None, desc="collection of sector descriptor objects"), simpleLabels=AttrMapValue( isBoolean, desc="If true(default) use String not super duper WedgeLabel"), # advanced usage checkLabelOverlap=AttrMapValue( isBoolean, desc= "If true check and attempt to fix\n standard label overlaps(default off)", advancedUsage=1), sideLabels=AttrMapValue( isBoolean, desc= "If true attempt to make chart with labels along side and pointers", advancedUsage=1), innerRadiusFraction=AttrMapValue( isNumberOrNone, desc= 'None or the fraction of the radius to be used as the inner hole.\nIf not a suitable default will be used.' ), ) def __init__(self): self.x = 0 self.y = 0 self.width = 100 self.height = 100 self.data = [1, 1] self.labels = None # or list of strings self.startAngle = 90 self.direction = "clockwise" self.simpleLabels = 1 self.checkLabelOverlap = 0 self.sideLabels = 0 self.innerRadiusFraction = None self.slices = TypedPropertyCollection(SectorProperties) self.slices[0].fillColor = colors.darkcyan self.slices[1].fillColor = colors.blueviolet self.slices[2].fillColor = colors.blue self.slices[3].fillColor = colors.cyan self.slices[4].fillColor = colors.pink self.slices[5].fillColor = colors.magenta self.slices[6].fillColor = colors.yellow def demo(self): d = Drawing(200, 100) dn = Doughnut() dn.x = 50 dn.y = 10 dn.width = 100 dn.height = 80 dn.data = [10, 20, 30, 40, 50, 60] dn.labels = ['a', 'b', 'c', 'd', 'e', 'f'] dn.slices.strokeWidth = 0.5 dn.slices[3].popout = 10 dn.slices[3].strokeWidth = 2 dn.slices[3].strokeDashArray = [2, 2] dn.slices[3].labelRadius = 1.75 dn.slices[3].fontColor = colors.red dn.slices[0].fillColor = colors.darkcyan dn.slices[1].fillColor = colors.blueviolet dn.slices[2].fillColor = colors.blue dn.slices[3].fillColor = colors.cyan dn.slices[4].fillColor = colors.aquamarine dn.slices[5].fillColor = colors.cadetblue dn.slices[6].fillColor = colors.lightcoral d.add(dn) return d def normalizeData(self, data=None): from operator import add sum = float(reduce(add, data, 0)) return abs(sum) >= 1e-8 and list( map(lambda x, f=360. / sum: f * x, data)) or len(data) * [0] 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 draw(self): g = Group() g.add(self.makeSectors()) return g
"\n\tdef annotate(self,x,y,text,fontName,fontSize,anchor='middle'):\n\t\t_BarcodeWidget.annotate(self,x,y,text,fontName,fontSize,anchor='start')\n" ) BarcodeECC200DataMatrix = _BCW( 'ECC200DataMatrix', 'ECC200DataMatrix', AttrMap( BASE=_BarcodeWidget, x=AttrMapValue( isNumber, desc='X position of the lower-left corner of the barcode.'), y=AttrMapValue( isNumber, desc='Y position of the lower-left corner of the barcode.'), barWidth=AttrMapValue(isNumber, desc='Size of data modules.'), barFillColor=AttrMapValue(isColorOrNone, desc='Color of data modules.'), value=AttrMapValue(EitherOr((isString, isNumber)), desc='Value.'), height=AttrMapValue(None, desc='ignored'), width=AttrMapValue(None, desc='ignored'), strokeColor=AttrMapValue(None, desc='ignored'), strokeWidth=AttrMapValue(None, desc='ignored'), fillColor=AttrMapValue(None, desc='ignored'), background=AttrMapValue(None, desc='ignored'), debug=AttrMapValue(None, desc='ignored'), gap=AttrMapValue(None, desc='ignored'), row_modules=AttrMapValue(None, desc='???'), col_modules=AttrMapValue(None, desc='???'), row_regions=AttrMapValue(None, desc='???'), col_regions=AttrMapValue(None, desc='???'), cw_data=AttrMapValue(None, desc='???'), cw_ecc=AttrMapValue(None, desc='???'), row_usable_modules=AttrMapValue(None, desc='???'),