Suppose I have a visualization that's trellissed by panel by some categorical variable, with one panel per page. I would like to loop over the panels and export each image to a file, with the filename matching the categorical variable.
The image export works totally fine, following some published examples. However, I am having a lot of trouble actually getting the name of the current panel so that I can properly name the image.
Here's my code:
from Spotfire.Dxp.Application.Visuals import VisualContent
from System.Drawing import Bitmap, Graphics, Rectangle, Point
from System.IO import Path
import re
vc=viz.As[VisualContent]() #viz is the visualization parameter passed to the script
trellis=vc.Trellis
originalIndex=trellis.ActivePageIndex
outputDir=Document.Properties["imageOutputDir"]
for i in range(trellis.PageCount):
#move to the right page
trellis.ActivePageIndex=i
#make the actual image -
viz_r = Document.ActivePageReference.GetVisualBounds(viz)
width=viz_r.Width
height=viz_r.Height
bm = Bitmap(width,height)
g = Graphics.FromImage(bm)
g.TextRenderingHint = g.TextRenderingHint.AntiAlias
r=Rectangle(0, 0, width,height)
vc.Render(g, r)
#save the image
name="%d"%i
#here we would like to instead get the current value of the trellis variable!
#name=?
clean_name=re.sub(r'[/\\:*?"<>|]', '_',name)
tempFilename = outputDir+"\\%s.png"%clean_name
bm.Save(tempFilename)
print "image saved as " + tempFilename
trellis.ActivePageIndex=originalIndex
I've seemingly looked through all the methods of VisualContent
and Trellis
and haven't found it.
An alternative is to loop through the data and just get the values of the categorical variable. However, the order is not necessarily preserved, so this doesn't work well. If I can get just the data corresponding to each trellis panel, of course I could work from that.
Here's what I ended up going with. This seems to work when the variable is of type string
and is sorted as standard sort order for datatype
.
If someone can make the sorting more robust, it will certainly be appreciated. I essentially had to figure out the alphanumeric sorting used by spotfire by loading in text data and inspecting the sort. I probably forgot some characters -- this seems to work for now for my data.
I could not access the TryGetCustomSortOrder
method suggested by Niko -- I am working in Spotfire 6.5 and it only became available in 7.0
from Spotfire.Dxp.Application.Visuals import VisualContent
import Spotfire.Dxp.Data.DataTable
from Spotfire.Dxp.Data import *
from System.Drawing import Bitmap, Graphics, Rectangle, Point
from System.IO import Path
import re
vc=viz.As[VisualContent]()
trellis=vc.Trellis
name_column=trellis.PanelAxis.Expression.Trim('<').Trim('>').Trim('[').Trim(']')
#get the unique column values
myTable = Document.ActiveDataTableReference
rowCount = myTable.RowCount
rowsToInclude = Document.ActiveFilteringSelectionReference.GetSelection(myTable).AsIndexSet()
cursor1 = DataValueCursor.Create(myTable.Columns[name_column])
S=set()
for row in myTable.GetRows(rowsToInclude,cursor1):
x=cursor1.CurrentDataValue.Value
if x not in S:
S.add(x)
L=list(S)
alphabet=r' _-,;:!.\'"(){}@*/\&#%`^+<=>|~$0123456789abcdefghijklmnopqrstuvwxyz'
L=sorted(L,key=lambda s:[alphabet.index(c) if c in alphabet else -1 for c in s.lower()])
#things not in alphabet probably unicode characters that get sorted to the beginning
originalIndex=trellis.ActivePageIndex
outputDir=Document.Properties["imageOutputDir"]
for i,name in enumerate(L):
trellis.ActivePageIndex=i
viz_r = Document.ActivePageReference.GetVisualBounds(viz)
width=viz_r.Width
height=viz_r.Height
bm = Bitmap(width,height)
g = Graphics.FromImage(bm)
g.TextRenderingHint = g.TextRenderingHint.AntiAlias
r=Rectangle(0, 0, width,height)
vc.Render(g, r)
clean_name=re.sub(r'[/\\:*?"<>|]', '_',name)
tempFilename = outputDir+"\\%s.png"%clean_name
bm.Save(tempFilename)
print "image saved as " + tempFilename
trellis.ActivePageIndex=originalIndex
I scoured and searched a few times, and finally ended up reaching out to TIBCO support. there is unfortunately no way to access the trellis headers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With