Customer Banners (Ads) - SpiceUp. AX and SpotfireX Disclaimer



If you find this site useful and you want to support, buy me a coffee   to keep this site alive and without ads.

Animating Visualizations


1. Create an Action Control Button that applies filter settings, bookmark or what have you  with ironPython
2. Create a script that triggers the Action Control Button button over and over (with optionally start and stop buttons as per the example)





html
<div id='spotfireButton' style='display:none'>
 <SpotfireControl id="y0ursp07f1r3c0n7r01IdH3r3" />
</div>

<SPAN id=startButton>Start</SPAN>
<SPAN id=stopButton style='display:none'>Stop</SPAN>

javascript
var pid
var speed = .5 //change filter 2/second
start = function(){
pid = setInterval(function(){
  $("#spotfireButton input").click()
},speed*1000)
$('#stopButton').show()
$('#startButton').hide()
}

stop = function(){
clearInterval(pid)
  $('#dd').text("stopped " + pid)
$('#stopButton').hide()
$('#startButton').show()
}

$("#stopButton").button().on('click',stop)

$("#startButton").button().on('click',start)

Example with Range Filter


python

#changes RangeFilter low and high bounds in small increments
from Spotfire.Dxp.Application.Filters import RangeFilter, ValueRange
from Spotfire.Dxp.Data import IndexSet

#get a reference to the range filter in question
filt=Document.FilteringSchemes[0].Item[myDataTable].Item[myDataTable.Columns.Item["b"]].As[RangeFilter]()

delta = .1
if(filt.ValueRange.High.ToString() == "High"): #reset filters
idx = IndexSet(myDataTable.RowCount,True)
min = myDataTable.Columns["b"].RowValues.GetMinValue(idx).Value
filt.ValueRange = ValueRange(min,min+delta)
print filt.ValueRange
else:

  filt.StepBodyUp()




Example with Dates

html and javascript are the same, the python code looks like this:


#changes RangeFilter low and high bounds in small increments

from Spotfire.Dxp.Application.Filters import RangeFilter, ValueRange


#startDate and endDate can be script parameters
from Spotfire.Dxp.Data.DataType import Date
startDate=Date.Formatter.Parse("2/1/2015") 
endDate=Date.Formatter.Parse("2/1/2015")

#get a reference to the range filter in question
filt=Document.FilteringSchemes[0].Item[myDataTable].Item[myDataTable.Columns.Item["Date"]].As[RangeFilter]()

#move low and upper bounds one tick up
filt.StepBodyUp()

#reset filters when upper bound reaches the end
if(filt.ValueRange.High.ToString() == "High"): #reset filters
filt.ValueRange = ValueRange(startDate,endDate)




Example with Item Filter

html and javascript are the same, the python code looks like this which requires a document property:

from Spotfire.Dxp.Application.Filters import ItemFilter, ValueRange
from Spotfire.Dxp.Data import IndexSet

#get item myItemFilterer reference
myItemFilter=Document.FilteringSchemes[0].Item[dt].Item[dt.Columns.Item[itemFilterName]].As[ItemFilter]()

#script parameters
dt = Document.Data.Tables["Data Table"]
col = "A" #name of the column that links to the ItemFilter
dp = "cv" #name of document property to hold the selected value

#logic starts here
cv=Document.Properties[dp]

for i in range(len(myItemFilter.Values)):
if myItemFilter.Values[i]==cv: Document.Properties[dp]=myItemFilter.Values[i+1 if i<len(myItemFilter.Values)-1 else 0]
myItemFilter.Value=Document.Properties[dp]
i=i+1


15 comments:

Jolene Robertson said...

Hey Jose, having a bit of trouble with this:
NameError: name 'increment' is not define

Jose Leviaguirre said...

Hello Jolene!

Have you tried set 'increment' as a script parameter? This script takes little increments depending on the nature of your filter.

