mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-24 08:52:15 +00:00
Added printing requirements
This commit is contained in:
165
reportlab/graphics/charts/dotbox.py
Normal file
165
reportlab/graphics/charts/dotbox.py
Normal file
@@ -0,0 +1,165 @@
|
||||
from reportlab.lib.colors import blue, _PCMYK_black
|
||||
from reportlab.graphics.charts.textlabels import Label
|
||||
from reportlab.graphics.shapes import Circle, Drawing, Group, Line, Rect, String
|
||||
from reportlab.graphics.widgetbase import Widget
|
||||
from reportlab.lib.attrmap import *
|
||||
from reportlab.lib.validators import *
|
||||
from reportlab.lib.units import cm
|
||||
from reportlab.pdfbase.pdfmetrics import getFont
|
||||
from reportlab.graphics.charts.lineplots import _maxWidth
|
||||
|
||||
class DotBox(Widget):
|
||||
"""Returns a dotbox widget."""
|
||||
|
||||
#Doesn't use TypedPropertyCollection for labels - this can be a later improvement
|
||||
_attrMap = AttrMap(
|
||||
xlabels = AttrMapValue(isNoneOrListOfNoneOrStrings,
|
||||
desc="List of text labels for boxes on left hand side"),
|
||||
ylabels = AttrMapValue(isNoneOrListOfNoneOrStrings,
|
||||
desc="Text label for second box on left hand side"),
|
||||
labelFontName = AttrMapValue(isString,
|
||||
desc="Name of font used for the labels"),
|
||||
labelFontSize = AttrMapValue(isNumber,
|
||||
desc="Size of font used for the labels"),
|
||||
labelOffset = AttrMapValue(isNumber,
|
||||
desc="Space between label text and grid edge"),
|
||||
strokeWidth = AttrMapValue(isNumber,
|
||||
desc='Width of the grid and dot outline'),
|
||||
gridDivWidth = AttrMapValue(isNumber,
|
||||
desc="Width of each 'box'"),
|
||||
gridColor = AttrMapValue(isColor,
|
||||
desc='Colour for the box and gridding'),
|
||||
dotDiameter = AttrMapValue(isNumber,
|
||||
desc="Diameter of the circle used for the 'dot'"),
|
||||
dotColor = AttrMapValue(isColor,
|
||||
desc='Colour of the circle on the box'),
|
||||
dotXPosition = AttrMapValue(isNumber,
|
||||
desc='X Position of the circle'),
|
||||
dotYPosition = AttrMapValue(isNumber,
|
||||
desc='X Position of the circle'),
|
||||
x = AttrMapValue(isNumber,
|
||||
desc='X Position of dotbox'),
|
||||
y = AttrMapValue(isNumber,
|
||||
desc='Y Position of dotbox'),
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.xlabels=["Value", "Blend", "Growth"]
|
||||
self.ylabels=["Small", "Medium", "Large"]
|
||||
self.labelFontName = "Helvetica"
|
||||
self.labelFontSize = 6
|
||||
self.labelOffset = 5
|
||||
self.strokeWidth = 0.5
|
||||
self.gridDivWidth=0.5*cm
|
||||
self.gridColor=colors.Color(25/255.0,77/255.0,135/255.0)
|
||||
self.dotDiameter=0.4*cm
|
||||
self.dotColor=colors.Color(232/255.0,224/255.0,119/255.0)
|
||||
self.dotXPosition = 1
|
||||
self.dotYPosition = 1
|
||||
self.x = 30
|
||||
self.y = 5
|
||||
|
||||
|
||||
def _getDrawingDimensions(self):
|
||||
leftPadding=rightPadding=topPadding=bottomPadding=5
|
||||
#find width of grid
|
||||
tx=len(self.xlabels)*self.gridDivWidth
|
||||
#add padding (and offset)
|
||||
tx=tx+leftPadding+rightPadding+self.labelOffset
|
||||
#add in maximum width of text
|
||||
tx=tx+_maxWidth(self.xlabels, self.labelFontName, self.labelFontSize)
|
||||
#find height of grid
|
||||
ty=len(self.ylabels)*self.gridDivWidth
|
||||
#add padding (and offset)
|
||||
ty=ty+topPadding+bottomPadding+self.labelOffset
|
||||
#add in maximum width of text
|
||||
ty=ty+_maxWidth(self.ylabels, self.labelFontName, self.labelFontSize)
|
||||
#print (tx, ty)
|
||||
return (tx,ty)
|
||||
|
||||
def demo(self,drawing=None):
|
||||
if not drawing:
|
||||
tx,ty=self._getDrawingDimensions()
|
||||
drawing = Drawing(tx,ty)
|
||||
drawing.add(self.draw())
|
||||
return drawing
|
||||
|
||||
def draw(self):
|
||||
g = Group()
|
||||
|
||||
#box
|
||||
g.add(Rect(self.x,self.y,len(self.xlabels)*self.gridDivWidth,len(self.ylabels)*self.gridDivWidth,
|
||||
strokeColor=self.gridColor,
|
||||
strokeWidth=self.strokeWidth,
|
||||
fillColor=None))
|
||||
|
||||
#internal gridding
|
||||
for f in range (1,len(self.ylabels)):
|
||||
#horizontal
|
||||
g.add(Line(strokeColor=self.gridColor,
|
||||
strokeWidth=self.strokeWidth,
|
||||
x1 = self.x,
|
||||
y1 = self.y+f*self.gridDivWidth,
|
||||
x2 = self.x+len(self.xlabels)*self.gridDivWidth,
|
||||
y2 = self.y+f*self.gridDivWidth))
|
||||
for f in range (1,len(self.xlabels)):
|
||||
#vertical
|
||||
g.add(Line(strokeColor=self.gridColor,
|
||||
strokeWidth=self.strokeWidth,
|
||||
x1 = self.x+f*self.gridDivWidth,
|
||||
y1 = self.y,
|
||||
x2 = self.x+f*self.gridDivWidth,
|
||||
y2 = self.y+len(self.ylabels)*self.gridDivWidth))
|
||||
|
||||
# draw the 'dot'
|
||||
g.add(Circle(strokeColor=self.gridColor,
|
||||
strokeWidth=self.strokeWidth,
|
||||
fillColor=self.dotColor,
|
||||
cx = self.x+(self.dotXPosition*self.gridDivWidth),
|
||||
cy = self.y+(self.dotYPosition*self.gridDivWidth),
|
||||
r = self.dotDiameter/2.0))
|
||||
|
||||
#used for centering y-labels (below)
|
||||
ascent=getFont(self.labelFontName).face.ascent
|
||||
if ascent==0:
|
||||
ascent=0.718 # default (from helvetica)
|
||||
ascent=ascent*self.labelFontSize # normalize
|
||||
|
||||
#do y-labels
|
||||
if self.ylabels != None:
|
||||
for f in range (len(self.ylabels)-1,-1,-1):
|
||||
if self.ylabels[f]!= None:
|
||||
g.add(String(strokeColor=self.gridColor,
|
||||
text = self.ylabels[f],
|
||||
fontName = self.labelFontName,
|
||||
fontSize = self.labelFontSize,
|
||||
fillColor=_PCMYK_black,
|
||||
x = self.x-self.labelOffset,
|
||||
y = self.y+(f*self.gridDivWidth+(self.gridDivWidth-ascent)/2.0),
|
||||
textAnchor = 'end'))
|
||||
|
||||
#do x-labels
|
||||
if self.xlabels != None:
|
||||
for f in range (0,len(self.xlabels)):
|
||||
if self.xlabels[f]!= None:
|
||||
l=Label()
|
||||
l.x=self.x+(f*self.gridDivWidth)+(self.gridDivWidth+ascent)/2.0
|
||||
l.y=self.y+(len(self.ylabels)*self.gridDivWidth)+self.labelOffset
|
||||
l.angle=90
|
||||
l.textAnchor='start'
|
||||
l.fontName = self.labelFontName
|
||||
l.fontSize = self.labelFontSize
|
||||
l.fillColor = _PCMYK_black
|
||||
l.setText(self.xlabels[f])
|
||||
l.boxAnchor = 'sw'
|
||||
l.draw()
|
||||
g.add(l)
|
||||
|
||||
return g
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
d = DotBox()
|
||||
d.demo().save(fnRoot="dotbox")
|
||||
Reference in New Issue
Block a user