Reputation: 348
I have a Spotfire Data function called ARIMA that works beautifully. It mainly needs two equally sized inputs: A column of evenly spaced dates, and a column of order values. My data function can handle input that is out of order or needs to be aggregated but for performance sakes I want to take advantage of the speed at which Spotfire can get that same data into a Cross Table.
Therefore, I need a way to get the values from a Cross table into my data function. Here is what I have so far in IronPython that extracts the actual numbers I need from the Cross Table:
from Spotfire.Dxp.Application.Visuals import CrossTablePlot
from Spotfire.Dxp.Data import IndexSet
from Spotfire.Dxp.Data import RowSelection
from Spotfire.Dxp.Data import DataValueCursor
from Spotfire.Dxp.Data import DataSelection
from datetime import date
from Spotfire.Dxp.Data.Expressions import ColumnExpression
crossTable = visual.As[CrossTablePlot]()
crossSource = crossTable.Data.DataTableReference
##Get a Row Count
rowCount = crossSource.RowCount
##Index Set of all our rows
allRows = IndexSet(rowCount,True)
##Empty Index Set to fill with our desired markings
rowsToMark = IndexSet(rowCount,False)
##Pick the column we're interested in examining for values.
##You can create multiple cursors to look at multiple columns.
##Specify the name of your column (or document property SelectBU).
colCurs = DataValueCursor.CreateFormatted(crossSource.Columns[SelectBU])
dateCurs = DataValueCursor.CreateFormatted(crossSource.Columns["Order Date"])
# Initialize OrderValue and OrderDate lists from cross table data
OrderValue = []
OrderDate = []
#ColumnExpression xColumnExpression = ColumnExpression.Create(context.XAxis.Expression);
OrderValueColumnExpression = ColumnExpression.Create(crossSource.Columns[SelectBU].NameEscapedForExpression)
OrderDateColumnExpression = ColumnExpression.Create(crossSource.Columns["Order Date"].NameEscapedForExpression)
for row in crossSource.GetRows(allRows, colCurs):
OrderValue.append(colCurs.CurrentValue)
for row in crossSource.GetRows(allRows, dateCurs):
dateStr = dateCurs.CurrentValue.split("/")
d =(date(int(dateStr[2]),int(dateStr[0]),int(dateStr[1])))
OrderDate.append(d)
So I have all the info I need in 2 python lists. But I dont know how to feed these in as inputs to a data function. Any ideas? Here is what I've tried:
from Spotfire.Dxp.Data.DataFunctions import DataFunctionExecutorService, DataFunctionInvocation, DataFunctionInvocationBuilder
dataManager = Document.Data
app = Application
dataFunction = None
for function in dataManager.DataFunctions:
if function.Name == 'ARIMA':
dataFunction = function
inputParams = []
inputCollection = dataFunction.Inputs.GetEnumerator()
for inputs in dataFunction.DataFunctionDefinition.InputParameters:
if inputs.DisplayName=="OrderDate":
dataFunction.Inputs.SetInput(inputs, OrderDate)
if inputs.DisplayName=="OrderValue":
dataFunction.Inputs.SetInput(inputs, OrderValue)
dfes = app.GetService(DataFunctionExecutorService)
context = app.ImportContext
invocationBuilder = DataFunctionInvocationBuilder(dataFunction.DataFunctionDefinition, app.ImportContext)
dataFunctionInvocation = invocationBuilder.Build()
print 'Executing...'
dfes.Execute(dataFunctionInvocation)
print 'Done'
I understand why it doesnt work: It's because of the line dataFunction.Inputs.SetInput(inputs, OrderDate)
OrderDate is a python variable for my dates list, but I believe the second argument of SetInput() expects something called an "expression" which I infer to be a Spotfire-like expression. No idea how to work around this so I need help.'
Edit I should add that the above code only has two input parameters: "visual" which is my cross table visual and "SelectBU" which is a document property which points to different numerical columns (BU = Business Units) I can use as my time series.
Upvotes: 2
Views: 1409
Reputation: 348
Here is how I solved the problem:
I wrote a CSV string with all the information I needed and rewrote my data function to only have one parameter (the csv string) which it parses to extract all the info it needs. The way I did this was setting up a document property of type String called csv and used ironpython to set the document property equal to the calculated csv string.
Upvotes: 1