I try to keep my scripts to the bare bone minimum to show demonstrate the concept. Additional programming is encouraged because of this reason. For example, the script crashes when there are no more available values. It also does not work when the filter being animated is all the way to the left.

Jose.-

Jolene Robertson said...

Thanks for your response! I'm trying to animate using dates, but not having much luck. I tried the parameter, but I'm not quite sure what to use as an increment. I keep getting unsupported operand type(s).

Jose Leviaguirre said...

Jolene, Basically you need to change the date of your filter in increments with scripting. If you can create an action script that can do that with ipython, you are 80% done. Next step is to setup a timer to automatically click such button every x seconds.

Jolene Robertson said...
This comment has been removed by a blog administrator.
Jolene Robertson said...

Ahhh, I got it now. Thanks again :)

secretariadeasustosdocentesrojas said...

Hello,

When I try to do newLow = filt.ValueRange.Low + .01, I have the next error:

TypeError: unsupported operand type(s) for +: 'Endpoint' and 'float'.

Thanks!

Leandro

Jose Leviaguirre said...

Hello Leonardo. If your filter is all the way down, then you cannot perform the addition.

If you want to get the min value of your filter, try this:

from Spotfire.Dxp.Data import IndexSet
idx = IndexSet(myDataTable.RowCount,True)
min = myDataTable.Columns["b"].RowValues.GetMinValue(idx).Value

Now you can set your filter:
filt.ValueRange = ValueRange(min,min+increment)

Is best to use the second example. For numeric ranges, just replace the last four lines of python code with:

if(filt.ValueRange.High.ToString() == "High"): #reset filters
from Spotfire.Dxp.Data import IndexSet
idx = IndexSet(myDataTable.RowCount,True)
min = myDataTable.Columns["b"].RowValues.GetMinValue(idx).Value
filt.ValueRange = ValueRange(min,min+increment)
else:
filt.StepBodyUp()



Unknown said...

Hi Jose,
Very interesting scripts. I have two questions triggered by your example.
1. I have some data I want to animate but with data that is constantly being collected in a SQL table that is being used as a historian. Hence, my data table needs to be refreshed at given intervals. Is that possible to capture in the animation?
2. I have a line chart where I want to color the background of the graph area according to a rule. e.g., if y-axis is between A and B then back color red. I was looking how to implement a X-bar chart coloring the critical zones and not the data points in the line. How can I control that?

Thanks
Juan

Jose Leviaguirre said...

Hola Juan,

Thanks for your comments.

1) I am not sure if its possible to animate data as smooth like that. Spotfire brings all data into memory (all or by chunks) but it does not append or is smart enough to keep data that does not need to be updated. Depending on how often you need to refresh the data and from where there could be other ways. For example, if you want to see updates on a dashboard using webplayer, Scheduled updates can do the trick. There are other tools like EMS or Stream base that might be a better tool.

2) It theory this should be possible in 7.0+ with themes, but it will affect all your visualizations. "If you can do it by hand, it can be scripted" There are hacks for that, but they are often risky to maintain and I am not sure if there is a Spotfire API for that, even by using the SDK. Your best bet is to create a custom visualization using the SDK

Usmclee said...

Jose
First of all thank you for the code it works well for me. I am not very familiar with python. How would you get the range filter to only increase the upper bound on each step as to show the whole data set as it goes through time.

Thanks again for sharing

Unknown said...

Hi Usmclee,

replace StepBodyUp by StepHighLimitUp

Anish said...

Hi,
I am getting an error " MyData Table' is not defined. It will be great if you can help me with this.

Thank You
Best Regards
Anish

Jose Leviaguirre said...

Anish, you need to replace MyDataTable in the code with the name of your data table or rename your data table to "MyDataTable"

Janki said...

I am looking to do this with time within a single day. So move in 15 minute increments from 8am to 8pm as an example. It looks like StepBodyUp is not working with DateTime, unless I am thinking about it incorrectly. Any thoughts on animating by time (minute) increments