Alex Braksator
Alex Braksator

Reputation: 348

Spotfire: Inputting columns from Cross Table into data function

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

Answers (1)

Alex Braksator
Alex Braksator

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

Related Questions