def _writeScaleControls(self, theSvg): """Write the text elements that control re-scaling.""" myAttrs = { 'class': self.CLASS_TEXT_SCALE, } myPointP = Coord.Pt( Coord.Dim(8.0, self.COMMON_UNITS), Coord.Dim(4.0, self.COMMON_UNITS), ) with SVGWriter.SVGGroup(theSvg, {'id': 'scaleGroup'}): with SVGWriter.SVGText(theSvg, myPointP, None, None, myAttrs): theSvg.characters('Select scale (bold selected):') myAttrs['text-decoration'] = "underline" myPointP = Coord.newPt(myPointP, incX=Coord.Dim(64, 'mm'), incY=None) for scale in self.SCALE_FACTORS: myAttrs['onclick'] = "scaleGraphic(%s, '%s')" % (scale, scale) myAttrs['id'] = str(scale) if scale == self._scale: myAttrs['font-weight'] = 'bold' else: myAttrs['font-weight'] = 'normal' text = '%d%%' % int(scale * 100) with SVGWriter.SVGText(theSvg, myPointP, None, None, myAttrs): theSvg.characters(text) myPointP = Coord.newPt(myPointP, incX=Coord.Dim(5 * len(text), 'mm'), incY=None)
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 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 _plotFileName(self, theSvg, theDatumL, theTpt): """Writes out the file name adjacent to the file box as static text.""" self.commentFunctionBegin(theSvg, File=self._fileName) if self._bb.hasSetArea: textPointP = self._fileNamePoint(theDatumL, theTpt) assert textPointP is not None myAttrs = { 'class': self.CLASS_VERDANA_12, 'opacity': '1.0', } with SVGWriter.SVGText(theSvg, textPointP, None, None, myAttrs): theSvg.characters(os.path.basename(self.nodeName)) self.commentFunctionEnd(theSvg, File=self._fileName)
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 _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)