[reportlab-users] ShadedCircle

Dirk Datzert reportlab-users@reportlab.com
Tue, 13 Aug 2002 22:43:42 +0200


Dies ist eine mehrteilige Nachricht im MIME-Format.
--------------390627DC9ECE780F5075240C
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi Robin,

I made radius attribute conform with Circles r-attribute and appended a
class for ShadedEllipse.

Regards,
Dirk
--------------390627DC9ECE780F5075240C
Content-Type: text/plain; charset=us-ascii;
 name="grids.circle-and-ellipse.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="grids.circle-and-ellipse.diff"

--- grids.py.orig	Sun Aug 11 19:27:44 2002
+++ grids.py	Tue Aug 13 22:39:02 2002
@@ -320,6 +318,162 @@
         return group
 
 
+class ShadedCircle(Widget):
+    """This makes a circle with shaded colors between two colors.
+
+    Colors are interpolated linearly between 'fillColorStart'
+    and 'fillColorEnd', both of which appear at the margins.
+    If 'numShades' is set to one, though, only 'fillColorStart'
+    is used.
+    """
+
+    _attrMap = AttrMap(
+        cx = AttrMapValue(isNumber, desc="The circle's center x position."),
+        cy = AttrMapValue(isNumber, desc="The circle's center y position."),
+        r  = AttrMapValue(isNumber, desc="The circle's radius."),
+        numShades = AttrMapValue(isNumber, desc='The number of interpolating colors.'),
+        fillColorStart = AttrMapValue(isColorOrNone, desc='Start value of the color shade.'),
+        fillColorEnd = AttrMapValue(isColorOrNone, desc='End value of the color shade.'),
+        strokeColor = AttrMapValue(isColorOrNone, desc='Color used for border line.'),
+        strokeWidth = AttrMapValue(isNumber, desc='Width used for lines.'),
+        cylinderMode = AttrMapValue(isBoolean, desc='True if shading reverses in middle.'),
+        )
+
+    def __init__(self,**kw):
+        self.cx = 0
+        self.cy = 0
+        self.r = 100
+        self.numShades = 20
+        self.fillColorStart = colors.pink
+        self.fillColorEnd = colors.black
+        self.strokeColor = colors.black
+        self.strokeWidth = 2
+        self.cylinderMode = 0
+        self.setProperties(kw)
+
+    def demo(self):
+        D = Drawing(100, 100)
+        g = ShadedCircle()
+        D.add(g)
+
+        return D
+
+    def draw(self):
+        # general widget bits
+        group = Group()
+        c0, c1 = self.fillColorStart, self.fillColorEnd
+        numShades = self.numShades
+        if self.cylinderMode:
+            if not numShades%2: numShades = numShades+1
+            halfNumShades = (numShades-1)/2 + 1
+        num = float(numShades) # must make it float!
+        if numShades == 1:
+            V = [self.r]
+        else:
+            V = frange(self.r, 0, -self.r/num)
+
+        for v in V:
+            circle = Circle(self.cx,self.cy,v)
+            if self.cylinderMode:
+                if V.index(v)>=halfNumShades:
+                    col = colors.linearlyInterpolatedColor(c1,c0,V[halfNumShades],V[-1], v)
+                else:
+                    col = colors.linearlyInterpolatedColor(c0,c1,V[0],V[halfNumShades], v)
+            else:
+                col = colors.linearlyInterpolatedColor(c0,c1,V[0],V[-1], v)
+            circle.fillColor = col
+            if v == self.r:
+                circle.strokeColor = self.strokeColor
+                circle.strokeWidth = self.strokeWidth
+            else:
+                circle.strokeColor = None
+                circle.strokeWidth = 0
+            group.add(circle)
+
+        return group
+
+
+class ShadedEllipse(Widget):
+    """This makes a ellipse with shaded colors between two colors.
+
+    Colors are interpolated linearly between 'fillColorStart'
+    and 'fillColorEnd', both of which appear at the margins.
+    If 'numShades' is set to one, though, only 'fillColorStart'
+    is used.
+    """
+
+    _attrMap = AttrMap(
+        cx = AttrMapValue(isNumber, desc="The ellipse's center x position."),
+        cy = AttrMapValue(isNumber, desc="The ellipse's center y position."),
+        rx = AttrMapValue(isNumber, desc="The ellipse's radius x direction."),
+        ry = AttrMapValue(isNumber, desc="The ellipse's radius y direction."),
+        numShades = AttrMapValue(isNumber, desc='The number of interpolating colors.'),
+        fillColorStart = AttrMapValue(isColorOrNone, desc='Start value of the color shade.'),
+        fillColorEnd = AttrMapValue(isColorOrNone, desc='End value of the color shade.'),
+        strokeColor = AttrMapValue(isColorOrNone, desc='Color used for border line.'),
+        strokeWidth = AttrMapValue(isNumber, desc='Width used for lines.'),
+        cylinderMode = AttrMapValue(isBoolean, desc='True if shading reverses in middle.'),
+        )
+
+    def __init__(self,**kw):
+        self.cx = 0
+        self.cy = 0
+        self.rx = 100
+        self.ry = 50
+        self.numShades = 20
+        self.fillColorStart = colors.pink
+        self.fillColorEnd = colors.black
+        self.strokeColor = colors.black
+        self.strokeWidth = 2
+        self.cylinderMode = 0
+        self.setProperties(kw)
+
+    def demo(self):
+        D = Drawing(100, 100)
+        g = ShadedCircle()
+        D.add(g)
+
+        return D
+
+    def draw(self):
+        # general widget bits
+        group = Group()
+        c0, c1 = self.fillColorStart, self.fillColorEnd
+        numShades = self.numShades
+        if self.cylinderMode:
+            if not numShades%2: numShades = numShades+1
+            halfNumShades = (numShades-1)/2 + 1
+        num = float(numShades) # must make it float!
+        if numShades == 1:
+            Vx = [self.rx]
+            Vy = [self.ry]
+        else:
+            Vx = frange(self.rx, 0, -self.rx/num)
+            Vy = frange(self.ry, 0, -self.ry/num)
+
+        for i in range(len(Vx)):
+            vx = Vx[i]
+            vy = Vy[i]
+            ellipse = Ellipse(self.cx,self.cy,vx,vy)
+            if self.cylinderMode:
+                if V.index(v)>=halfNumShades:
+                    col = colors.linearlyInterpolatedColor(c1,c0,Vx[halfNumShades],Vx[-1], vx)
+                else:
+                    col = colors.linearlyInterpolatedColor(c0,c1,Vx[0],Vx[halfNumShades], vx)
+            else:
+                col = colors.linearlyInterpolatedColor(c0,c1,Vx[0],Vx[-1], vx)
+            ellipse.fillColor = col
+            if vx == self.rx:
+                ellipse.strokeColor = self.strokeColor
+                ellipse.strokeWidth = self.strokeWidth
+            else:
+                ellipse.strokeColor = None
+                ellipse.strokeWidth = 0
+            group.add(ellipse)
+
+        return group
+
+
 class ShadedRect(Widget):
     """This makes a rectangle with shaded colors between two colors.
 

--------------390627DC9ECE780F5075240C--