def _plotTextOverlayTokenCountTable(self, theSvg, theDatumL, theTpt): """Plots the token count table as text+alternate text.""" assert (not self.isRoot) self.commentFunctionBegin(theSvg, File=self._fileName) myDatumL = self._bb.plotPointSelf(theDatumL) # Move to center myDatumL = Coord.newPt( myDatumL, incX=self._bb.width, #.scale(0.5), incY=None) # incY=self._bb.depth.scale(0.5)) triggerBoxL = self._bb.box if self.__mustPlotSelfHistogram(): myDatumL = Coord.newPt(myDatumL, None, self.HIST_DEPTH) triggerBoxL = Coord.Box(triggerBoxL.width, triggerBoxL.depth - self.HIST_DEPTH) if self.__mustPlotChildHistogram(): myDatumL = Coord.newPt(myDatumL, None, self.HIST_DEPTH) triggerBoxL = Coord.Box(triggerBoxL.width, triggerBoxL.depth - self.HIST_DEPTH) myDatumP = theTpt.pt(myDatumL) altTextS = self._altTextsForTokenCount() self.writeAltTextAndMouseOverRect( theSvg, theSvg.id, myDatumP, altTextS, myDatumP, theTpt.boxP(triggerBoxL), ) self.commentFunctionEnd(theSvg, File=self._fileName)
def test_07(self): """TestSVGlWriter.test_07(): text. Based on http://www.w3.org/TR/2003/REC-SVG11-20030114/text.html#TextElement""" myF = io.StringIO() myViewPort = Coord.Box( Coord.Dim(12, 'cm'), Coord.Dim(4, 'cm'), ) with SVGWriter.SVGWriter(myF, myViewPort, {'viewBox': "0 0 1000 300"}) as xS: with XmlWrite.Element(xS, 'desc'): xS.characters("Example text01 - 'Hello, out there' in blue") myPt = Coord.Pt(Coord.baseUnitsDim(250), Coord.baseUnitsDim(150)) with SVGWriter.SVGText(xS, myPt, "Verdans", 55, {'fill': "blue"}): xS.characters('Hello, out there') #xS.comment(" Show outline of canvas using 'rect' element ") myPt = Coord.Pt(Coord.baseUnitsDim(1), Coord.baseUnitsDim(1)) myBx = Coord.Box(Coord.baseUnitsDim(998), Coord.baseUnitsDim(298)) with SVGWriter.SVGRect(xS, myPt, myBx, { 'fill': "none", 'stroke': "blue", 'stroke-width': "2" }): pass #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="4.00cm" version="1.1" viewBox="0 0 1000 300" width="12.00cm" xmlns="http://www.w3.org/2000/svg"> <desc>Example text01 - 'Hello, out there' in blue</desc> <text fill="blue" font-family="Verdans" font-size="55" x="250px" y="150px">Hello, out there</text> <rect fill="none" height="298px" stroke="blue" stroke-width="2" width="998px" x="1px" y="1px" /> </svg> """)
def setUp(self): self._canvas = Coord.Box( Coord.Dim(300, None), Coord.Dim(500, None), ) self._box = Coord.Box( Coord.Dim(80, None), Coord.Dim(20, None), )
def test_06(self): """TestSVGlWriter.test_06(): a polygon. Based on http://www.w3.org/TR/2003/REC-SVG11-20030114/shapes.html#PolygonElement""" myF = io.StringIO() myViewPort = Coord.Box( Coord.Dim(12, 'cm'), Coord.Dim(4, 'cm'), ) with SVGWriter.SVGWriter(myF, myViewPort, {'viewBox': "0 0 1200 400"}) as xS: with XmlWrite.Element(xS, 'desc'): xS.characters( 'Example line01 - lines expressed in user coordinates') #xS.comment(" Show outline of canvas using 'rect' element ") myPt = Coord.Pt(Coord.baseUnitsDim(1), Coord.baseUnitsDim(1)) myBx = Coord.Box(Coord.baseUnitsDim(1198), Coord.baseUnitsDim(398)) with SVGWriter.SVGRect(xS, myPt, myBx, { 'fill': "none", 'stroke': "blue", 'stroke-width': "2" }): pass # Make a group with SVGWriter.SVGPolygon(xS, [ Coord.Pt(Coord.baseUnitsDim(350), Coord.baseUnitsDim(75)), Coord.Pt(Coord.baseUnitsDim(379), Coord.baseUnitsDim(161)), Coord.Pt(Coord.baseUnitsDim(469), Coord.baseUnitsDim(161)), Coord.Pt(Coord.baseUnitsDim(397), Coord.baseUnitsDim(215)), Coord.Pt(Coord.baseUnitsDim(423), Coord.baseUnitsDim(301)), Coord.Pt(Coord.baseUnitsDim(350), Coord.baseUnitsDim(250)), Coord.Pt(Coord.baseUnitsDim(277), Coord.baseUnitsDim(301)), Coord.Pt(Coord.baseUnitsDim(303), Coord.baseUnitsDim(215)), Coord.Pt(Coord.baseUnitsDim(231), Coord.baseUnitsDim(161)), Coord.Pt(Coord.baseUnitsDim(321), Coord.baseUnitsDim(161)), ], { 'fill': 'red', 'stroke': 'blue', 'stroke-width': "10" }): pass #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="4.00cm" version="1.1" viewBox="0 0 1200 400" width="12.00cm" xmlns="http://www.w3.org/2000/svg"> <desc>Example line01 - lines expressed in user coordinates</desc> <rect fill="none" height="398px" stroke="blue" stroke-width="2" width="1198px" x="1px" y="1px" /> <polygon fill="red" points="350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161" stroke="blue" stroke-width="10" /> </svg> """)
def _plotHistogram(self, theSvg, theHistDl, theTpt, theTokCounter): myTokCountTotal = theTokCounter.totalAllUnconditional # Avoid divide by zero errors assert (theTokCounter.tokenCountNonWs(isAll=False) > 0) assert (myTokCountTotal > 0) #myPos = Coord.Dim(0, self.COMMON_UNITS) myHistDl = theHistDl #self._bb.plotPointSelf(theDl) for k, myFill in self.HIST_PP_TOKEN_TYPES_COLOURS: tCount = theTokCounter.tokenCount(k, isAll=False) if tCount > 0: myWidth = self._bb.width.scale(tCount / (1.0 * myTokCountTotal)) myBox = Coord.Box(myWidth, self.HIST_DEPTH) # Convert to physical and plot with SVGWriter.SVGRect( theSvg, theTpt.boxDatumP(myHistDl, myBox), theTpt.boxP(myBox), { 'fill': myFill, 'stroke': self.HIST_RECT_COLOUR_STROKE, 'stroke-width': self.HIST_RECT_STROKE_WIDTH, }, ): pass # Increment the datum myHistDl = Coord.newPt(myHistDl, incX=myWidth, incY=None)
def _plotFileNameStackPopup(self, theSvg, theDatumL, theTpt, idStack): """Writes out the file name at the top with a pop-up with the absolute path.""" self.commentFunctionBegin(theSvg, File=self._fileName) if self._bb.hasSetArea: textPointP = self._fileNamePoint(theDatumL, theTpt) assert textPointP is not None # Make the trigger box 14 points high to cover the 12 pt text and # 12pts per char in the triggerBoxP = Coord.Box( Coord.baseUnitsDim(12 * len(os.path.basename(self.nodeName))), Coord.baseUnitsDim(14)) triggerPointP = Coord.newPt( textPointP, triggerBoxP.width.scale(-0.5), triggerBoxP.depth.scale(-0.5), ) self.writeAltTextAndMouseOverRect( theSvg, theSvg.id, textPointP, self._fileIdStackToListOfStr(idStack), triggerPointP, triggerBoxP, ) self.commentFunctionEnd(theSvg, File=self._fileName)
def setUp(self): self._pnbcObj = PlotNode.PlotNodeBboxBoxy() self._pnbcObj.width = Coord.Dim(12, 'mm') self._pnbcObj.depth = Coord.Dim(8, 'mm') #print '\nTRACE self._pnbcObj', self._pnbcObj self._pnbcObj.bbSelfPadding = Coord.Pad( Coord.Dim(1, 'mm'), # prev Coord.Dim(3, 'mm'), # next Coord.Dim(5, 'mm'), # parent Coord.Dim(7, 'mm'), # child ) self._pnbcObj.bbSpaceChildren = Coord.Dim(16, 'mm') self.assertEqual(True, self._pnbcObj.bbChildrenWidth is None) self.assertEqual(True, self._pnbcObj.bbChildrenDepth is None) self.assertEqual(0, self._pnbcObj.numChildren) self._pnbcObj.extendChildBbox( Coord.Box( Coord.Dim(15, 'mm'), Coord.Dim(7, 'mm'), )) # Child box now w:15, d:7 self.assertEqual(1, self._pnbcObj.numChildren) self.assertEqual(self._pnbcObj.bbChildrenWidth, Coord.Dim(15, 'mm')) self.assertEqual(self._pnbcObj.bbChildrenDepth, Coord.Dim(7, 'mm')) self._pnbcObj.extendChildBbox( Coord.Box( Coord.Dim(31, 'mm'), Coord.Dim(29, 'mm'), )) # Child box now w:15+31=46, d:max(7,29)=29 self.assertEqual(2, self._pnbcObj.numChildren) self.assertEqual(self._pnbcObj.bbChildrenWidth, Coord.Dim(46, 'mm')) self.assertEqual(self._pnbcObj.bbChildrenDepth, Coord.Dim(29, 'mm')) self._pnbcObj.extendChildBbox( Coord.Box( Coord.Dim(11, 'mm'), Coord.Dim(9, 'mm'), )) # Child box now w:46+11=57, d:max(29,9)=29 self.assertEqual(3, self._pnbcObj.numChildren) self.assertEqual(self._pnbcObj.bbChildrenWidth, Coord.Dim(57, 'mm')) self.assertEqual(self._pnbcObj.bbChildrenDepth, Coord.Dim(29, 'mm')) # Logical datum self._logicalDatum = Coord.Pt( Coord.Dim(21, 'mm'), Coord.Dim(180, 'mm'), )
def testSigma_03(self): """Tests PlotNode() get sigma width and depth (parent is null node).""" myObj = PlotNode.PlotNodeBbox() myObj.width = None self.assertEqual(myObj.width, None) myObj.depth = None self.assertEqual(myObj.depth, None) myPad = Coord.Pad( Coord.Dim(0.5, 'in'), # prev Coord.Dim(0.5, 'in'), # next Coord.Dim(0.5, 'in'), # parent Coord.Dim(0.5, 'in'), # child ) myObj.bbSelfPadding = myPad myObj.bbSpaceChildren = Coord.Dim(0.5, 'in') self.assertEqual(myObj.bbSpaceChildren, Coord.Dim(0.5, 'in')) myObj.bbChildren = Coord.Box( Coord.Dim(4, 'in'), Coord.Dim(2.5, 'in'), ) self.assertEqual( myObj.bbChildrenWidth, Coord.Dim(4, 'in'), ) self.assertEqual( myObj.bbChildrenDepth, Coord.Dim(2.5, 'in'), ) self.assertEqual(myObj.bbChildren, Coord.Box( Coord.Dim(4, 'in'), Coord.Dim(2.5, 'in'), )) self.assertEqual( myObj.bbSigmaWidth, Coord.Dim(4.0, 'in'), ) self.assertEqual( myObj.bbSigmaDepth, Coord.Dim(2.5, 'in'), ) self.assertEqual( myObj.bbSigma, Coord.Box( Coord.Dim(4.0, 'in'), Coord.Dim(2.5, 'in'), ))
def writeAltTextAndMouseOverRect(self, theSvg, theId, theAltPt, theAltS, theTrigPt, theTrigRect): """Composes and writes the (pop-up) alternate text. Also writes a trigger rectangle.""" # Write a grouping element and give it the alternate ID with SVGWriter.SVGGroup(theSvg, { 'id': 't%s%s' % (theId, self.ALT_ID_SUFFIX), 'opacity': '0.0' }): altFontSize = self.ALT_FONT_PROPERTIES[ self.ALT_FONT_FAMILY]['size'] altFontLenFactor = self.ALT_FONT_PROPERTIES[ self.ALT_FONT_FAMILY]['lenFactor'] altFontHeightFactor = self.ALT_FONT_PROPERTIES[ self.ALT_FONT_FAMILY]['heightFactor'] # Compute masking box for alternate maxChars = max([len(s) for s in theAltS]) # Take around 80% of character length boxWidth = Coord.Dim(altFontSize * maxChars * altFontLenFactor, 'pt') if len(theAltS) < 2: boxHeight = Coord.Dim(altFontSize * 2, 'pt') else: boxHeight = Coord.Dim( altFontSize * len(theAltS) * altFontHeightFactor, 'pt') boxAttrs = {'fill': self.ALT_RECT_FILL} with SVGWriter.SVGRect( theSvg, theAltPt, Coord.Box(boxWidth, boxHeight), boxAttrs, ): pass # As the main text is centered and the alt text is left # justified we need to move the text plot point left by a bit. myAltTextPt = Coord.newPt( theAltPt, incX=Coord.Dim(1 * altFontSize * 3 * altFontLenFactor / 2.0, 'pt'), incY=Coord.Dim(12, 'pt'), ) with SVGWriter.SVGText(theSvg, myAltTextPt, 'Courier', altFontSize, { 'font-weight': "normal", }): self._writeStringListToTspan(theSvg, myAltTextPt, theAltS) # Add the trigger rectangle for writing on finalise boxAttrs = { 'class' : self.CLASS_RECT_INVIS, 'id' : 't%s' % theId, 'onmouseover' : "swapOpacity('t%s', 't%s')" \ % (theId, theId+self.ALT_ID_SUFFIX), 'onmouseout' : "swapOpacity('t%s', 't%s')" \ % (theId, theId+self.ALT_ID_SUFFIX), } self._triggerS.append((theTrigPt, theTrigRect, boxAttrs))
def setUp(self): self._canvas = Coord.Box( Coord.Dim(300, None), Coord.Dim(500, None), ) self._pt = Coord.Pt( Coord.Dim(17, None), Coord.Dim(29, None), )
def testIncWD_right(self): """TestTreePlotTransformBoxP.boxP(): right.""" myObj = TreePlotTransform.TreePlotTransform(self._canvas, rootPos='right') self.assertEqual( myObj.boxP(self._box), Coord.Box( Coord.Dim(20, None), Coord.Dim(80, None), ), )
def testBbChildren(self): """Tests PlotNode() set/get bbChildren.""" myObj = PlotNode.PlotNodeBbox() myObj.bbChildren = Coord.Box( Coord.Dim(1, 'px'), Coord.Dim(2, 'px'), ) self.assertEqual(myObj.bbChildren, Coord.Box( Coord.Dim(1, 'px'), Coord.Dim(2, 'px'), )) self.assertEqual( myObj.bbChildrenWidth, Coord.Dim(1, 'px'), ) self.assertEqual( myObj.bbChildrenDepth, Coord.Dim(2, 'px'), )
def test_02(self): """TestSVGlWriter.test_02(): a circle. From http://www.w3.org/TR/2003/REC-SVG11-20030114/shapes.html#CircleElement""" myF = io.StringIO() myViewPort = Coord.Box( Coord.Dim(12, 'cm'), Coord.Dim(4, 'cm'), ) with SVGWriter.SVGWriter(myF, myViewPort) as xS: with XmlWrite.Element(xS, 'desc'): xS.characters( 'Example circle01 - circle filled with red and stroked with blue' ) #xS.comment(" Show outline of canvas using 'rect' element ") myPt = Coord.Pt(Coord.baseUnitsDim(1), Coord.baseUnitsDim(1)) myBx = Coord.Box(Coord.baseUnitsDim(1198), Coord.baseUnitsDim(398)) with SVGWriter.SVGRect(xS, myPt, myBx, { 'fill': "none", 'stroke': "blue", 'stroke-width': "2" }): pass myPt = Coord.Pt(Coord.baseUnitsDim(600), Coord.baseUnitsDim(200)) myRad = Coord.baseUnitsDim(100) with SVGWriter.SVGCircle(xS, myPt, myRad, { 'fill': "red", 'stroke': "blue", 'stroke-width': "10" }): pass #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="4.00cm" version="1.1" width="12.00cm" xmlns="http://www.w3.org/2000/svg"> <desc>Example circle01 - circle filled with red and stroked with blue</desc> <rect fill="none" height="398px" stroke="blue" stroke-width="2" width="1198px" x="1px" y="1px" /> <circle cx="600px" cy="200px" fill="red" r="100px" stroke="blue" stroke-width="10" /> </svg> """)
def testCanvasP_left(self): """TestTreePlotTransformCanvas.canvasP(): left.""" myO = TreePlotTransform.TreePlotTransform(self._boxDefault, rootPos='left') expValue = Coord.Box( Coord.Dim(500, None), Coord.Dim(300, None), ) self.assertEqual( myO.canvasP(), expValue, )
def setUp(self): self._canvas = Coord.Box( Coord.Dim(300, None), Coord.Dim(800, None), ) self._pt = Coord.Pt( Coord.Dim(400, None), Coord.Dim(250, None), ) self._childIncS = [ Coord.Dim(36, None), Coord.Dim(101, None), Coord.Dim(74, None), ]
def test_00(self): """TestSVGWriter.test_00(): construction.""" myF = io.StringIO() myViewPort = Coord.Box( Coord.Dim(100, 'mm'), Coord.Dim(20, 'mm'), ) with SVGWriter.SVGWriter(myF, myViewPort): pass #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="20.0mm" version="1.1" width="100.0mm" xmlns="http://www.w3.org/2000/svg" />\n""" )
def test_01(self): """TestSVGlWriter.test_01(): <desc> and four rectangles. From second example in http://www.w3.org/TR/2003/REC-SVG11-20030114/struct.html#NewDocumentOverview""" myF = io.StringIO() myViewPort = Coord.Box( Coord.Dim(5, 'cm'), Coord.Dim(4, 'cm'), ) with SVGWriter.SVGWriter(myF, myViewPort) as xS: with XmlWrite.Element(xS, 'desc'): xS.characters('Four separate rectangles') myPt = Coord.Pt(Coord.Dim(0.5, 'cm'), Coord.Dim(0.5, 'cm')) myBx = Coord.Box(Coord.Dim(2.0, 'cm'), Coord.Dim(1.0, 'cm')) with SVGWriter.SVGRect(xS, myPt, myBx): pass myPt = Coord.Pt(Coord.Dim(0.5, 'cm'), Coord.Dim(2.0, 'cm')) myBx = Coord.Box(Coord.Dim(1.0, 'cm'), Coord.Dim(1.5, 'cm')) with SVGWriter.SVGRect(xS, myPt, myBx): pass myPt = Coord.Pt(Coord.Dim(3.0, 'cm'), Coord.Dim(0.5, 'cm')) myBx = Coord.Box(Coord.Dim(1.5, 'cm'), Coord.Dim(2.0, 'cm')) with SVGWriter.SVGRect(xS, myPt, myBx): pass myPt = Coord.Pt(Coord.Dim(3.5, 'cm'), Coord.Dim(3.0, 'cm')) myBx = Coord.Box(Coord.Dim(1.0, 'cm'), Coord.Dim(0.5, 'cm')) with SVGWriter.SVGRect(xS, myPt, myBx): pass myPt = Coord.Pt(Coord.Dim(0.01, 'cm'), Coord.Dim(0.01, 'cm')) myBx = Coord.Box(Coord.Dim(4.98, 'cm'), Coord.Dim(3.98, 'cm')) with SVGWriter.SVGRect(xS, myPt, myBx, attrs={ 'fill': "none", 'stroke': "blue", 'stroke-width': ".02cm", }): pass #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="4.00cm" version="1.1" width="5.00cm" xmlns="http://www.w3.org/2000/svg"> <desc>Four separate rectangles</desc> <rect height="1.00cm" width="2.00cm" x="0.50cm" y="0.50cm" /> <rect height="1.50cm" width="1.00cm" x="0.50cm" y="2.00cm" /> <rect height="2.00cm" width="1.50cm" x="3.00cm" y="0.50cm" /> <rect height="0.50cm" width="1.00cm" x="3.50cm" y="3.00cm" /> <rect fill="none" height="3.98cm" stroke="blue" stroke-width=".02cm" width="4.98cm" x="0.01cm" y="0.01cm" /> </svg> """)
def _plotTextOverlayHistogram(self, theSvg, theHistDl, theTpt): """Plot the text associated with a histogram.""" myCentreL = Coord.newPt(theHistDl, self._bb.width.scale(0.5), self.HIST_DEPTH.scale(0.5)) myPointP = theTpt.pt(myCentreL) # TODO: The myPointP.x.value + 2, myPointP.y.value - 2 # looks wrong. It is not using theTpt. myAttrs = { 'class' : self.CLASS_RECT_INVIS, 'onmouseover' : "showHistogram(%s, %s)" \ % (myPointP.x.value + 3, myPointP.y.value + 2), 'onmouseout' : "hideHistogram()", } myWidth = self._bb.width myBox = Coord.Box(myWidth, self.HIST_DEPTH) with SVGWriter.SVGRect(theSvg, theTpt.boxDatumP(theHistDl, myBox), theTpt.boxP(myBox), myAttrs): pass
def _writeAlternateText(self, theSvg, thePoint, theId, theText, theAltS, yOffs=Coord.Dim(0, 'pt')): """Composes and writes the (pop-up) alternate text. thePoint is the physical point to locate both texts.""" # Write a grouping element and give it the alternate ID with SVGWriter.SVGGroup(theSvg, {'id' : 't%s%s' % (theId, self.ALT_ID_SUFFIX), 'opacity' : '0.0'}): altFontSize = self.ALT_FONT_PROPERTIES[self.ALT_FONT_FAMILY]['size'] altFontLenFactor = self.ALT_FONT_PROPERTIES[self.ALT_FONT_FAMILY]['lenFactor'] altFontHeightFactor = self.ALT_FONT_PROPERTIES[self.ALT_FONT_FAMILY]['heightFactor'] # Compute masking box for alternate maxChars = max([len(s) for s in theAltS]) # Take around 80% of character length boxWidth = Coord.Dim(altFontSize * maxChars * altFontLenFactor, 'pt') if len(theAltS) < 2: boxHeight = Coord.Dim(altFontSize * 2, 'pt') else: boxHeight = Coord.Dim(altFontSize * len(theAltS) * altFontHeightFactor, 'pt') boxAttrs = { 'fill' : self.ALT_RECT_FILL } with SVGWriter.SVGRect( theSvg, # Edge the plot point up and left by a bit Coord.newPt( thePoint, incX=Coord.Dim(-1 * altFontSize * (1 + len(theText) * altFontLenFactor / 2.0), 'pt'), incY=Coord.Dim(-1*altFontHeightFactor * altFontSize, 'pt') + yOffs, ), Coord.Box(boxWidth, boxHeight), boxAttrs, ): pass # As the main text is centered and the alt text is left # justified we need to move the text plot point left by a bit. myAltTextPt = Coord.newPt( thePoint, incX=Coord.Dim(-1 * altFontSize * len(theText) * altFontLenFactor / 2.0, 'pt'), incY=yOffs, ) with SVGWriter.SVGText(theSvg, myAltTextPt, 'Courier', altFontSize, { 'font-weight' : "normal", } ): self._writeStringListToTspan(theSvg, myAltTextPt, theAltS)
def processIncGraphToSvg(theLex, theFilePath, theClass, tptPos, tptSweep): """Convert a Include graph from a PpLexer to SVG in theFilePath.""" myVis = FileIncludeGraph.FigVisitorTree(theClass) theLex.fileIncludeGraphRoot.acceptVisitor(myVis) # Tree is now a graph of: theClass myIgs = myVis.tree() # Pad the canvass myWidth = CANVAS_PADDING.prev \ + myIgs.plotCanvas.width \ + CANVAS_PADDING.next myDepth = CANVAS_PADDING.parent \ + myIgs.plotCanvas.depth \ + CANVAS_PADDING.child # Round up myWidth = Coord.Dim(int(myWidth.value+0.5), myWidth.units) myDepth = Coord.Dim(int(myDepth.value+0.5), myDepth.units) myCanvas = Coord.Box(myWidth, myDepth) #Create a plot configuration myTpt = TreePlotTransform.TreePlotTransform(myCanvas, tptPos, tptSweep) # Write to file myIgs.plotToFilePath(theFilePath, myTpt)
def _plotHistogramLegend(self, theSvg, theTpt): """Plot a standardised legend. This is plotted as a group within a defs.""" myDatumP = Coord.Pt( Coord.Dim(0.0, self.COMMON_UNITS), Coord.Dim(0.0, self.COMMON_UNITS), ) with SVGWriter.SVGGroup(theSvg, { 'id': self.HIST_LEGEND_ID, 'opacity': '0.0' }): idVal = 0 # Outline rectangle with SVGWriter.SVGRect( theSvg, myDatumP, Coord.Box( Coord.Dim(48.0, self.COMMON_UNITS), Coord.Dim(40.0, self.COMMON_UNITS), ), { 'fill': self.ALT_RECT_FILL, 'id': '%d' % idVal, }, ): idVal += 2 myDatumP = Coord.newPt( myDatumP, incX=Coord.Dim(2.0, self.COMMON_UNITS), incY=Coord.Dim(2.0, self.COMMON_UNITS), ) myTokIdxS = list(range(len(self.HIST_PP_TOKEN_TYPES_COLOURS))) if theTpt.positiveSweepDir: myTokIdxS.reverse() for iC in myTokIdxS: myBox = Coord.Box(self.HIST_DEPTH, self.HIST_DEPTH) # Convert to physical and plot with SVGWriter.SVGRect( theSvg, myDatumP, myBox, { 'fill': self.HIST_PP_TOKEN_TYPES_COLOURS[iC][1], 'stroke': self.HIST_RECT_COLOUR_STROKE, 'stroke-width': self.HIST_RECT_STROKE_WIDTH, 'id': '%d' % idVal }, ): idVal += 2 myTextDatumP = Coord.newPt( myDatumP, incX=self.HIST_DEPTH + Coord.Dim(2.0, self.COMMON_UNITS), incY=self.HIST_DEPTH.scale(0.5), ) with SVGWriter.SVGText( theSvg, myTextDatumP, None, None, { 'font-family': 'Verdana', 'font-size': '10', 'dominant-baseline': 'middle', 'id': '%d' % idVal, }): theSvg.characters(self.HIST_PP_TOKEN_TYPES_COLOURS[iC][0]) idVal += 2 # Increment the datum myDatumP = Coord.newPt(myDatumP, incX=None, incY=self.HIST_DEPTH)
def setUp(self): self._boxDefault = Coord.Box( Coord.Dim(300, None), Coord.Dim(500, None), )
def testBbChildren_00(self): """TestPlotNodeBboxWithChildren.testBbChildren_00() - three children.""" myObj = PlotNode.PlotNodeBbox() myObj.width = Coord.Dim(12, 'mm') myObj.depth = Coord.Dim(8, 'mm') #print '\nTRACE myObj', myObj myObj.bbSelfPadding = Coord.Pad( Coord.Dim(1, 'mm'), # prev Coord.Dim(3, 'mm'), # next Coord.Dim(5, 'mm'), # parent Coord.Dim(7, 'mm'), # child ) myObj.bbSpaceChildren = Coord.Dim(16, 'mm') self.assertEqual(True, myObj.bbChildrenWidth is None) self.assertEqual(True, myObj.bbChildrenDepth is None) self.assertEqual(0, myObj.numChildren) myObj.extendChildBbox( Coord.Box( Coord.Dim(15, 'mm'), Coord.Dim(7, 'mm'), )) # Child box now w:15, d:7 self.assertEqual(1, myObj.numChildren) self.assertEqual(myObj.bbChildrenWidth, Coord.Dim(15, 'mm')) self.assertEqual(myObj.bbChildrenDepth, Coord.Dim(7, 'mm')) myObj.extendChildBbox( Coord.Box( Coord.Dim(31, 'mm'), Coord.Dim(29, 'mm'), )) # Child box now w:15+31=46, d:max(7,29)=29 self.assertEqual(2, myObj.numChildren) self.assertEqual(myObj.bbChildrenWidth, Coord.Dim(46, 'mm')) self.assertEqual(myObj.bbChildrenDepth, Coord.Dim(29, 'mm')) myObj.extendChildBbox( Coord.Box( Coord.Dim(11, 'mm'), Coord.Dim(9, 'mm'), )) # Child box now w:46+11=57, d:max(29,9)=29 self.assertEqual(3, myObj.numChildren) self.assertEqual(myObj.bbChildrenWidth, Coord.Dim(57, 'mm')) self.assertEqual(myObj.bbChildrenDepth, Coord.Dim(29, 'mm')) # bbSigma: # Width is 57mm as children are wider than me # Depth is 5 + 8 + 7 + 16 + 29 = 65mm #print #print 'myObj.bbSigma:', myObj.bbSigma self.assertEqual(myObj.bbSigma, Coord.Box( Coord.Dim(57, 'mm'), Coord.Dim(65, 'mm'), )) # Set my datum up myD = Coord.Pt( Coord.Dim(135, 'mm'), Coord.Dim(19, 'mm'), ) # x should be 135 + 0.5 * (57-(1+12+3) + 1) = 135 + 0.5 * 41 + 1 = 156.5 #print #print 'myObj.plotPointSelf:', myObj.plotPointSelf(myD) self.assertEqual( myObj.plotPointSelf(myD), Coord.Pt( Coord.Dim(156.5, 'mm'), Coord.Dim(24, 'mm'), )) #childBboxDatum #print #print 'myObj.childBboxDatum:', myObj.childBboxDatum(myD) self.assertEqual(myObj.childBboxDatum(myD), Coord.Pt( Coord.Dim(135, 'mm'), Coord.Dim(55, 'mm'), ))
def plotToFileObj(self, theFileObj, theTpt): """Root level call to plot to a file object. The SVG stream is created here.""" if self._numPassesToPlotSelf < 1: raise ValueError('No self._numPassesToPlotSelf set!') # Make viewBox user coordinates * self.VIEWBOX_SCALE myRootAttrs = { # 'viewBox' : '0 0 %d %d' \ # % ( # theTpt.canvasP().width.value * self.VIEWBOX_SCALE, # theTpt.canvasP().depth.value * self.VIEWBOX_SCALE, # ), 'xmlns:xlink' : self.NAMESPACE_XLINK, } # Bit of a hacky way to add enough margin for the pop-ups or rather # drop downs. This adds space for the bottom most boxes. canvasY = theTpt.canvasP().depth + Coord.Dim(60, 'mm') + Coord.Dim(8, 'mm') myCanvas = Coord.Box( theTpt.canvasP().width + Coord.Dim(60, 'mm'), canvasY, ) # Shrink canvas if it is a large plot yOffsetForScalingText = Coord.Dim(10, 'mm') scaleIdx = self.SCALE_FACTORS.index(1) assert scaleIdx >= 0 while scaleIdx > 0 and canvasY > self.SCALE_MAX_Y: canvasY = canvasY.scale(0.5) scaleIdx -= 1 self._scale = self.SCALE_FACTORS[scaleIdx] with SVGWriter.SVGWriter(theFileObj, myCanvas, myRootAttrs, mustIndent=cpip.INDENT_ML) as myS: # yOffsetForScalingText is applied wrong, should respect theTpt myDatum = Coord.Pt( CANVAS_PADDING.prev - yOffsetForScalingText, CANVAS_PADDING.parent, ) self.writePreamble(myS) myS.comment(' Root position: %s, Sweep direction: %s canvas=%s datum=%s' \ % (theTpt.rootPos, theTpt.sweepDir, theTpt.canvasP(), myDatum), newLine=True) # Shift the drawing down a bit to make way for the scale buttons. with SVGWriter.SVGGroup(myS, {'transform' : "translate(0, 24)"}): with SVGWriter.SVGGroup(myS, { 'id' : 'graphic', 'transform' : "scale(%s)" % self.SCALE_FACTORS[scaleIdx] }): # Apply a group element for scaling the plot # More hackery: yOffsetForScalingText is applied wrong, should respect theTpt with SVGWriter.SVGRect( myS, Coord.newPt( Coord.zeroBaseUnitsPt(), incX=None, incY=yOffsetForScalingText), theTpt.canvasP(), { 'fill' : 'none', 'stroke' : 'grey', 'stroke-width' : '2', }, ): pass # Start the plot self.plotInitialise(myS, myDatum, theTpt) # Now plot all contents for p in range(self._numPassesToPlotSelf): self.plotToSVGStream(myS, myDatum, theTpt, p, []) # Finish the plot self.plotFinalise(myS, myDatum, theTpt)
def _plotWhereWhyHow(self, theSvg, iChild, theDatumL, theTpt): """Plot description of Where/Why/How inclusion of a single child to a stream at the (self) logical datum point.""" assert (not self.isRoot) assert (len(self._children) > 0) assert (iChild >= 0 and iChild < len(self._children)) self.commentFunctionBegin(theSvg, File=self._fileName) #myDatumL = theDatumL #myDatumL = Coord.newPt(theDatumL, incX=self.FILE_PADDING.prev, incY=None)#self.FILE_PADDING.parent.scale(-1.0)) myDatumL = self._children[iChild].bb.plotPointSelf(theDatumL) # Move logical datum logically 'up' and 'right' by half # myDatumL = Coord.newPt( # myDatumL, # incX=self._children[iChild].bb.width.scale(0.5), # incY=self.FILE_PADDING.parent.scale(-0.5), # ) myAltTxtPointP = theTpt.pt( Coord.newPt( myDatumL, incX=self._children[iChild].bb.width.scale(0.5), incY=self.FILE_PADDING.parent.scale(-0.5), )) altTextS = [] altTextS.append('Where: %s#%d ' \ % (self.nodeName, self._children[iChild].lineNum)) if len(self._children[iChild].condComp) > 0: # altTextS.append( # ' Why: %s since: %s ' \ # % ( # str(self._children[iChild].condCompState), # self._children[iChild].condComp # ) # ) assert self._children[iChild].condCompState altTextS.append( ' Why: %s ' \ % ( self._children[iChild].condComp ) ) else: altTextS.append( ' Why: %s ' \ % (str(self._children[iChild].condCompState) ) ) altTextS.append(' How: #include %s' % ', '.join(self._children[iChild].findLogic)) # self.writeAltTextAndMouseOverText( # theSvg, myPointP, theSvg.id, # self.POPUP_TEXT, altTextS, Coord.Dim(20, 'pt')) triggerBoxP = theTpt.boxP( Coord.Box(self._children[iChild].bb.width, self.FILE_PADDING.parent)) # triggerPointP = theTpt.pt(myDatumL) triggerPointP = theTpt.pt( Coord.newPt( myDatumL, incX=self._children[iChild].bb.width, incY=self.FILE_PADDING.parent.scale(-1.0), )) self.writeAltTextAndMouseOverRect( theSvg, theSvg.id, myAltTxtPointP, altTextS, triggerPointP, triggerBoxP, ) self.commentFunctionEnd(theSvg, File=self._fileName)
def test_05(self): """TestSVGlWriter.test_05(): a polyline. Based on http://www.w3.org/TR/2003/REC-SVG11-20030114/shapes.html#PolylineElement""" myF = io.StringIO() myViewPort = Coord.Box( Coord.Dim(12, 'cm'), Coord.Dim(4, 'cm'), ) with SVGWriter.SVGWriter(myF, myViewPort, {'viewBox': "0 0 1200 400"}) as xS: with XmlWrite.Element(xS, 'desc'): xS.characters( 'Example line01 - lines expressed in user coordinates') #xS.comment(" Show outline of canvas using 'rect' element ") myPt = Coord.Pt(Coord.baseUnitsDim(1), Coord.baseUnitsDim(1)) myBx = Coord.Box(Coord.baseUnitsDim(1198), Coord.baseUnitsDim(398)) with SVGWriter.SVGRect(xS, myPt, myBx, { 'fill': "none", 'stroke': "blue", 'stroke-width': "2" }): pass # Make a group with SVGWriter.SVGPolyline(xS, [ Coord.Pt(Coord.baseUnitsDim(50), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(150), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(150), Coord.baseUnitsDim(325)), Coord.Pt(Coord.baseUnitsDim(250), Coord.baseUnitsDim(325)), Coord.Pt(Coord.baseUnitsDim(250), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(350), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(350), Coord.baseUnitsDim(250)), Coord.Pt(Coord.baseUnitsDim(450), Coord.baseUnitsDim(250)), Coord.Pt(Coord.baseUnitsDim(450), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(550), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(550), Coord.baseUnitsDim(175)), Coord.Pt(Coord.baseUnitsDim(650), Coord.baseUnitsDim(175)), Coord.Pt(Coord.baseUnitsDim(650), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(750), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(750), Coord.baseUnitsDim(100)), Coord.Pt(Coord.baseUnitsDim(850), Coord.baseUnitsDim(100)), Coord.Pt(Coord.baseUnitsDim(850), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(950), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(950), Coord.baseUnitsDim(25)), Coord.Pt(Coord.baseUnitsDim(1050), Coord.baseUnitsDim(25)), Coord.Pt(Coord.baseUnitsDim(1050), Coord.baseUnitsDim(375)), Coord.Pt(Coord.baseUnitsDim(1150), Coord.baseUnitsDim(375)), ], { 'fill': 'none', 'stroke': 'blue', 'stroke-width': "5" }): pass #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="4.00cm" version="1.1" viewBox="0 0 1200 400" width="12.00cm" xmlns="http://www.w3.org/2000/svg"> <desc>Example line01 - lines expressed in user coordinates</desc> <rect fill="none" height="398px" stroke="blue" stroke-width="2" width="1198px" x="1px" y="1px" /> <polyline fill="none" points="50,375 150,375 150,325 250,325 250,375 350,375 350,250 450,250 450,375 550,375 550,175 650,175 650,375 750,375 750,100 850,100 850,375 950,375 950,25 1050,25 1050,375 1150,375" stroke="blue" stroke-width="5" /> </svg> """)
def test_04(self): """TestSVGlWriter.test_04(): a line. Based on http://www.w3.org/TR/2003/REC-SVG11-20030114/shapes.html#LineElement""" myF = io.StringIO() myViewPort = Coord.Box( Coord.Dim(12, 'cm'), Coord.Dim(4, 'cm'), ) with SVGWriter.SVGWriter(myF, myViewPort) as xS: with XmlWrite.Element(xS, 'desc'): xS.characters( 'Example line01 - lines expressed in user coordinates') #xS.comment(" Show outline of canvas using 'rect' element ") myPt = Coord.Pt(Coord.baseUnitsDim(1), Coord.baseUnitsDim(1)) myBx = Coord.Box(Coord.baseUnitsDim(1198), Coord.baseUnitsDim(398)) with SVGWriter.SVGRect(xS, myPt, myBx, { 'fill': "none", 'stroke': "blue", 'stroke-width': "2" }): pass # Make a group with SVGWriter.SVGGroup(xS, {'stroke': 'green'}): with SVGWriter.SVGLine( xS, Coord.Pt(Coord.baseUnitsDim(100), Coord.baseUnitsDim(300)), Coord.Pt(Coord.baseUnitsDim(300), Coord.baseUnitsDim(100)), {'stroke-width': "5"}): pass with SVGWriter.SVGLine( xS, Coord.Pt(Coord.baseUnitsDim(300), Coord.baseUnitsDim(300)), Coord.Pt(Coord.baseUnitsDim(500), Coord.baseUnitsDim(100)), {'stroke-width': "10"}): pass with SVGWriter.SVGLine( xS, Coord.Pt(Coord.baseUnitsDim(500), Coord.baseUnitsDim(300)), Coord.Pt(Coord.baseUnitsDim(700), Coord.baseUnitsDim(100)), {'stroke-width': "15"}): pass with SVGWriter.SVGLine( xS, Coord.Pt(Coord.baseUnitsDim(700), Coord.baseUnitsDim(300)), Coord.Pt(Coord.baseUnitsDim(900), Coord.baseUnitsDim(100)), {'stroke-width': "20"}): pass with SVGWriter.SVGLine( xS, Coord.Pt(Coord.baseUnitsDim(900), Coord.baseUnitsDim(300)), Coord.Pt(Coord.baseUnitsDim(1100), Coord.baseUnitsDim(100)), {'stroke-width': "25"}): pass #print #print myF.getvalue() self.assertEqual( myF.getvalue(), """<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="4.00cm" version="1.1" width="12.00cm" xmlns="http://www.w3.org/2000/svg"> <desc>Example line01 - lines expressed in user coordinates</desc> <rect fill="none" height="398px" stroke="blue" stroke-width="2" width="1198px" x="1px" y="1px" /> <g stroke="green"> <line stroke-width="5" x1="100px" x2="300px" y1="300px" y2="100px" /> <line stroke-width="10" x1="300px" x2="500px" y1="300px" y2="100px" /> <line stroke-width="15" x1="500px" x2="700px" y1="300px" y2="100px" /> <line stroke-width="20" x1="700px" x2="900px" y1="300px" y2="100px" /> <line stroke-width="25" x1="900px" x2="1100px" y1="300px" y2="100px" /> </g> </svg> """)