def makeInnerTiles(self): # inner grid lines group = Group() w, h = self.width, self.height # inner grid stripes (solid rectangles) if self.useRects == 1: cols = self.stripeColors if self.orientation == 'vertical': r = self.makeLinePosList(self.x, isX=1) elif self.orientation == 'horizontal': r = self.makeLinePosList(self.y, isX=0) dist = makeDistancesList(r) i = 0 for j in range(len(dist)): if self.orientation == 'vertical': x = r[j] stripe = Rect(x, self.y, dist[j], h) elif self.orientation == 'horizontal': y = r[j] stripe = Rect(self.x, y, w, dist[j]) stripe.fillColor = cols[i % len(cols)] stripe.strokeColor = None group.add(stripe) i = i + 1 return group
def rotatedEnclosingRect(P, angle, rect): ''' given P a sequence P of x,y coordinate pairs and an angle in degrees find the centroid of P and the axis at angle theta through it find the extreme points of P wrt axis parallel distance and axis orthogonal distance. Then compute the least rectangle that will still enclose P when rotated by angle. The class R ''' from math import pi, cos, sin, tan x0, y0 = centroid(P) theta = (angle/180.)*pi s,c=sin(theta),cos(theta) def parallelAxisDist(xy,s=s,c=c,x0=x0,y0=y0): x,y = xy return (s*(y-y0)+c*(x-x0)) def orthogonalAxisDist(xy,s=s,c=c,x0=x0,y0=y0): x,y = xy return (c*(y-y0)+s*(x-x0)) L = map(parallelAxisDist,P) L.sort() a0, a1 = L[0], L[-1] L = map(orthogonalAxisDist,P) L.sort() b0, b1 = L[0], L[-1] rect.x, rect.width = a0, a1-a0 rect.y, rect.height = b0, b1-b0 g = Group(transform=(c,s,-s,c,x0,y0)) g.add(rect) return g
def makeSwatchSample(self, rowNo, x, y, width, height): baseStyle = self.strands styleIdx = rowNo % len(baseStyle) style = baseStyle[styleIdx] strokeColor = getattr(style, 'strokeColor', getattr(baseStyle,'strokeColor',None)) fillColor = getattr(style, 'fillColor', getattr(baseStyle,'fillColor',None)) strokeDashArray = getattr(style, 'strokeDashArray', getattr(baseStyle,'strokeDashArray',None)) strokeWidth = getattr(style, 'strokeWidth', getattr(baseStyle, 'strokeWidth',0)) symbol = getattr(style, 'symbol', getattr(baseStyle, 'symbol',None)) ym = y+height/2.0 if fillColor is None and strokeColor is not None and strokeWidth>0: bg = Line(x,ym,x+width,ym,strokeWidth=strokeWidth,strokeColor=strokeColor, strokeDashArray=strokeDashArray) elif fillColor is not None: bg = Rect(x,y,width,height,strokeWidth=strokeWidth,strokeColor=strokeColor, strokeDashArray=strokeDashArray,fillColor=fillColor) else: bg = None if symbol: symbol = uSymbol2Symbol(symbol,x+width/2.,ym,color) if bg: g = Group() g.add(bg) g.add(symbol) return g return symbol or bg
def _Flag_Greece(self): s = _size g = Group() box = Rect(0, 0, s*2, s, fillColor = colors.gold, strokeColor = colors.black, strokeWidth=0) g.add(box) for stripecounter in range (9,0, -1): stripeheight = s/9.0 if not (stripecounter%2 == 0): stripecolor = colors.deepskyblue else: stripecolor = colors.mintcream blueorwhiteline = Rect(0, (s-(stripeheight*stripecounter)), width=s*2, height=stripeheight, fillColor = stripecolor, strokeColor = None, strokeWidth=20) g.add(blueorwhiteline) bluebox1 = Rect(0, ((s)-stripeheight*5), width=(stripeheight*5), height=stripeheight*5, fillColor = colors.deepskyblue, strokeColor = None, strokeWidth=0) g.add(bluebox1) whiteline1 = Rect(0, ((s)-stripeheight*3), width=stripeheight*5, height=stripeheight, fillColor = colors.mintcream, strokeColor = None, strokeWidth=0) g.add(whiteline1) whiteline2 = Rect((stripeheight*2), ((s)-stripeheight*5), width=stripeheight, height=stripeheight*5, fillColor = colors.mintcream, strokeColor = None, strokeWidth=0) g.add(whiteline2) return g
def getTalkRect(self, startTime, duration, trackId, text): "Return shapes for a specific talk" g = Group() y_bottom = self.scaleTime(startTime + duration) y_top = self.scaleTime(startTime) y_height = y_top - y_bottom if trackId is None: #spans all columns x = self._colLeftEdges[1] width = self.width - self._colWidths[0] else: #trackId is 1-based and these arrays have the margin info in column #zero, so no need to add 1 x = self._colLeftEdges[trackId] width = self._colWidths[trackId] lab = Label() lab.setText(text) lab.setOrigin(x + 0.5*width, y_bottom+0.5*y_height) lab.boxAnchor = 'c' lab.width = width lab.height = y_height lab.fontSize = 6 r = Rect(x, y_bottom, width, y_height, fillColor=colors.cyan) g.add(r) g.add(lab) #now for a label # would expect to color-code and add text return g
def makeCircularString(x, y, radius, angle, text, fontName, fontSize, inside=0, G=None,textAnchor='start'): '''make a group with circular text in it''' if not G: G = Group() angle %= 360 pi180 = pi/180 phi = angle*pi180 width = stringWidth(text, fontName, fontSize) sig = inside and -1 or 1 hsig = sig*0.5 sig90 = sig*90 if textAnchor!='start': if textAnchor=='middle': phi += sig*(0.5*width)/radius elif textAnchor=='end': phi += sig*float(width)/radius elif textAnchor=='numeric': phi += sig*float(numericXShift(textAnchor,text,width,fontName,fontSize,None))/radius for letter in text: width = stringWidth(letter, fontName, fontSize) beta = float(width)/radius h = Group() h.add(String(0, 0, letter, fontName=fontName,fontSize=fontSize,textAnchor="start")) h.translate(x+cos(phi)*radius,y+sin(phi)*radius) #translate to radius and angle h.rotate((phi-hsig*beta)/pi180-sig90) # rotate as needed G.add(h) #add to main group phi -= sig*beta #increment return G
def draw(self): s = float(self.size) #abbreviate as we will use this a lot g = Group() # new algorithm from markers.StarFive R = float(self.size)/2 r = R*sin(18*(pi/180.0))/cos(36*(pi/180.0)) P = [] angle = 90 for i in xrange(5): for radius in R, r: theta = angle*(pi/180.0) P.append(radius*cos(theta)) P.append(radius*sin(theta)) angle = angle + 36 # star specific bits star = Polygon(P, fillColor = self.fillColor, strokeColor = self.strokeColor, strokeWidth=s/50) g.rotate(self.angle) g.shift(self.x+self.dx,self.y+self.dy) g.add(star) return g
def draw(self): self.qr.make() g = Group() color = self.barFillColor border = self.barBorder width = self.barWidth height = self.barHeight x = self.x y = self.y g.add(SRect(x, y, width, height, fillColor=None)) moduleCount = self.qr.getModuleCount() minwh = float(min(width, height)) boxsize = minwh / (moduleCount + border * 2.0) offsetX = (width - minwh) / 2.0 offsetY = (minwh - height) / 2.0 for r, row in enumerate(self.qr.modules): row = map(bool, row) c = 0 for t, tt in itertools.groupby(row): isDark = t count = len(list(tt)) if isDark: x = (c + border) * boxsize y = (r + border + 1) * boxsize s = SRect(offsetX + x, offsetY + height - y, count * boxsize, boxsize) g.add(s) c += count return g
def makeSwatchSample(self,rowNo, x, y, width, height): baseStyle = self.lines styleIdx = rowNo % len(baseStyle) style = baseStyle[styleIdx] color = style.strokeColor y = y+height/2. if self.joinedLines: dash = getattr(style, 'strokeDashArray', getattr(baseStyle,'strokeDashArray',None)) strokeWidth= getattr(style, 'strokeWidth', getattr(style, 'strokeWidth',None)) L = Line(x,y,x+width,y,strokeColor=color,strokeLineCap=0) if strokeWidth: L.strokeWidth = strokeWidth if dash: L.strokeDashArray = dash else: L = None if hasattr(style, 'symbol'): S = style.symbol elif hasattr(baseStyle, 'symbol'): S = baseStyle.symbol else: S = None if S: S = uSymbol2Symbol(S,x+width/2.,y,color) if S and L: g = Group() g.add(L) g.add(S) return g return S or L
def draw(self): fillColor = self.fillColor strokeColor = self.strokeColor g = Group() bg = self.background bd = self.border bdw = self.borderWidth shadow = self.shadow x, y = self.x, self.y if bg: if shadow is not None and 0<=shadow<1: shadow = Color(bg.red*shadow,bg.green*shadow,bg.blue*shadow) self._paintLogo(g,dy=-2.5, dx=2,fillColor=shadow) self._paintLogo(g,fillColor=fillColor,strokeColor=strokeColor) g.skew(kx=self.skewX, ky=self.skewY) g.shift(self._dx,self._dy) G = Group() G.add(g) _w, _h = 130, 86 w, h = self.width, self.height if bg or (bd and bdw): G.insert(0,Rect(0,0,_w,_h,fillColor=bg,strokeColor=bd,strokeWidth=bdw)) if w!=_w or h!=_h: G.scale(w/float(_w),h/float(_h)) angle = self.angle if self.angle: w, h = w/2., h/2. G.shift(-w,-h) G.rotate(angle) G.shift(w,h) G.shift(x,y) return G
def getCaptcha(n=5,fontName='Courier',fontSize=14,text=None,fillColor=None): '''return n random chars in a string and in a byte string structured as a GIF image''' from reportlab.graphics.shapes import Drawing, Group, String, \ rotate, skewX, skewY, mmult, translate, Rect if not text: from random import randint, uniform text=''.join([_allowed[randint(0,_mx)] for i in range(n)]) else: uniform = lambda l,h: 0.5*(l+h) n = len(text) baseline = 0 x = 0 G0 = Group() for c in text: x += 1 A = translate(x,uniform(baseline-5,baseline+5)) A = mmult(A,rotate(uniform(-15,15))) A = mmult(A,skewX(uniform(-8,8))) A = mmult(A,skewY(uniform(-8,8))) G = Group(transform=A) G.add(String(0,0,c,fontname=fontName,fontSize=fontSize)) G0.add(G) x0,y0,x1,y1 = G0.getBounds() x = 1+x1 G0.transform=translate(2-x0,2-y0) W = 4+x1-x0 H = 4+y1-y0 D = Drawing(W,H) if fillColor: from reportlab.lib.colors import toColor D.add(Rect(0,0,W,H, fillColor = toColor(fillColor),strokeColor=None)) D.add(G0) return text, D.asString('gif')
def renderUse(self, node, group=None, clipping=None): if group is None: group = Group() xlink_href = node.attrib.get('{http://www.w3.org/1999/xlink}href') if not xlink_href: return if xlink_href[1:] not in self.definitions: # The missing definition should appear later in the file self.waiting_use_nodes[xlink_href[1:]].append((node, group)) return group if clipping: group.add(clipping) if len(node.getchildren()) == 0: # Append a copy of the referenced node as the <use> child (if not already done) node.append(copy.deepcopy(self.definitions[xlink_href[1:]])) self.renderNode(node.getchildren()[-1], parent=group) getAttr = node.getAttribute transform = getAttr("transform") x, y = map(getAttr, ("x", "y")) if x or y: transform += " translate(%s, %s)" % (x or '0', y or '0') if transform: self.shape_converter.applyTransformOnGroup(transform, group) return group
def _Flag_Japan(self): s = _size g = Group() w = self._width = s*1.5 g.add(Rect(0,0,w,s,fillColor=colors.mintcream,strokeColor=None, strokeWidth=0)) g.add(Circle(cx=w/2,cy=s/2,r=0.3*w,fillColor=colors.red,strokeColor=None, strokeWidth=0)) return g
def convertPolyline(self, node): getAttr = node.getAttribute points = getAttr("points") points = points.replace(',', ' ') points = points.split() points = list(map(self.attrConverter.convertLength, points)) if len(points) % 2 != 0 or len(points) == 0: # Odd number of coordinates or no coordinates, invalid polyline return None polyline = PolyLine(points) self.applyStyleOnShape(polyline, node) has_fill = self.attrConverter.findAttr(node, 'fill') not in ('', 'none') if has_fill: # ReportLab doesn't fill polylines, so we are creating a polygon # polygon copy of the polyline, but without stroke. group = Group() polygon = Polygon(points) self.applyStyleOnShape(polygon, node) polygon.strokeColor = None group.add(polygon) group.add(polyline) return group return polyline
def makeSwatchSample(self,rowNo, x, y, width, height): styleCount = len(self.lines) styleIdx = rowNo % styleCount rowColor = self.lines[styleIdx].strokeColor if self.joinedLines: dash = getattr(self.lines[styleIdx], 'strokeDashArray', getattr(self.lines,'strokeDashArray',None)) strokeWidth= getattr(self.lines[styleIdx], 'strokeWidth', getattr(self.lines[styleIdx], 'strokeWidth',None)) L = Line(x,y,x+width,y+height,strokeColor=rowColor,strokeLineCap=0) if strokeWidth: L.strokeWidth = strokeWidth if dash: L.strokeDashArray = dash else: L = None if hasattr(self.lines[styleIdx], 'symbol'): S = self.lines[styleIdx].symbol elif hasattr(self.lines, 'symbol'): S = self.lines.symbol else: S = None if S: S = uSymbol2Symbol(S,x+width/2.,y+height/2.,rowColor) if S and L: g = Group() g.add(S) g.add(L) return g return S or L
def draw(self): "Draws itself." vA, cA = self.valueAxis, self.categoryAxis vA.setPosition(self.x, self.y, self.height) if vA: vA.joinAxis = cA if cA: cA.joinAxis = vA vA.configure(self.data) # If zero is in chart, put x axis there, otherwise # use bottom. xAxisCrossesAt = vA.scale(0) if ((xAxisCrossesAt > self.y + self.height) or (xAxisCrossesAt < self.y)): y = self.y else: y = xAxisCrossesAt cA.setPosition(self.x, y, self.width) cA.configure(self.data) self.calcPositions() g = Group() g.add(self.makeBackground()) if self.inFill: self._inFillG = Group() g.add(self._inFillG) g.add(cA) g.add(vA) cA.makeGrid(g,parent=self,dim=vA.getGridDims) vA.makeGrid(g,parent=self,dim=cA.getGridDims) g.add(self.makeLines()) for a in getattr(self,'annotations',()): g.add(a(self,cA.scale,vA.scale)) return g
def _Flag_Spain(self): s = _size g = Group() w = self._width = s*1.5 g.add(Rect(0, 0, width=w, height=s, fillColor = colors.red, strokeColor = None, strokeWidth=0)) g.add(Rect(0, (s/4), width=w, height=s/2, fillColor = colors.yellow, strokeColor = None, strokeWidth=0)) return g
def draw(self): xA, yA = self.xAxis, self.yAxis xA.setPosition(self.x, self.y, 360) yA.setPosition(self.x, self.y, 360) xA.joinAxis = yA yA.joinAxis = xA xA.valueMin = -180 xA.valueMax = 180 xA.valueStep = self.gridSpacing yA.valueMin = -180 yA.valueMax = 180 yA.valueStep = self.gridSpacing xA.configure(self.data) yA.configure(self.data) g = Group() g.add(self.makeBackground()) # axis labels phiLabX, phiLabY = self.x + 180, self.y - 20 psiLabX, psiLabY = self.x - 20, self.y + 180 g.add(Label(x=phiLabX, y=phiLabY, _text=u"\u03A6\u00B0")) g.add(Label(x=psiLabX, y=psiLabY, _text=u"\u03A8\u00B0")) g.add(xA) g.add(yA) # internal axes g.add(Line(self.x + 180, self.y, self.x + 180, self.y + 360)) g.add(Line(self.x, self.y + 180, self.x + 360, self.y + 180)) if self.visibleGrid: xA.visibleGrid = True yA.visibleGrid = True xA.gridStart = yA._x yA.gridStart = xA._y xA.gridEnd = yA._x + yA._length yA.gridEnd = xA._y + xA._length xA.makeGrid(g, parent=self) yA.makeGrid(g, parent=self) # the points for i, pointSet in enumerate(self.data): c = self.pointSets[i].fillColor for p in pointSet: phi, psi = p phiAsX = phi + 180 + self.x psiAsY = psi + 180 + self.y g.add(Rect(phiAsX, psiAsY, 1, 1, strokeColor=c)) return g
def convertText(self, node): attrConv = self.attrConverter x, y = map(node.getAttribute, ('x', 'y')) x, y = map(attrConv.convertLength, (x, y)) xml_space = node.getAttribute("{%s}space" % XML_NS) if xml_space: preserve_space = xml_space == 'preserve' else: preserve_space = self.preserve_space gr = Group() frag_lengths = [] dx0, dy0 = 0, 0 x1, y1 = 0, 0 ff = attrConv.findAttr(node, "font-family") or "Helvetica" ff = attrConv.convertFontFamily(ff) fs = attrConv.findAttr(node, "font-size") or "12" fs = attrConv.convertLength(fs) for c in itertools.chain([node], node.getchildren()): has_x = False dx, dy = 0, 0 baseLineShift = 0 if node_name(c) == 'text': text = self.clean_text(c.text, preserve_space) if not text: continue elif node_name(c) == 'tspan': text = self.clean_text(c.text, preserve_space) if not text: continue x1, y1, dx, dy = [c.attrib.get(name, '') for name in ("x", "y", "dx", "dy")] has_x = x1 != '' x1, y1, dx, dy = map(attrConv.convertLength, (x1, y1, dx, dy)) dx0 = dx0 + dx dy0 = dy0 + dy baseLineShift = c.attrib.get("baseline-shift", '0') if baseLineShift in ("sub", "super", "baseline"): baseLineShift = {"sub":-fs/2, "super":fs/2, "baseline":0}[baseLineShift] else: baseLineShift = attrConv.convertLength(baseLineShift, fs) else: continue frag_lengths.append(stringWidth(text, ff, fs)) new_x = x1 if has_x else sum(frag_lengths[:-1]) shape = String(x + new_x, y - y1 - dy0 + baseLineShift, text) self.applyStyleOnShape(shape, node) if node_name(c) == 'tspan': self.applyStyleOnShape(shape, c) gr.add(shape) gr.scale(1, -1) gr.translate(0, -2*y) return gr
def annotation(self,xScale,yScale): x = xScale(xv) y = yScale(yv) g = Group() xA = xScale.im_self #the x axis g.add(Line(xA._x,y,xA._x+xA._length,y,strokeColor=strokeColor,strokeWidth=strokeWidth)) yA = yScale.im_self #the y axis g.add(Line(x,yA._y,x,yA._y+yA._length,strokeColor=strokeColor,strokeWidth=strokeWidth)) return g
def _Flag_USA(self): s = _size # abbreviate as we will use this a lot g = Group() box = Rect(0, 0, s * 2, s, fillColor=colors.mintcream, strokeColor=colors.black, strokeWidth=0) g.add(box) for stripecounter in range(13, 0, -1): stripeheight = s / 13.0 if not (stripecounter % 2 == 0): stripecolor = colors.red else: stripecolor = colors.mintcream redorwhiteline = Rect( 0, (s - (stripeheight * stripecounter)), width=s * 2, height=stripeheight, fillColor=stripecolor, strokeColor=None, strokeWidth=20, ) g.add(redorwhiteline) bluebox = Rect( 0, (s - (stripeheight * 7)), width=0.8 * s, height=stripeheight * 7, fillColor=colors.darkblue, strokeColor=None, strokeWidth=0, ) g.add(bluebox) lss = s * 0.045 lss2 = lss / 2.0 s9 = s / 9.0 s7 = s / 7.0 for starxcounter in range(5): for starycounter in range(4): ls = Star() ls.size = lss ls.x = 0 - s / 22.0 + lss / 2.0 + s7 + starxcounter * s7 ls.fillColor = colors.mintcream ls.y = s - (starycounter + 1) * s9 + lss2 g.add(ls) for starxcounter in range(6): for starycounter in range(5): ls = Star() ls.size = lss ls.x = 0 - (s / 22.0) + lss / 2.0 + s / 14.0 + starxcounter * s7 ls.fillColor = colors.mintcream ls.y = s - (starycounter + 1) * s9 + (s / 18.0) + lss2 g.add(ls) return g
def _borderDraw(self,f): s = self.size # abbreviate as we will use this a lot g = Group() g.add(f) x, y, sW = self.x+self.dx, self.y+self.dy, self.strokeWidth/2. g.insert(0,Rect(-sW, -sW, width=getattr(self,'_width',2*s)+3*sW, height=getattr(self,'_height',s)+2*sW, fillColor = None, strokeColor = self.strokeColor, strokeWidth=sW*2)) g.shift(x,y) g.scale(s/_size, s/_size) return g
def draw(self): dx = self.width / 16.0 dy = self.height / 16.0 g = Group() g.add(Rect(self.x, self.y, self.width, self.height, fillColor=None, strokeColor=colors.black)) for x in range(16): for y in range(16): charValue = y * 16 + x if charValue > 32: s = String(self.x + x * dx, self.y + (self.height - y * dy), chr(charValue)) g.add(s) return g
def makeBackground(self): g = Group() g.add(HorizontalLineChart.makeBackground(self)) valAxis = self.valueAxis valTickPositions = valAxis._tickValues for y in valTickPositions: y = valAxis.scale(y) g.add(Line(self.x, y, self.x + self.width, y, strokeColor=self.strokeColor)) return g
def _Flag_Cuba(self): s = _size g = Group() for i in range(5): stripe = Rect(0, i*s/5, width=s*2, height=s/5, fillColor = [colors.darkblue, colors.mintcream][i%2], strokeColor = None, strokeWidth=0) g.add(stripe) redwedge = Polygon(points = [ 0, 0, 4*s/5, (s/2), 0, s], fillColor = colors.red, strokeColor = None, strokeWidth=0) g.add(redwedge) star = Star() star.x = 2.5*s/10 star.y = s/2 star.size = 3*s/10 star.fillColor = colors.white g.add(star) box = Rect(0, 0, s*2, s, fillColor = None, strokeColor = colors.black, strokeWidth=0) g.add(box) return g
def _Flag_Turkey(self): s = _size g = Group() box = Rect(0, 0, s*2, s, fillColor = colors.red, strokeColor = colors.black, strokeWidth=0) g.add(box) whitecircle = Circle(cx=((s*0.35)*2), cy=s/2, r=s*0.3, fillColor = colors.mintcream, strokeColor = None, strokeWidth=0) g.add(whitecircle) redcircle = Circle(cx=((s*0.39)*2), cy=s/2, r=s*0.24, fillColor = colors.red, strokeColor = None, strokeWidth=0) g.add(redcircle) ws = Star() ws.angle = 15 ws.size = s/5 ws.x = (s*0.5)*2+ws.size/2 ws.y = (s*0.5) ws.fillColor = colors.mintcream ws.strokeColor = None g.add(ws) return g
def draw(self): P = self.points P = list(map(lambda i, P=P: (P[i], P[i + 1]), range(0, len(P), 2))) path = definePath( [("moveTo",) + P[0]] + [("lineTo",) + x for x in P[1:]] + ["closePath"], fillColor=None, strokeColor=None ) path.isClipPath = 1 g = Group() g.add(path) angle = self.angle orientation = "vertical" if angle == 180: angle = 0 elif angle in (90, 270): orientation = "horizontal" angle = 0 rect = ShadedRect(strokeWidth=0, strokeColor=None, orientation=orientation) for k in "fillColorStart", "fillColorEnd", "numShades", "cylinderMode": setattr(rect, k, getattr(self, k)) g.add(rotatedEnclosingRect(P, angle, rect)) g.add(EmptyClipPath) path = path.copy() path.isClipPath = 0 path.strokeColor = self.strokeColor path.strokeWidth = self.strokeWidth g.add(path) return g
def _Flag_France(self): s = _size g = Group() box = Rect(0, 0, s * 2, s, fillColor=colors.navy, strokeColor=colors.black, strokeWidth=0) g.add(box) bluebox = Rect(0, 0, width=((s / 3.0) * 2.0), height=s, fillColor=colors.blue, strokeColor=None, strokeWidth=0) g.add(bluebox) whitebox = Rect( ((s / 3.0) * 2.0), 0, width=((s / 3.0) * 2.0), height=s, fillColor=colors.mintcream, strokeColor=None, strokeWidth=0, ) g.add(whitebox) redbox = Rect( ((s / 3.0) * 4.0), 0, width=((s / 3.0) * 2.0), height=s, fillColor=colors.red, strokeColor=None, strokeWidth=0, ) g.add(redbox) return g
def _Flag_Palestine(self): s = _size g = Group() box = Rect(0, s/3, s*2, s/3, fillColor = colors.mintcream, strokeColor = None, strokeWidth=0) g.add(box) greenbox = Rect(0, 0, width=s*2, height=s/3, fillColor = colors.limegreen, strokeColor = None, strokeWidth=0) g.add(greenbox) blackbox = Rect(0, 2*s/3, width=s*2, height=s/3, fillColor = colors.black, strokeColor = None, strokeWidth=0) g.add(blackbox) redwedge = Polygon(points = [ 0, 0, 2*s/3, (s/2), 0, s], fillColor = colors.red, strokeColor = None, strokeWidth=0) g.add(redwedge) return g
def draw(self): P = self.points P = map(lambda i, P=P:(P[i],P[i+1]),xrange(0,len(P),2)) path = definePath([('moveTo',)+P[0]]+map(lambda x: ('lineTo',)+x,P[1:])+['closePath'], fillColor=None, strokeColor=None) path.isClipPath = 1 g = Group() g.add(path) angle = self.angle orientation = 'vertical' if angle==180: angle = 0 elif angle in (90,270): orientation ='horizontal' angle = 0 rect = ShadedRect(strokeWidth=0,strokeColor=None,orientation=orientation) for k in 'fillColorStart', 'fillColorEnd', 'numShades', 'cylinderMode': setattr(rect,k,getattr(self,k)) g.add(rotatedEnclosingRect(P, angle, rect)) g.add(EmptyClipPath) path = path.copy() path.isClipPath = 0 path.strokeColor = self.strokeColor path.strokeWidth = self.strokeWidth g.add(path) return g
def draw(self): sx = 0.5 fillColor = self.fillColor strokeColor = self.strokeColor shadow = Color(fillColor.red*sx,fillColor.green*sx,fillColor.blue*sx) g = Group() g2= Group() g.add(Rect(fillColor=fillColor, strokeColor=fillColor, x=0, y=0, width=self._w, height=self._h)) sx = (self._w-2)/self._sw() g2.scale(sx,1) self._addPage(g2,strokeWidth=3,dx=2,dy=-2.5,color=shadow) self._addPage(g2,strokeWidth=3,color=strokeColor) g2.scale(1/sx,1) g2.add(self._getText(x=1,y=0,color=shadow)) g2.add(self._getText(x=0,y=1,color=strokeColor)) g2.scale(sx,1) g2.skew(kx=10, ky=0) g2.shift(0,38) g.add(g2) g.scale(self.width/self._w,self.height/self._h) g.shift(self.x,self.y) return g
def draw(self): P = self.points P = map(lambda i, P=P: (P[i], P[i + 1]), xrange(0, len(P), 2)) path = definePath([('moveTo', ) + P[0]] + map(lambda x: ('lineTo', ) + x, P[1:]) + ['closePath'], fillColor=None, strokeColor=None) path.isClipPath = 1 g = Group() g.add(path) rect = ShadedRect(strokeWidth=0, strokeColor=None) for k in 'fillColorStart', 'fillColorEnd', 'numShades', 'cylinderMode': setattr(rect, k, getattr(self, k)) g.add(rotatedEnclosingRect(P, self.angle, rect)) g.add(EmptyClipPath) path = path.copy() path.isClipPath = 0 path.strokeColor = self.strokeColor path.strokeWidth = self.strokeWidth g.add(path) return g
def _Flag_Turkey(self): s = _size g = Group() box = Rect(0, 0, s * 2, s, fillColor=colors.red, strokeColor=colors.black, strokeWidth=0) g.add(box) whitecircle = Circle(cx=((s * 0.35) * 2), cy=s / 2, r=s * 0.3, fillColor=colors.mintcream, strokeColor=None, strokeWidth=0) g.add(whitecircle) redcircle = Circle(cx=((s * 0.39) * 2), cy=s / 2, r=s * 0.24, fillColor=colors.red, strokeColor=None, strokeWidth=0) g.add(redcircle) ws = Star() ws.angle = 15 ws.size = s / 5 ws.x = (s * 0.5) * 2 + ws.size / 2 ws.y = (s * 0.5) ws.fillColor = colors.mintcream ws.strokeColor = None g.add(ws) return g
def _Flag_Afghanistan(self): s = _size g = Group() box = Rect(0, 0, s*2, s, fillColor = colors.mintcream, strokeColor = colors.black, strokeWidth=0) g.add(box) greenbox = Rect(0, ((s/3.0)*2.0), width=s*2.0, height=s/3.0, fillColor = colors.limegreen, strokeColor = None, strokeWidth=0) g.add(greenbox) blackbox = Rect(0, 0, width=s*2.0, height=s/3.0, fillColor = colors.black, strokeColor = None, strokeWidth=0) g.add(blackbox) return g
def _Flag_Germany(self): s = _size g = Group() box = Rect(0, 0, s*2, s, fillColor = colors.gold, strokeColor = colors.black, strokeWidth=0) g.add(box) blackbox1 = Rect(0, ((s/3.0)*2.0), width=s*2.0, height=s/3.0, fillColor = colors.black, strokeColor = None, strokeWidth=0) g.add(blackbox1) redbox1 = Rect(0, (s/3.0), width=s*2.0, height=s/3.0, fillColor = colors.orangered, strokeColor = None, strokeWidth=0) g.add(redbox1) return g
def _Flag_Ireland(self): s = _size g = Group() box = Rect(0, 0, s*2, s, fillColor = colors.forestgreen, strokeColor = colors.black, strokeWidth=0) g.add(box) whitebox = Rect(((s*2.0)/3.0), 0, width=(2.0*(s*2.0)/3.0), height=s, fillColor = colors.mintcream, strokeColor = None, strokeWidth=0) g.add(whitebox) orangebox = Rect(((2.0*(s*2.0)/3.0)), 0, width=(s*2.0)/3.0, height=s, fillColor = colors.darkorange, strokeColor = None, strokeWidth=0) g.add(orangebox) return g
def _Flag_Holland(self): s = _size g = Group() box = Rect(0, 0, s*2, s, fillColor = colors.mintcream, strokeColor = colors.black, strokeWidth=0) g.add(box) redbox = Rect(0, ((s/3.0)*2.0), width=s*2.0, height=s/3.0, fillColor = colors.red, strokeColor = None, strokeWidth=0) g.add(redbox) bluebox = Rect(0, 0, width=s*2.0, height=s/3.0, fillColor = colors.darkblue, strokeColor = None, strokeWidth=0) g.add(bluebox) return g
def _Flag_Cuba(self): s = _size g = Group() for i in range(5): stripe = Rect(0, i * s / 5, width=s * 2, height=s / 5, fillColor=[colors.darkblue, colors.mintcream][i % 2], strokeColor=None, strokeWidth=0) g.add(stripe) redwedge = Polygon(points=[0, 0, 4 * s / 5, (s / 2), 0, s], fillColor=colors.red, strokeColor=None, strokeWidth=0) g.add(redwedge) star = Star() star.x = 2.5 * s / 10 star.y = s / 2 star.size = 3 * s / 10 star.fillColor = colors.white g.add(star) box = Rect(0, 0, s * 2, s, fillColor=None, strokeColor=colors.black, strokeWidth=0) g.add(box) return g
def _Flag_Palestine(self): s = _size g = Group() box = Rect(0, s / 3, s * 2, s / 3, fillColor=colors.mintcream, strokeColor=None, strokeWidth=0) g.add(box) greenbox = Rect(0, 0, width=s * 2, height=s / 3, fillColor=colors.limegreen, strokeColor=None, strokeWidth=0) g.add(greenbox) blackbox = Rect(0, 2 * s / 3, width=s * 2, height=s / 3, fillColor=colors.black, strokeColor=None, strokeWidth=0) g.add(blackbox) redwedge = Polygon(points=[0, 0, 2 * s / 3, (s / 2), 0, s], fillColor=colors.red, strokeColor=None, strokeWidth=0) g.add(redwedge) return g
def _Flag_Finland(self): s = _size g = Group() # crossbox specific bits box = Rect(0, 0, s*2, s, fillColor = colors.ghostwhite, strokeColor = colors.black, strokeWidth=0) g.add(box) blueline1 = Rect((s*0.6), 0, width=0.3*s, height=s, fillColor = colors.darkblue, strokeColor = None, strokeWidth=0) g.add(blueline1) blueline2 = Rect(0, (s*0.4), width=s*2, height=s*0.3, fillColor = colors.darkblue, strokeColor = None, strokeWidth=0) g.add(blueline2) return g
def _Flag_Denmark(self): s = _size g = Group() self._width = w = s*1.4 box = Rect(0, 0, w, s, fillColor = colors.red, strokeColor = colors.black, strokeWidth=0) g.add(box) whitebox1 = Rect(((s/5)*2), 0, width=s/6, height=s, fillColor = colors.mintcream, strokeColor = None, strokeWidth=0) g.add(whitebox1) whitebox2 = Rect(0, ((s/2)-(s/12)), width=w, height=s/6, fillColor = colors.mintcream, strokeColor = None, strokeWidth=0) g.add(whitebox2) return g
def _Flag_Austria(self): s = _size # abbreviate as we will use this a lot g = Group() box = Rect(0, 0, s*2, s, fillColor = colors.mintcream, strokeColor = colors.black, strokeWidth=0) g.add(box) redbox1 = Rect(0, 0, width=s*2.0, height=s/3.0, fillColor = colors.red, strokeColor = None, strokeWidth=0) g.add(redbox1) redbox2 = Rect(0, ((s/3.0)*2.0), width=s*2.0, height=s/3.0, fillColor = colors.red, strokeColor = None, strokeWidth=0) g.add(redbox2) return g
def _Flag_Sweden(self): s = _size g = Group() self._width = s*1.4 box = Rect(0, 0, self._width, s, fillColor = colors.dodgerblue, strokeColor = colors.black, strokeWidth=0) g.add(box) box1 = Rect(((s/5)*2), 0, width=s/6, height=s, fillColor = colors.gold, strokeColor = None, strokeWidth=0) g.add(box1) box2 = Rect(0, ((s/2)-(s/12)), width=self._width, height=s/6, fillColor = colors.gold, strokeColor = None, strokeWidth=0) g.add(box2) return g
def _Flag_CzechRepublic(self): s = _size g = Group() box = Rect(0, 0, s*2, s, fillColor = colors.mintcream, strokeColor = colors.black, strokeWidth=0) g.add(box) redbox = Rect(0, 0, width=s*2, height=s/2, fillColor = colors.red, strokeColor = None, strokeWidth=0) g.add(redbox) bluewedge = Polygon(points = [ 0, 0, s, (s/2), 0, s], fillColor = colors.darkblue, strokeColor = None, strokeWidth=0) g.add(bluewedge) return g
def _Flag_Switzerland(self): s = _size g = Group() self._width = s g.add( Rect(0, 0, s, s, fillColor=colors.red, strokeColor=colors.black, strokeWidth=0)) g.add( Line((s / 2), (s / 5.5), (s / 2), (s - (s / 5.5)), fillColor=colors.mintcream, strokeColor=colors.mintcream, strokeWidth=(s / 5))) g.add( Line((s / 5.5), (s / 2), (s - (s / 5.5)), (s / 2), fillColor=colors.mintcream, strokeColor=colors.mintcream, strokeWidth=s / 5)) return g
def makeLines(self): labelFmt = self.lineLabelFormat P = list(range(len(self._positions))) if self.reversePlotOrder: P.reverse() inFill = self.inFill assert not inFill, "inFill not supported for 3d yet" #if inFill: #inFillY = self.categoryAxis._y #inFillX0 = self.valueAxis._x #inFillX1 = inFillX0 + self.categoryAxis._length #inFillG = getattr(self,'_inFillG',g) zDepth = self.zDepth _zadjust = self._zadjust theta_x = self.theta_x theta_y = self.theta_y F = _FakeGroup() from reportlab.graphics.charts.utils3d import _make_3d_line_info tileWidth = getattr(self,'_3d_tilewidth',None) if not tileWidth and self.categoryAxis.style!='parallel_3d': tileWidth = 1 # Iterate over data rows. for rowNo in P: row = self._positions[rowNo] n = len(row) styleCount = len(self.lines) styleIdx = rowNo % styleCount rowStyle = self.lines[styleIdx] rowColor = rowStyle.strokeColor dash = getattr(rowStyle, 'strokeDashArray', None) z0 = self._calc_z0(rowNo) z1 = z0 + zDepth if hasattr(self.lines[styleIdx], 'strokeWidth'): strokeWidth = self.lines[styleIdx].strokeWidth elif hasattr(self.lines, 'strokeWidth'): strokeWidth = self.lines.strokeWidth else: strokeWidth = None # Iterate over data columns. if self.joinedLines: if n: x0, y0 = row[0] for colNo in range(1,n): x1, y1 = row[colNo] _make_3d_line_info( F, x0, x1, y0, y1, z0, z1, theta_x, theta_y, rowColor, fillColorShaded=None, tileWidth=tileWidth, strokeColor=None, strokeWidth=None, strokeDashArray=None, shading=0.1) x0, y0 = x1, y1 if hasattr(self.lines[styleIdx], 'symbol'): uSymbol = self.lines[styleIdx].symbol elif hasattr(self.lines, 'symbol'): uSymbol = self.lines.symbol else: uSymbol = None if uSymbol: for colNo in range(n): x1, y1 = row[colNo] x1, y1 = _zadjust(x1,y1,z0) symbol = uSymbol2Symbol(uSymbol,x1,y1,rowColor) if symbol: F.add((2,z0,z0,x1,y1,symbol)) # Draw item labels. for colNo in range(n): x1, y1 = row[colNo] x1, y1 = _zadjust(x1,y1,z0) L = self._innerDrawLabel(rowNo, colNo, x1, y1) if L: F.add((2,z0,z0,x1,y1,L)) F.sort() g = Group() for v in F.value(): g.add(v[-1]) return g
def makeLines(self): g = Group() labelFmt = self.lineLabelFormat P = list(range(len(self._positions))) if self.reversePlotOrder: P.reverse() inFill = self.inFill if inFill: inFillY = self.categoryAxis._y inFillX0 = self.valueAxis._x inFillX1 = inFillX0 + self.categoryAxis._length inFillG = getattr(self,'_inFillG',g) yzero = self._yzero # Iterate over data rows. for rowNo in P: row = self._positions[rowNo] styleCount = len(self.lines) styleIdx = rowNo % styleCount rowStyle = self.lines[styleIdx] rowColor = rowStyle.strokeColor dash = getattr(rowStyle, 'strokeDashArray', None) lineStyle = getattr(rowStyle,'lineStyle',None) if hasattr(rowStyle, 'strokeWidth'): strokeWidth = rowStyle.strokeWidth elif hasattr(self.lines, 'strokeWidth'): strokeWidth = self.lines.strokeWidth else: strokeWidth = None # Iterate over data columns. if lineStyle=='bar': barWidth = getattr(rowStyle,'barWidth',Percentage(50)) fillColor = getattr(rowStyle,'fillColor',rowColor) if isinstance(barWidth,Percentage): hbw = self._hngs*barWidth*0.01 else: hbw = barWidth*0.5 for colNo in range(len(row)): x,y = row[colNo] g.add(Rect(x-hbw,min(y,yzero),2*hbw,abs(y-yzero),strokeWidth=strokeWidth,strokeColor=rowColor,fillColor=fillColor)) elif self.joinedLines or lineStyle=='joinedLine': points = [] for colNo in range(len(row)): points += row[colNo] if inFill: points = points + [inFillX1,inFillY,inFillX0,inFillY] inFillG.add(Polygon(points,fillColor=rowColor,strokeColor=rowColor,strokeWidth=0.1)) else: line = PolyLine(points,strokeColor=rowColor,strokeLineCap=0,strokeLineJoin=1) if strokeWidth: line.strokeWidth = strokeWidth if dash: line.strokeDashArray = dash g.add(line) if hasattr(rowStyle, 'symbol'): uSymbol = rowStyle.symbol elif hasattr(self.lines, 'symbol'): uSymbol = self.lines.symbol else: uSymbol = None if uSymbol: for colNo in range(len(row)): x1, y1 = row[colNo] symbol = uSymbol2Symbol(uSymbol,x1,y1,rowStyle.strokeColor) if symbol: g.add(symbol) # Draw item labels. for colNo in range(len(row)): x1, y1 = row[colNo] self.drawLabel(g, rowNo, colNo, x1, y1) 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 _Flag_Brazil(self): s = _size # abbreviate as we will use this a lot g = Group() m = s / 14 self._width = w = (m * 20) def addStar(x, y, size, g=g, w=w, s=s, m=m): st = Star() st.fillColor = colors.mintcream st.size = size * m st.x = (w / 2) + (x * (0.35 * m)) st.y = (s / 2) + (y * (0.35 * m)) g.add(st) g.add( Rect(0, 0, w, s, fillColor=colors.green, strokeColor=None, strokeWidth=0)) g.add( Polygon(points=[ 1.7 * m, (s / 2), (w / 2), s - (1.7 * m), w - (1.7 * m), (s / 2), (w / 2), 1.7 * m ], fillColor=colors.yellow, strokeColor=None, strokeWidth=0)) g.add( Circle(cx=w / 2, cy=s / 2, r=3.5 * m, fillColor=colors.blue, strokeColor=None, strokeWidth=0)) g.add( Wedge((w / 2) - (2 * m), 0, 8.5 * m, 50, 98.1, 8.5 * m, fillColor=colors.mintcream, strokeColor=None, strokeWidth=0)) g.add( Wedge((w / 2), (s / 2), 3.501 * m, 156, 352, 3.501 * m, fillColor=colors.mintcream, strokeColor=None, strokeWidth=0)) g.add( Wedge((w / 2) - (2 * m), 0, 8 * m, 48.1, 100, 8 * m, fillColor=colors.blue, strokeColor=None, strokeWidth=0)) g.add( Rect(0, 0, w, (s / 4) + 1.7 * m, fillColor=colors.green, strokeColor=None, strokeWidth=0)) g.add( Polygon(points=[ 1.7 * m, (s / 2), (w / 2), s / 2 - 2 * m, w - (1.7 * m), (s / 2), (w / 2), 1.7 * m ], fillColor=colors.yellow, strokeColor=None, strokeWidth=0)) g.add( Wedge(w / 2, s / 2, 3.502 * m, 166, 342.1, 3.502 * m, fillColor=colors.blue, strokeColor=None, strokeWidth=0)) addStar(3.2, 3.5, 0.3) addStar(-8.5, 1.5, 0.3) addStar(-7.5, -3, 0.3) addStar(-4, -5.5, 0.3) addStar(0, -4.5, 0.3) addStar(7, -3.5, 0.3) addStar(-3.5, -0.5, 0.25) addStar(0, -1.5, 0.25) addStar(1, -2.5, 0.25) addStar(3, -7, 0.25) addStar(5, -6.5, 0.25) addStar(6.5, -5, 0.25) addStar(7, -4.5, 0.25) addStar(-5.5, -3.2, 0.25) addStar(-6, -4.2, 0.25) addStar(-1, -2.75, 0.2) addStar(2, -5.5, 0.2) addStar(4, -5.5, 0.2) addStar(5, -7.5, 0.2) addStar(5, -5.5, 0.2) addStar(6, -5.5, 0.2) addStar(-8.8, -3.2, 0.2) addStar(2.5, 0.5, 0.2) addStar(-0.2, -3.2, 0.14) addStar(-7.2, -2, 0.14) addStar(0, -8, 0.1) sTmp = "ORDEM E PROGRESSO" nTmp = len(sTmp) delta = 0.850848010347 / nTmp radius = 7.9 * m centerx = (w / 2) - (2 * m) centery = 0 for i in range(nTmp): rad = 2 * pi - i * delta - 4.60766922527 x = cos(rad) * radius + centerx y = sin(rad) * radius + centery if i == 6: z = 0.35 * m else: z = 0.45 * m g2 = Group( String(x, y, sTmp[i], fontName='Helvetica-Bold', fontSize=z, strokeColor=None, fillColor=colors.green)) g2.rotate(rad) g.add(g2) return g
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 _Flag_UK(self): s = _size g = Group() w = s * 2 g.add( Rect(0, 0, w, s, fillColor=colors.navy, strokeColor=colors.black, strokeWidth=0)) g.add( Polygon([ 0, 0, s * .225, 0, w, s * (1 - .1125), w, s, w - s * .225, s, 0, s * .1125 ], fillColor=colors.mintcream, strokeColor=None, strokeWidth=0)) g.add( Polygon([ 0, s * (1 - .1125), 0, s, s * .225, s, w, s * .1125, w, 0, w - s * .225, 0 ], fillColor=colors.mintcream, strokeColor=None, strokeWidth=0)) g.add( Polygon([ 0, s - (s / 15), (s - ((s / 10) * 4)), (s * 0.65), (s - (s / 10) * 3), (s * 0.65), 0, s ], fillColor=colors.red, strokeColor=None, strokeWidth=0)) g.add( Polygon([ 0, 0, (s - ((s / 10) * 3)), (s * 0.35), (s - ((s / 10) * 2)), (s * 0.35), (s / 10), 0 ], fillColor=colors.red, strokeColor=None, strokeWidth=0)) g.add( Polygon([ w, s, (s + ((s / 10) * 3)), (s * 0.65), (s + ((s / 10) * 2)), (s * 0.65), w - (s / 10), s ], fillColor=colors.red, strokeColor=None, strokeWidth=0)) g.add( Polygon([ w, (s / 15), (s + ((s / 10) * 4)), (s * 0.35), (s + ((s / 10) * 3)), (s * 0.35), w, 0 ], fillColor=colors.red, strokeColor=None, strokeWidth=0)) g.add( Rect(((s * 0.42) * 2), 0, width=(0.16 * s) * 2, height=s, fillColor=colors.mintcream, strokeColor=None, strokeWidth=0)) g.add( Rect(0, (s * 0.35), width=w, height=s * 0.3, fillColor=colors.mintcream, strokeColor=None, strokeWidth=0)) g.add( Rect(((s * 0.45) * 2), 0, width=(0.1 * s) * 2, height=s, fillColor=colors.red, strokeColor=None, strokeWidth=0)) g.add( Rect(0, (s * 0.4), width=w, height=s * 0.2, fillColor=colors.red, strokeColor=None, strokeWidth=0)) return g
def draw(self): colorNamePairs = self.colorNamePairs autoCP = isAuto(colorNamePairs) if autoCP: chart = getattr(colorNamePairs, 'chart', getattr(colorNamePairs, 'obj', None)) swatchMarker = None autoCP = Auto(obj=chart) n = chart._seriesCount chartTexts = self._getTexts(colorNamePairs) else: swatchMarker = getattr(self, 'swatchMarker', None) if isAuto(swatchMarker): chart = getattr(swatchMarker, 'chart', getattr(swatchMarker, 'obj', None)) swatchMarker = Auto(obj=chart) n = len(colorNamePairs) dx = self.dx dy = self.dy alignment = self.alignment columnMaximum = self.columnMaximum deltax = self.deltax deltay = self.deltay dxTextSpace = self.dxTextSpace fontName = self.fontName fontSize = self.fontSize fillColor = self.fillColor strokeWidth = self.strokeWidth strokeColor = self.strokeColor subCols = self.subCols leading = fontSize * 1.2 yGap = self.yGap if not deltay: deltay = max(dy, leading) + self.autoYPadding ba = self.boxAnchor maxWidth = self._calculateMaxBoundaries(colorNamePairs) nCols = int((n + columnMaximum - 1) / (columnMaximum * 1.0)) xW = dx + dxTextSpace + self.autoXPadding variColumn = self.variColumn if variColumn: width = reduce(operator.add, [m[-1] for m in maxWidth], 0) + xW * nCols else: deltax = max(maxWidth[-1] + xW, deltax) width = maxWidth[-1] + nCols * deltax maxWidth = nCols * [maxWidth] thisx = self.x thisy = self.y - self.dy if ba not in ('ne', 'n', 'nw', 'autoy'): height = self._calcHeight() if ba in ('e', 'c', 'w'): thisy += height / 2. else: thisy += height if ba not in ('nw', 'w', 'sw', 'autox'): if ba in ('n', 'c', 's'): thisx -= width / 2 else: thisx -= width upperlefty = thisy g = Group() ascent = getFont(fontName).face.ascent / 1000. if ascent == 0: ascent = 0.718 # default (from helvetica) ascent *= fontSize # normalize lim = columnMaximum - 1 callout = getattr(self, 'callout', None) scallout = getattr(self, 'swatchCallout', None) dividerLines = self.dividerLines if dividerLines: dividerWidth = self.dividerWidth dividerColor = self.dividerColor dividerDashArray = self.dividerDashArray dividerOffsX = self.dividerOffsX dividerOffsY = self.dividerOffsY for i in xrange(n): if autoCP: col = autoCP col.index = i name = chartTexts[i] else: col, name = colorNamePairs[i] if isAuto(swatchMarker): col = swatchMarker col.index = i if isAuto(name): name = getattr(swatchMarker, 'chart', getattr(swatchMarker, 'obj', None)).getSeriesName( i, 'series %d' % i) T = _getLines(name) S = [] aS = S.append j = int(i / (columnMaximum * 1.0)) jOffs = maxWidth[j] # thisy+dy/2 = y+leading/2 y = y0 = thisy + (dy - ascent) * 0.5 if callout: callout(self, g, thisx, y, (col, name)) if alignment == "left": x = thisx xn = thisx + jOffs[-1] + dxTextSpace elif alignment == "right": x = thisx + dx + dxTextSpace xn = thisx else: raise ValueError, "bad alignment" if not isSeqType(name): T = [T] yd = y for k, lines in enumerate(T): y = y0 kk = k * 2 x1 = x + jOffs[kk] x2 = x + jOffs[kk + 1] sc = subCols[k, i] anchor = sc.align fN = getattr(sc, 'fontName', fontName) fS = getattr(sc, 'fontSize', fontSize) fC = getattr(sc, 'fillColor', fillColor) fL = getattr(sc, 'leading', 1.2 * fontSize) if fN == fontName: fA = (ascent * fS) / fontSize else: fA = getFont(fontName).face.ascent / 1000. if fA == 0: fA = 0.718 fA *= fS if anchor == 'left': anchor = 'start' xoffs = x1 elif anchor == 'right': anchor = 'end' xoffs = x2 elif anchor == 'numeric': xoffs = x2 else: anchor = 'middle' xoffs = 0.5 * (x1 + x2) for t in lines: aS( String(xoffs, y, t, fontName=fN, fontSize=fS, fillColor=fC, textAnchor=anchor)) y -= fL yd = min(yd, y) y += fL for iy, a in ((y - max(fL - fA, 0), 'underlines'), (y + fA, 'overlines')): il = getattr(sc, a, None) if il: if not isinstance(il, (tuple, list)): il = (il, ) for l in il: l = copy.copy(l) l.y1 += iy l.y2 += iy l.x1 += x1 l.x2 += x2 aS(l) x = xn y = yd leadingMove = 2 * y0 - y - thisy if dividerLines: xd = thisx + dx + dxTextSpace + jOffs[-1] + dividerOffsX[1] yd = thisy + dy * 0.5 + dividerOffsY if ((dividerLines & 1) and i % columnMaximum) or ( (dividerLines & 2) and not i % columnMaximum): g.add( Line(thisx + dividerOffsX[0], yd, xd, yd, strokeColor=dividerColor, strokeWidth=dividerWidth, strokeDashArray=dividerDashArray)) if (dividerLines & 4) and (i % columnMaximum == lim or i == (n - 1)): yd -= max(deltay, leadingMove) + yGap g.add( Line(thisx + dividerOffsX[0], yd, xd, yd, strokeColor=dividerColor, strokeWidth=dividerWidth, strokeDashArray=dividerDashArray)) # Make a 'normal' color swatch... if isAuto(col): chart = getattr(col, 'chart', getattr(col, 'obj', None)) c = chart.makeSwatchSample(getattr(col, 'index', i), x, thisy, dx, dy) elif isinstance(col, colors.Color): if isSymbol(swatchMarker): c = uSymbol2Symbol(swatchMarker, x + dx / 2., thisy + dy / 2., col) else: c = self._defaultSwatch(x, thisy, dx, dy, fillColor=col, strokeWidth=strokeWidth, strokeColor=strokeColor) elif col is not None: try: c = copy.deepcopy(col) c.x = x c.y = thisy c.width = dx c.height = dy except: c = None else: c = None if c: g.add(c) if scallout: scallout(self, g, thisx, y0, i, (col, name), c) for s in S: g.add(s) if self.colEndCallout and (i % columnMaximum == lim or i == (n - 1)): if alignment == "left": xt = thisx else: xt = thisx + dx + dxTextSpace yd = thisy + dy * 0.5 + dividerOffsY - ( max(deltay, leadingMove) + yGap) self.colEndCallout(self, g, thisx, xt, yd, jOffs[-1], jOffs[-1] + dx + dxTextSpace) if i % columnMaximum == lim: if variColumn: thisx += jOffs[-1] + xW else: thisx = thisx + deltax thisy = upperlefty else: thisy = thisy - max(deltay, leadingMove) - yGap return g
def makeBackground(self): if self.background is not None: BG = self.background if isinstance(BG,Group): g = BG for bg in g.contents: bg.x = self.x bg.y = self.y bg.width = self.width bg.height = self.height else: g = Group() if type(BG) not in (type(()),type([])): BG=(BG,) for bg in BG: bg.x = self.x bg.y = self.y bg.width = self.width bg.height = self.height g.add(bg) return g else: strokeColor,strokeWidth,fillColor=self.strokeColor, self.strokeWidth, self.fillColor if (strokeWidth and strokeColor) or fillColor: g = Group() _3d_dy = getattr(self,'_3d_dy',None) x = self.x y = self.y h = self.height w = self.width if _3d_dy is not None: _3d_dx = self._3d_dx if fillColor and not strokeColor: from reportlab.lib.colors import Blacker c = Blacker(fillColor, getattr(self,'_3d_blacken',0.7)) else: c = strokeColor if not strokeWidth: strokeWidth = 0.5 if fillColor or strokeColor or c: bg = Polygon([x,y,x,y+h,x+_3d_dx,y+h+_3d_dy,x+w+_3d_dx,y+h+_3d_dy,x+w+_3d_dx,y+_3d_dy,x+w,y], strokeColor=strokeColor or c or grey, strokeWidth=strokeWidth, fillColor=fillColor) g.add(bg) g.add(Line(x,y,x+_3d_dx,y+_3d_dy, strokeWidth=0.5, strokeColor=c)) g.add(Line(x+_3d_dx,y+_3d_dy, x+_3d_dx,y+h+_3d_dy,strokeWidth=0.5, strokeColor=c)) fc = Blacker(c, getattr(self,'_3d_blacken',0.8)) g.add(Polygon([x,y,x+_3d_dx,y+_3d_dy,x+w+_3d_dx,y+_3d_dy,x+w,y], strokeColor=strokeColor or c or grey, strokeWidth=strokeWidth, fillColor=fc)) bg = Line(x+_3d_dx,y+_3d_dy, x+w+_3d_dx,y+_3d_dy,strokeWidth=0.5, strokeColor=c) else: bg = None else: bg = Rect(x, y, w, h, strokeColor=strokeColor, strokeWidth=strokeWidth, fillColor=fillColor) if bg: g.add(bg) return g else: return None
def draw(self): fillColor = self.fillColor strokeColor = self.strokeColor g = Group() g.add( Rect(x=0, y=0, fillColor=self.fillColor, strokeColor=self.fillColor, width=self.borderWidth, height=self.height)) g.add( Rect(x=0, y=self.height - self.borderWidth, fillColor=self.fillColor, strokeColor=self.fillColor, width=self.width, height=self.borderWidth)) g2 = Group() rl = RL_CorpLogo() rl.height = 1.25 * cm rl.width = 1.9 * cm rl.draw() g2.add(rl) g.add(g2) g2.shift(x=(self.width - (rl.width + (self.width / 42))), y=(self.height - (rl.height + (self.height / 42)))) g.add( String(x=self.borderWidth / 5.0, y=((self.height - (rl.height + (self.height / 42))) + ((38 / 90.5) * rl.height)), fontSize=6, fillColor=self.altStrokeColor, fontName="Helvetica-BoldOblique", textAnchor='start', text=self._strapline)) leftText = ["Tel:", "Mobile:", "Fax:", "Email:", "Web:"] leftDetails = [ self.telephone, self.mobile, self.fax, self.email, self.web ] leftText.reverse() leftDetails.reverse() for f in range(len(leftText), 0, -1): g.add( String(x=self.borderWidth + (self.borderWidth / 5.0), y=(self.borderWidth / 5.0) + ((f - 1) * (5 * 1.2)), fontSize=5, fillColor=self.strokeColor, fontName="Helvetica", textAnchor='start', text=leftText[f - 1])) g.add( String(x=self.borderWidth + (self.borderWidth / 5.0) + self.borderWidth, y=(self.borderWidth / 5.0) + ((f - 1) * (5 * 1.2)), fontSize=5, fillColor=self.strokeColor, fontName="Helvetica", textAnchor='start', text=leftDetails[f - 1])) ty = (self.height - self.borderWidth - (self.borderWidth / 5.0) + 2) # g.add(Line(self.borderWidth, ty, self.borderWidth+(self.borderWidth/5.0), ty)) # g.add(Line(self.borderWidth+(self.borderWidth/5.0), ty, self.borderWidth+(self.borderWidth/5.0), # ty+(self.borderWidth/5.0))) # g.add(Line(self.borderWidth, ty-10, # self.borderWidth+(self.borderWidth/5.0), ty-10)) rightText = self.rh_blurb_top for f in range(1, (len(rightText) + 1)): g.add( String(x=self.width - (self.borderWidth / 5.0), y=ty - ((f) * (5 * 1.2)), fontSize=5, fillColor=self.strokeColor, fontName="Helvetica", textAnchor='end', text=rightText[f - 1])) g.add( String(x=self.borderWidth + (self.borderWidth / 5.0), y=ty - 10, fontSize=10, fillColor=self.strokeColor, fontName="Helvetica", textAnchor='start', text=self.name)) ty1 = ty - 10 * 1.2 g.add( String(x=self.borderWidth + (self.borderWidth / 5.0), y=ty1 - 8, fontSize=8, fillColor=self.strokeColor, fontName="Helvetica", textAnchor='start', text=self.position)) if self.border: g.add( Rect(x=0, y=0, fillColor=None, strokeColor=black, width=self.width, height=self.height)) g.shift(self.x, self.y) return g
def _Flag_Norway(self): s = _size g = Group() self._width = s * 1.4 box = Rect(0, 0, self._width, s, fillColor=colors.red, strokeColor=colors.black, strokeWidth=0) g.add(box) box = Rect(0, 0, self._width, s, fillColor=colors.red, strokeColor=colors.black, strokeWidth=0) g.add(box) whiteline1 = Rect(((s * 0.2) * 2), 0, width=s * 0.2, height=s, fillColor=colors.ghostwhite, strokeColor=None, strokeWidth=0) g.add(whiteline1) whiteline2 = Rect(0, (s * 0.4), width=self._width, height=s * 0.2, fillColor=colors.ghostwhite, strokeColor=None, strokeWidth=0) g.add(whiteline2) blueline1 = Rect(((s * 0.225) * 2), 0, width=0.1 * s, height=s, fillColor=colors.darkblue, strokeColor=None, strokeWidth=0) g.add(blueline1) blueline2 = Rect(0, (s * 0.45), width=self._width, height=s * 0.1, fillColor=colors.darkblue, strokeColor=None, strokeWidth=0) g.add(blueline2) return g
def convertPath(self, node): d = node.getAttribute('d') if not d: return None normPath = normalise_svg_path(d) path = Path() points = path.points # Track subpaths needing to be closed later unclosed_subpath_pointers = [] subpath_start = [] lastop = '' for i in range(0, len(normPath), 2): op, nums = normPath[i:i+2] if op in ('m', 'M') and i > 0 and path.operators[-1] != _CLOSEPATH: unclosed_subpath_pointers.append(len(path.operators)) # moveto absolute if op == 'M': path.moveTo(*nums) subpath_start = points[-2:] # lineto absolute elif op == 'L': path.lineTo(*nums) # moveto relative elif op == 'm': if len(points) >= 2: if lastop in ('Z', 'z'): starting_point = subpath_start else: starting_point = points[-2:] xn, yn = starting_point[0] + nums[0], starting_point[1] + nums[1] path.moveTo(xn, yn) else: path.moveTo(*nums) subpath_start = points[-2:] # lineto relative elif op == 'l': xn, yn = points[-2] + nums[0], points[-1] + nums[1] path.lineTo(xn, yn) # horizontal/vertical line absolute elif op == 'H': path.lineTo(nums[0], points[-1]) elif op == 'V': path.lineTo(points[-2], nums[0]) # horizontal/vertical line relative elif op == 'h': path.lineTo(points[-2] + nums[0], points[-1]) elif op == 'v': path.lineTo(points[-2], points[-1] + nums[0]) # cubic bezier, absolute elif op == 'C': path.curveTo(*nums) elif op == 'S': x2, y2, xn, yn = nums if len(points) < 4 or lastop not in {'c', 'C', 's', 'S'}: xp, yp, x0, y0 = points[-2:] * 2 else: xp, yp, x0, y0 = points[-4:] xi, yi = x0 + (x0 - xp), y0 + (y0 - yp) path.curveTo(xi, yi, x2, y2, xn, yn) # cubic bezier, relative elif op == 'c': xp, yp = points[-2:] x1, y1, x2, y2, xn, yn = nums path.curveTo(xp + x1, yp + y1, xp + x2, yp + y2, xp + xn, yp + yn) elif op == 's': x2, y2, xn, yn = nums if len(points) < 4 or lastop not in {'c', 'C', 's', 'S'}: xp, yp, x0, y0 = points[-2:] * 2 else: xp, yp, x0, y0 = points[-4:] xi, yi = x0 + (x0 - xp), y0 + (y0 - yp) path.curveTo(xi, yi, x0 + x2, y0 + y2, x0 + xn, y0 + yn) # quadratic bezier, absolute elif op == 'Q': x0, y0 = points[-2:] x1, y1, xn, yn = nums (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \ convert_quadratic_to_cubic_path((x0, y0), (x1, y1), (xn, yn)) path.curveTo(x1, y1, x2, y2, xn, yn) elif op == 'T': if len(points) < 4: xp, yp, x0, y0 = points[-2:] * 2 else: xp, yp, x0, y0 = points[-4:] xi, yi = x0 + (x0 - xp), y0 + (y0 - yp) xn, yn = nums (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \ convert_quadratic_to_cubic_path((x0, y0), (xi, yi), (xn, yn)) path.curveTo(x1, y1, x2, y2, xn, yn) # quadratic bezier, relative elif op == 'q': x0, y0 = points[-2:] x1, y1, xn, yn = nums x1, y1, xn, yn = x0 + x1, y0 + y1, x0 + xn, y0 + yn (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \ convert_quadratic_to_cubic_path((x0, y0), (x1, y1), (xn, yn)) path.curveTo(x1, y1, x2, y2, xn, yn) elif op == 't': if len(points) < 4: xp, yp, x0, y0 = points[-2:] * 2 else: xp, yp, x0, y0 = points[-4:] x0, y0 = points[-2:] xn, yn = nums xn, yn = x0 + xn, y0 + yn xi, yi = x0 + (x0 - xp), y0 + (y0 - yp) (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \ convert_quadratic_to_cubic_path((x0, y0), (xi, yi), (xn, yn)) path.curveTo(x1, y1, x2, y2, xn, yn) # elliptical arc elif op in ('A', 'a'): rx, ry, phi, fA, fS, x2, y2 = nums x1, y1 = points[-2:] if op == 'a': x2 += x1 y2 += y1 if abs(rx) <= 1e-10 or abs(ry) <= 1e-10: path.lineTo(x2, y2) else: bp = bezier_arc_from_end_points(x1, y1, rx, ry, phi, fA, fS, x2, y2) for _, _, x1, y1, x2, y2, xn, yn in bp: path.curveTo(x1, y1, x2, y2, xn, yn) # close path elif op in ('Z', 'z'): path.closePath() else: logger.debug("Suspicious path operator: %s" % op) lastop = op gr = Group() self.applyStyleOnShape(path, node) if path.operators[-1] != _CLOSEPATH: unclosed_subpath_pointers.append(len(path.operators)) if unclosed_subpath_pointers and path.fillColor is not None: # ReportLab doesn't fill unclosed paths, so we are creating a copy # of the path with all subpaths closed, but without stroke. # https://bitbucket.org/rptlab/reportlab/issues/99/ closed_path = NoStrokePath(copy_from=path) for pointer in reversed(unclosed_subpath_pointers): closed_path.operators.insert(pointer, _CLOSEPATH) gr.add(closed_path) path.fillColor = None gr.add(path) return gr
def draw(self): g = Group() g.add(self.makeSectors()) return g
def draw(self): colorNamePairs = self.colorNamePairs autoCP = isAuto(colorNamePairs) if autoCP: chart = getattr(colorNamePairs,'chart',getattr(colorNamePairs,'obj',None)) swatchMarker = None autoCP = Auto(obj=chart) n = chart._seriesCount chartTexts = self._getTexts(colorNamePairs) else: swatchMarker = getattr(self,'swatchMarker',None) if isAuto(swatchMarker): chart = getattr(swatchMarker,'chart',getattr(swatchMarker,'obj',None)) swatchMarker = Auto(obj=chart) n = len(colorNamePairs) dx = self.dx dy = self.dy alignment = self.alignment columnMaximum = self.columnMaximum deltax = self.deltax deltay = self.deltay dxTextSpace = self.dxTextSpace fontName = self.fontName fontSize = self.fontSize fillColor = self.fillColor strokeWidth = self.strokeWidth strokeColor = self.strokeColor leading = fontSize*1.2 yGap = self.yGap if not deltay: deltay = max(dy,leading)+self.autoYPadding ba = self.boxAnchor maxWidth = self._calculateMaxWidth(colorNamePairs) nCols = int((n+columnMaximum-1)/columnMaximum) xW = dx+dxTextSpace+self.autoXPadding variColumn = self.variColumn if variColumn: width = reduce(operator.add,maxWidth,0)+xW*(nCols-1) else: deltax = max(maxWidth+xW,deltax) width = maxWidth+(nCols-1)*deltax maxWidth = nCols*[maxWidth] thisx = self.x thisy = self.y - self.dy if ba not in ('ne','n','nw','autoy'): height = self._calcHeight() if ba in ('e','c','w'): thisy += height/2. else: thisy += height if ba not in ('nw','w','sw','autox'): if ba in ('n','c','s'): thisx -= width/2 else: thisx -= width upperlefty = thisy g = Group() def gAdd(t,g=g,fontName=fontName,fontSize=fontSize,fillColor=fillColor): t.fontName = fontName t.fontSize = fontSize t.fillColor = fillColor return g.add(t) ascent=getFont(fontName).face.ascent/1000. if ascent==0: ascent=0.718 # default (from helvetica) ascent *= fontSize # normalize lim = columnMaximum - 1 callout = getattr(self,'callout',None) dividerLines = self.dividerLines if dividerLines: dividerWidth = self.dividerWidth dividerColor = self.dividerColor dividerDashArray = self.dividerDashArray dividerOffsX = self.dividerOffsX dividerOffsY = self.dividerOffsY for i in xrange(n): if autoCP: col = autoCP col.index = i name = chartTexts[i] else: col, name = colorNamePairs[i] if isAuto(swatchMarker): col = swatchMarker col.index = i if isAuto(name): name = getattr(swatchMarker,'chart',getattr(swatchMarker,'obj',None)).getSeriesName(i,'series %d' % i) T = _getLines(name) S = [] j = int(i/columnMaximum) # thisy+dy/2 = y+leading/2 y = y0 = thisy+(dy-ascent)*0.5 if callout: callout(self,g,thisx,y,(col,name)) if alignment == "left": if isSeqType(name): for t in T[0]: S.append(String(thisx,y,t,fontName=fontName,fontSize=fontSize,fillColor=fillColor, textAnchor = "start")) y -= leading yd = y y = y0 for t in T[1]: S.append(String(thisx+maxWidth[j],y,t,fontName=fontName,fontSize=fontSize,fillColor=fillColor, textAnchor = "end")) y -= leading y = min(yd,y) else: for t in T: # align text to left S.append(String(thisx+maxWidth[j],y,t,fontName=fontName,fontSize=fontSize,fillColor=fillColor, textAnchor = "end")) y -= leading x = thisx+maxWidth[j]+dxTextSpace elif alignment == "right": if isSeqType(name): y0 = y for t in T[0]: S.append(String(thisx+dx+dxTextSpace,y,t,fontName=fontName,fontSize=fontSize,fillColor=fillColor, textAnchor = "start")) y -= leading yd = y y = y0 for t in T[1]: S.append(String(thisx+dx+dxTextSpace+maxWidth[j],y,t,fontName=fontName,fontSize=fontSize,fillColor=fillColor, textAnchor = "end")) y -= leading y = min(yd,y) else: for t in T: # align text to right S.append(String(thisx+dx+dxTextSpace,y,t,fontName=fontName,fontSize=fontSize,fillColor=fillColor, textAnchor = "start")) y -= leading x = thisx else: raise ValueError, "bad alignment" leadingMove = 2*y0-y-thisy if dividerLines: xd = thisx+dx+dxTextSpace+maxWidth[j]+dividerOffsX[1] yd = thisy+dy*0.5+dividerOffsY if ((dividerLines&1) and i%columnMaximum) or ((dividerLines&2) and not i%columnMaximum): g.add(Line(thisx+dividerOffsX[0],yd,xd,yd, strokeColor=dividerColor, strokeWidth=dividerWidth, strokeDashArray=dividerDashArray)) if (dividerLines&4) and (i%columnMaximum==lim or i==(n-1)): yd -= max(deltay,leadingMove)+yGap g.add(Line(thisx+dividerOffsX[0],yd,xd,yd, strokeColor=dividerColor, strokeWidth=dividerWidth, strokeDashArray=dividerDashArray)) # Make a 'normal' color swatch... if isAuto(col): chart = getattr(col,'chart',getattr(col,'obj',None)) g.add(chart.makeSwatchSample(getattr(col,'index',i),x,thisy,dx,dy)) elif isinstance(col, colors.Color): if isSymbol(swatchMarker): g.add(uSymbol2Symbol(swatchMarker,x+dx/2.,thisy+dy/2.,col)) else: g.add(self._defaultSwatch(x,thisy,dx,dy,fillColor=col,strokeWidth=strokeWidth,strokeColor=strokeColor)) else: try: c = copy.deepcopy(col) c.x = x c.y = thisy c.width = dx c.height = dy g.add(c) except: pass map(gAdd,S) if self.colEndCallout and (i%columnMaximum==lim or i==(n-1)): if alignment == "left": xt = thisx else: xt = thisx+dx+dxTextSpace yd = thisy+dy*0.5+dividerOffsY - (max(deltay,leadingMove)+yGap) self.colEndCallout(self, g, thisx, xt, yd, maxWidth[j], maxWidth[j]+dx+dxTextSpace) if i%columnMaximum==lim: if variColumn: thisx += maxWidth[j]+xW else: thisx = thisx+deltax thisy = upperlefty else: thisy = thisy-max(deltay,leadingMove)-yGap 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) _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 convertText(self, node): attrConv = self.attrConverter xml_space = node.getAttribute("{%s}space" % XML_NS) if xml_space: preserve_space = xml_space == 'preserve' else: preserve_space = self.preserve_space gr = Group() frag_lengths = [] dx0, dy0 = 0, 0 x1, y1 = 0, 0 ff = attrConv.findAttr(node, "font-family") or DEFAULT_FONT_NAME ff = attrConv.convertFontFamily(ff) fs = attrConv.findAttr(node, "font-size") or "12" fs = attrConv.convertLength(fs) convertLength = partial(attrConv.convertLength, em_base=fs) x, y = map(node.getAttribute, ('x', 'y')) x, y = map(convertLength, (x, y)) for c in itertools.chain([node], node.getchildren()): has_x, has_y = False, False dx, dy = 0, 0 baseLineShift = 0 if node_name(c) == 'text': text = self.clean_text(c.text, preserve_space) if not text: continue elif node_name(c) == 'tspan': text = self.clean_text(c.text, preserve_space) if not text: continue x1, y1, dx, dy = [ c.attrib.get(name, '') for name in ("x", "y", "dx", "dy") ] has_x, has_y = (x1 != '', y1 != '') x1, y1, dx, dy = map(convertLength, (x1, y1, dx, dy)) dx0 = dx0 + dx dy0 = dy0 + dy baseLineShift = c.attrib.get("baseline-shift", '0') if baseLineShift in ("sub", "super", "baseline"): baseLineShift = { "sub": -fs / 2, "super": fs / 2, "baseline": 0 }[baseLineShift] else: baseLineShift = convertLength(baseLineShift, fs) else: continue frag_lengths.append(stringWidth(text, ff, fs)) new_x = (x1 + dx) if has_x else (x + dx0 + sum(frag_lengths[:-1])) new_y = (y1 + dy) if has_y else (y + dy0) shape = String(new_x, -(new_y - baseLineShift), text) self.applyStyleOnShape(shape, node) if node_name(c) == 'tspan': self.applyStyleOnShape(shape, c) gr.add(shape) gr.scale(1, -1) return gr