[reportlab-users] circleShadedRect

Dirk Datzert reportlab-users@reportlab.com
Mon, 12 Aug 2002 22:07:05 +0200


Hi,

here is a algorithm to draw a shadedRect with shadedCircle instead of 
ractangles.

Most of the code came from ShadedRect-draw() function which I rewritten
for use of circleShading.

--

Robin,

if I want to add this group to a background of a chart there is a
problem that Circles have no x,y,width,height. So I think that the
PlotArea function draw() must be rewritten to check the variables
x,y,width,height or do a try/except statement on the assignment.

Regards,
Dirk

--


from math import sqrt

from reportlab.graphics.shapes import Group, definePath, Circle,
EmptyClipPath
from reportlab.graphics.widgets.grids import ShadedPolygon, ShadedRect,
frange
from reportlab.lib import colors

def circleShading(points, centerP, fillColorStart=colors.lightblue,
fillColorEnd
=colors.red, strokeColor=colors.black, strokeWidth=1, numShades=10):

        P = points
        P = map(lambda i, P=P:(P[i],P[i+1]),xrange(0,len(P),2))

        radius = 0
        cx = centerP[0]
        cy = centerP[1]

        for p in P:
            radius = max(radius, sqrt((p[0]-cx)**2+(p[1]-cy)**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)

        c0, c1 = fillColorStart, fillColorEnd
        num = float(numShades) # must make it float!
        if numShades == 1:
                V = [radius]
        else:
                V = frange(radius, 0, -radius/num)

        for v in V:
            stripe = Circle(cx,cy,v)
            col = colors.linearlyInterpolatedColor(c0,c1,V[0],V[-1], v)
            stripe.fillColor = col
            stripe.strokeColor = None
            stripe.strokeWidth = 0
            g.add(stripe)

        g.add(EmptyClipPath)
        path = path.copy()
        path.isClipPath = 0
        path.strokeColor = strokeColor
        path.strokeWidth = strokeWidth
        g.add(path)
        return g

The example:

points = [x,y,x+w,y,x+w,y+h,x,y+h]
centerP = (x+w,y+h)
circleShading(points,centerP)

will draw a ShadedRect with width=w,height=h at to coords x,y
The Shading Area will be filled with circles with centre at upper right
corner