You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@gump.apache.org by aj...@apache.org on 2004/04/20 19:44:32 UTC
cvs commit: gump/python/gump/svg depdiag.py svg.py drawing.py
ajack 2004/04/20 10:44:32
Modified: python .cvsignore
python/gump/document/forrest xdoc.py documenter.py
python/gump/test drawing.py
python/gump/model depend.py
python/gump/svg depdiag.py svg.py drawing.py
Log:
Tinkering with SVGs...
Revision Changes Path
1.10 +2 -1 gump/python/.cvsignore
Index: .cvsignore
===================================================================
RCS file: /home/cvs/gump/python/.cvsignore,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- .cvsignore 14 Apr 2004 22:32:45 -0000 1.9
+++ .cvsignore 20 Apr 2004 17:44:32 -0000 1.10
@@ -14,4 +14,5 @@
*.log
bogus
gumpy_log.txt
-gumpy.lock
\ No newline at end of file
+gumpy.lock
+*.svg
\ No newline at end of file
1.4 +3 -0 gump/python/gump/document/forrest/xdoc.py
Index: xdoc.py
===================================================================
RCS file: /home/cvs/gump/python/gump/document/forrest/xdoc.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- xdoc.py 14 Apr 2004 23:06:56 -0000 1.3
+++ xdoc.py 20 Apr 2004 17:44:32 -0000 1.4
@@ -308,6 +308,9 @@
def createFork(self,href,text=None):
return self.storePiece(XDocFork(self.createSubContext(),href,text))
+
+ def createIcon(self,href,alt=None):
+ return self.storePiece(XDocIcon(self.createSubContext(),href,alt))
class XDocComment(XDocPiece):
def __init__(self,context,text):
1.7 +49 -26 gump/python/gump/document/forrest/documenter.py
Index: documenter.py
===================================================================
RCS file: /home/cvs/gump/python/gump/document/forrest/documenter.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- documenter.py 19 Apr 2004 15:47:05 -0000 1.6
+++ documenter.py 20 Apr 2004 17:44:32 -0000 1.7
@@ -219,13 +219,17 @@
# Sync over public pages...
#
syncDirectories(stagingDirectory,logDirectory)
- #
- # Clean up
- wipeDirectoryTree(stagingDirectory)
-
- # Clean only if successful.
- if (forrestResult.state==CMD_STATE_SUCCESS):
- wipeDirectoryTree(forrestWorkDir)
+
+ cleanUp=0
+
+ if cleanUp:
+ #
+ # Clean up
+ wipeDirectoryTree(stagingDirectory)
+
+ # Clean only if successful.
+ if (forrestResult.state==CMD_STATE_SUCCESS):
+ wipeDirectoryTree(forrestWorkDir)
except:
log.error('--- Failed to staging->log sync and/or clean-up', exc_info=1)
success=0
@@ -1518,7 +1522,7 @@
statsTable=statsSection.createTable()
# Generate an SVG for FOG:
- (pngFile,pngTitle) = self.documentFOG(project)
+ (pngFile,pngTitle) = self.diagramFOG(project)
if pngFile:
statsTable.createEntry('FOG Factor').createData().createIcon(pngFile,pngTitle)
@@ -1541,16 +1545,16 @@
self.documentFileList(run,document,project,'Project-level Files')
self.documentWorkList(run,document,project,'Project-level Work')
- #addnSection=document.createSection('Additional Details')
- #addnPara=addnSection.createParagraph()
- #addnPara.createLink(gumpSafeName(project.getName()) + '_details.html', \
- # 'More project details ...')
- #document.serialize()
- #
- #document=XDocDocument('Project Details : ' + project.getName(), \
- # self.resolver.getFile(project, \
- # project.getName() + '_details', \
- # '.xml'))
+ addnSection=document.createSection('Additional Details')
+ addnPara=addnSection.createParagraph()
+ addnPara.createLink(gumpSafeName(project.getName()) + '_details.html', \
+ 'For additional project details (including dependencies) ...')
+ document.serialize()
+
+ document=XDocDocument('Project Details : ' + project.getName(), \
+ self.resolver.getFile(project, \
+ project.getName() + '_details', \
+ '.xml'))
# x.write('<p><strong>Project Config :</strong> <link href=\'%s\'>XML</link></p>' \
# % (getModuleProjectRelativeUrl(modulename,project.name)) )
@@ -1636,7 +1640,15 @@
dependencySection.createNote('No projects depend upon this project.')
if not depens:
dependencySection.createNote('This project depends upon no others.')
-
+
+ try:
+ # Generate an SVG for FOG:
+ (pngFile,pngTitle) = self.diagramDependencies(project)
+ if pngFile:
+ para=dependencySection.createSection('Dependency Diagram').createParagraph()
+ para.createFork(pngFile).createIcon(pngFile,pngTitle)
+ except:
+ log.error('Failed to diagram dependencies for [' + project.getName() + ']', exc_info=1)
document.serialize()
@@ -2194,7 +2206,7 @@
fdocument.serialize()
fdocument=None
- def documentFOG(self,object,base=None):
+ def diagramFOG(self,object,base=None):
stats = object.getStats()
name=object.getName()
@@ -2214,6 +2226,20 @@
return (None, None)
+ def diagramDependencies(self,project,base=None):
+
+ name=project.getName()
+ if not base: base=project
+
+ svgFile=self.resolver.getFile(base,name+'_depend','.svg')
+ pngFile=os.path.basename(svgFile).replace('.svg','.png')
+ from gump.svg.depdiag import DependencyDiagram
+ diagram=DependencyDiagram(project)
+ diagram.compute()
+ diagram.generateDiagram().serializeToFile(svgFile)
+
+ return (pngFile, 'Dependency Diagram')
+
#####################################################################
#
# Helper Methods
@@ -2639,16 +2665,13 @@
fogRow.createData(pstats.failures)
fogRow.createData(pstats.prereqs)
fogRow.createData('%02.2f' % pstats.getFOGFactor())
-
-
+
# Generate an SVG for FOG:
- (pngFile,pngTitle) = self.documentFOG(project,stats)
+ (pngFile,pngTitle) = self.diagramFOG(project,stats)
if pngFile:
fogRow.createData().createIcon(pngFile,pngTitle)
else:
- fogRow.createData('Not Available')
-
-
+ fogRow.createData('Not Available')
document.serialize()
1.3 +4 -4 gump/python/gump/test/drawing.py
Index: drawing.py
===================================================================
RCS file: /home/cvs/gump/python/gump/test/drawing.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- drawing.py 14 Apr 2004 22:12:57 -0000 1.2
+++ drawing.py 20 Apr 2004 17:44:32 -0000 1.3
@@ -50,7 +50,7 @@
self.assertEqual('Shifted & Scaled', 125, y)
def testGridDrawingContext(self):
- baseContext=StandardDrawingContext(rect=Rect(0,0,100,100))
+ baseContext=StandardDrawingContext(rect=Rect(0,0,100,200))
context=GridDrawingContext('TestGrid',baseContext,10,10)
for row in [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]:
for col in [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]:
@@ -59,10 +59,10 @@
# Calculate expected
expectedX=(row*10)+5
- expectedY=(col*10)+5
+ expectedY=(col*20)+10
- print `(row,col)`
- print `(x,y)`
+ #print `(row,col)`
+ #print `(x,y)`
# Check...
self.assertEqual('Grid', expectedX, x)
1.26 +2 -2 gump/python/gump/model/depend.py
Index: depend.py
===================================================================
RCS file: /home/cvs/gump/python/gump/model/depend.py,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- depend.py 31 Mar 2004 17:41:41 -0000 1.25
+++ depend.py 20 Apr 2004 17:44:32 -0000 1.26
@@ -314,10 +314,10 @@
#
def getDependencyDepth(self):
if self.depth: return self.depth
- maxDepth=1
+ maxDepth=0
for depend in self.directDependencies.getDepends():
dependencyDepth=depend.getProject().getDependencyDepth() + 1
- if maxDepth < dependencyDepth:
+ if maxDepth < dependencyDepth:
maxDepth=dependencyDepth
self.depth=maxDepth
return self.depth
1.7 +37 -31 gump/python/gump/svg/depdiag.py
Index: depdiag.py
===================================================================
RCS file: /home/cvs/gump/python/gump/svg/depdiag.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- depdiag.py 16 Apr 2004 17:28:42 -0000 1.6
+++ depdiag.py 20 Apr 2004 17:44:32 -0000 1.7
@@ -71,6 +71,7 @@
# Create a sparse matrix
self.depths={}
+ self.maxDepth=0
self.maxNumAtDepth=0
# Create a lookup
@@ -98,7 +99,7 @@
for rowNo in self.depths.keys():
colNo=0
for node in self.depths[rowNo]:
- node.setRowCol(rowNo-1,colNo)
+ node.setRowCol(rowNo,colNo)
colNo+=1
# Insert into lists
@@ -114,17 +115,21 @@
depthList=self.depths[depth]
depthList.append(node)
- # Keep track of
+ # Keep track of ...
numAtDepth=len(depthList)
if (numAtDepth > self.maxNumAtDepth):
- self.maxNumAtDepth=numAtDepth
+ self.maxNumAtDepth=numAtDepth
+
+ # Keep track of ...
+ if (depth > self.maxDepth):
+ self.maxDepth=depth
# Lookups
self.nodes[project]=node
def getExtent(self):
# Max by max
- return (len(self.depths.keys()),self.maxNumAtDepth)
+ return (self.maxDepth+1,self.maxNumAtDepth)
def getRowWidth(self,row):
return len(self.depths[row])
@@ -168,21 +173,28 @@
# Get the maximum rows/cols
(rows, cols) = self.matrix.getExtent()
- mainContext=StandardDrawingContext('Dependencies', None, \
- Rect(0,0,100*rows,100*cols))
-
- # Let the context define the rect.
- rect=mainContext.realRect()
-
- print 'RECT: ' + str(rect)
- print '(ROWS,COLS) : ' + `(rows, cols)`
+ # The drawing plane
+ absoluteRect=Rect(0,0,100*cols,100*rows)
- context=GridDrawingContext('Grid', mainContext, rows, cols )
+ # The standard context for that plane
+ mainContext=StandardDrawingContext('Dependencies', None,
+ absoluteRect)
+
+ #print 'RECT: ' + str(absoluteRect)
+ #print '(ROWS,COLS) : ' + `(rows, cols)`
+
+ context=SwitchAxisDrawingContext('Switch',
+ YInvertDrawingContext('Invert',
+ GridDrawingContext('Grid', mainContext, cols, rows ),
+ rows - 1 ) )
# Build an SVG to fit the real world size, and the
# context rectangle.
- svg=SimpleSvg(rect.getWidth(),rect.getHeight())
+ svg=SimpleSvg(absoluteRect.getWidth(), absoluteRect.getHeight())
+ #
+ # Add a border
+ #
svg.addBorder()
#
@@ -198,16 +210,10 @@
#print cols,rowWidth,row,col,' -> ',centeredCol
- print '(ROW,COL) : ' + `(row, col)`
- (x,y) = context.realPoint(col,(rows-row)+2)
- print '(X,Y) : ' + `(x, y)`
- node.setPoint(Point(x,y))
-
- for x in range(0,rows):
- for y in range(0,cols):
- print 'DOTTY : ' + `(x,y)`
- (x1,y1)=context.realPoint(x,y)
- svg.addSpot(x1,y1)
+ #print 'NODE (ROW,COL) : ' + `(row, col)`
+ (x,y) = context.realPoint(row,col)
+ #print '(X,Y) : ' + `(x, y)`
+ node.setPoint(Point(x,y))
#
# Draw dependency lines
@@ -240,7 +246,7 @@
elif project.getFOGFactor() < 0.1:
color='red'
- print 'LINE %s,%s -> %s,%s' % (x,y,x1,y1)
+ #print 'LINE %s,%s -> %s,%s' % (x,y,x1,y1)
svg.addLine(x,y,x1,y1, \
{ 'stroke':color, \
'stroke-width':width, \
@@ -253,10 +259,10 @@
project = node.getProject()
(row, col) = node.getRowCol()
- (x,y) = context.realPoint(col-0.25,(rows-row)+2-0.25)
- (x1,y1) = context.realPoint(col+0.25,(rows-row)+2+0.25)
+ (x,y) = context.realPoint(row+0.25,col-0.25)
+ (x1,y1) = context.realPoint(row-0.25,col+0.25)
- print 'RECTANGLE %s,%s -> %s,%s' % (x,y,x1,y1)
+ #print 'RECTANGLE %s,%s -> %s,%s' % (x,y,x1,y1)
# Shape color
color='green'
@@ -271,8 +277,8 @@
{ 'fill':color, \
'comment':project.getName() } )
- (x,y) = context.realPoint(col-0.25,(rows-row)+2-0.27)
- print 'TEXT %s,%s' % (x,y)
+ (x,y) = context.realPoint(row+0.27,col-0.27)
+ #print 'TEXT %s,%s' % (x,y)
svg.addText(x,y,project.getName() + ' (' + `project.getFOGFactor()` + ')', \
{ 'fill':'red', \
@@ -287,7 +293,7 @@
from gump.core.gumprun import GumpRun, GumpRunOptions, GumpSet
from gump.core.commandLine import handleArgv
- from gump.core.model.loader import WorkspaceLoader
+ from gump.model.loader import WorkspaceLoader
from gump.output.statsdb import *
# Process command line
1.6 +19 -8 gump/python/gump/svg/svg.py
Index: svg.py
===================================================================
RCS file: /home/cvs/gump/python/gump/svg/svg.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- svg.py 16 Apr 2004 17:28:42 -0000 1.5
+++ svg.py 20 Apr 2004 17:44:32 -0000 1.6
@@ -102,9 +102,10 @@
# Assume the pixels are at least an order of
# magnitude larger than we'd like this in
- # centimeters
- svgW=int(w/10)
- svgH=int(h/10)
+ # centimeters. :TODO: Unhack these values,
+ # which basically work for DepDiag only...
+ svgW=int(w/30)
+ svgH=int(h/30)
if svgW > 20:
ratio = float(svgW)/20
@@ -173,13 +174,23 @@
self.actions.append(self.formatElement(type,attrs,content))
def addBorder(self):
- x=self.viewWidth*0.05
- y=self.viewHeight*0.05
- w=min(self.viewWidth*0.02,self.viewHeight*0.02)
- self.addRect(x,y,self.viewWidth-(2*x),self.viewHeight-(2*y), \
+
+ # Make stroke width proportional, but not greater than 1
+ w=min(self.viewWidth*0.01,self.viewHeight*0.01)
+ if w > 1: w = 1
+ self.addRect(w,w,self.viewWidth-w,self.viewHeight-w, \
{'stroke':'black','stroke-width':w,'fill':'none', \
'comment':'Border Rectangle'})
-
+
+
+ #print '(ROWS,COLS) : ' + `(rows, cols)`
+ #for r in range(0,rows):
+ # for c in range(0,cols):
+ # print 'DOTTY (ROW,COL): ' + `(r,c)`
+ # (x,y)=context.realPoint(r,c)
+ # svg.addSpot(x,y)
+ # svg.addText(x,y, `(r,c)`, {'stroke':'black'})
+
def addSpot(self,x,y):
self.addRect(x-2,y-2,4,4, \
{'stroke':'black','stroke-width':1,'fill':'black', \
1.5 +65 -5 gump/python/gump/svg/drawing.py
Index: drawing.py
===================================================================
RCS file: /home/cvs/gump/python/gump/svg/drawing.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- drawing.py 15 Apr 2004 17:26:07 -0000 1.4
+++ drawing.py 20 Apr 2004 17:44:32 -0000 1.5
@@ -89,7 +89,7 @@
class DrawingContext:
""" The interface to a chainable context """
- def __init__(self,name=None,next=None) :
+ def __init__(self,name,next=None) :
self.name=name
self.next=next
@@ -110,6 +110,7 @@
# Calculate (or pass though)
if hasattr(self,'getRealPoint')and callable(self.getRealPoint):
(x1,y1)=self.getRealPoint(x,y)
+ #log.debug(`self.name` + ' : ' + `(x,y)` + ' -> ' + `(x1,y1)`)
else:
(x1,y1)=(x,y)
@@ -145,7 +146,7 @@
class StandardDrawingContext(DrawingContext):
""" A drawing context, is an area width*height """
- def __init__(self,name=None,context=None,rect=None):
+ def __init__(self,name,context=None,rect=None):
DrawingContext.__init__(self,name,context)
if rect: self.rect=rect
@@ -169,7 +170,7 @@
output.write(getIndent(indent)+'Height : ' + `self.getHeight()` + '\n')
class ScaledDrawingContext(StandardDrawingContext):
- def __init__(self,name=None,context=None,rect=None,scaledWidth=1,scaledHeight=1):
+ def __init__(self,name,context=None,rect=None,scaledWidth=1,scaledHeight=1):
StandardDrawingContext.__init__(self,name,context,rect)
if not scaledWidth: raise RuntimeError, 'Can\'t scale with 0 width.'
@@ -197,7 +198,7 @@
output.write(getIndent(indent)+'hRatio : ' + `self.hRatio` + '\n')
class ShiftedDrawingContext(StandardDrawingContext):
- def __init__(self,name=None,context=None,shiftedX=0,shiftedY=0):
+ def __init__(self,name,context=None,shiftedX=0,shiftedY=0):
StandardDrawingContext.__init__(self,name,context)
if not (shiftedX or shiftedY):
@@ -224,11 +225,14 @@
middle of their blocks. E.g. 0,0 -> 5,5 (with units of 10 points)
"""
- def __init__(self,name=None,context=None,rows=10,cols=10):
+ def __init__(self,name,context=None,rows=10,cols=10):
# Initiaze w/o sub-context
DrawingContext.__init__(self,name)
+ self.rows=rows
+ self.cols=cols
+
# Create the scale
self.scale=ScaledDrawingContext('GridScale:'+name,context,None,rows,cols)
@@ -238,6 +242,24 @@
# Install this context...
self.setNextContext(self.shift)
+ def getRealPoint(self,x,y):
+ #if not x == int(x):
+ # raise RuntimeError, 'X isn\'t an integer [' + `x` + ']'
+ #
+ #if not y == int(y):
+ # raise RuntimeError, 'Y isn\'t an integer [' + `y` + ']'
+
+ return (x,y)
+
+ xrange=range(0,self.rows)
+ if not x in xrange:
+ raise RuntimeError, 'X isn\'t in range [' + `x` + '] [' + `xrange` + ']'
+
+ yrange=range(0,self.cols)
+ if not y in yrange:
+ raise RuntimeError, 'Y isn\'t in range [' + `y` + '] [' + `yrange` + ']'
+
+ return (x,y)
# def generateRowContexts(self,context):
# rowContexts={}
@@ -264,6 +286,44 @@
# row+=1
#
# return rowContexts
+
+class XInvertDrawingContext(DrawingContext):
+ """
+ Invert X
+ """
+ def __init__(self,name,context,maxX):
+
+ # Initiaze w/o sub-context
+ DrawingContext.__init__(self,name)
+ self.maxX=maxX
+
+ def getRealPoint(self,x,y):
+ return (self.maxX - x,y)
+
+class YInvertDrawingContext(DrawingContext):
+ """
+ Invert Y
+ """
+ def __init__(self,name,context,maxY):
+
+ # Initiaze w/o sub-context
+ DrawingContext.__init__(self,name,context)
+ self.maxY=maxY
+
+ def getRealPoint(self,x,y):
+ return (x,self.maxY-y)
+
+class SwitchAxisDrawingContext(DrawingContext):
+ """
+ Invert Y
+ """
+ def __init__(self,name,context):
+
+ # Initiaze w/o sub-context
+ DrawingContext.__init__(self,name,context)
+
+ def getRealPoint(self,x,y):
+ return (y,x)
class VirtualPoint:
def __init__(self,x,y,context):
---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
For additional commands, e-mail: general-help@gump.apache.org