Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spotfire IronPython Script to Scroll through a Filter and Update a Visualization Each Step (Play Button through Date Ranges)

Morning Everyone,

I've been working on this issue for a couple of days and I can't figure out a fix. I've researched and googled to no avail. Any help/insight would be greatly appreciated. I am trying to create a button that when clicked will automatically go through a Date filter (starting on 1/1/15 say) and go through 1/2 -1/5 updating a map with the newly filtered marker layer as it steps through the function. I have gotten the filter to step through 1/1-1/5; however, it doesn't update the map visualization as it progresses so all the user sees is a jump from 1/1 to 1/5 with a pause in between (I have a sleep timer in for each step). I've included the code below, I'm just learning IronPython and I'm not sure what I need to call to refresh a visualization. Visualization.Refresh() does not work. Thanks so much!

import Spotfire.Dxp.Application.Filters as filters
import Spotfire.Dxp.Application.Filters.ItemFilter
import time
from Spotfire.Dxp.Application.Filters import FilterTypeIdentifiers
from Spotfire.Dxp.Data import DataProperty, DataType, DataPropertyAttributes, DataPropertyClass
from Spotfire.Dxp.Application.Visuals import MarkerLayer

myPanel = Document.ActivePageReference.FilterPanel
myFilter= myPanel.TableGroups[2].GetFilter("Date (Daily)")

myFilter.FilterReference.TypeId = FilterTypeIdentifiers.ItemFilter
itemFilter = myFilter.FilterReference.As[filters.ItemFilter]()

whichCol = itemFilter.DataColumnReference
count = 0
while count < 5:

    count = count +1
    if (whichCol.Properties.PropertyExists("CurrentStep") == False):
        myProp = DataProperty.CreateCustomPrototype("CurrentStep",0,DataType.Integer,DataPropertyAttributes.IsVisible|DataPropertyAttributes.IsEditable)
        Document.Data.Properties.AddProperty(DataPropertyClass.Column, myProp)
        whichCol.Properties.SetProperty("CurrentStep",0)
        Document.Properties["DateTest"] = "1/1/15" 
        time.sleep(1)

    else:
        time.sleep(1)
        whichVal = whichCol.Properties.GetProperty("CurrentStep")
        #print whichVal
        #print itemFilter.Values.Count
        if (whichVal == itemFilter.Values.Count):
            whichCol.Properties.SetProperty("CurrentStep",0)
            Document.Properties["DateTest"] = "1/1/15"
        else:
            itemFilter.Value = itemFilter.Values.Item[whichVal]
            whichCol.Properties.SetProperty("CurrentStep",whichVal+1)
            Document.Properties["DateTest"] =  itemFilter.Value
like image 565
MLH13 Avatar asked Mar 16 '23 17:03

MLH13


2 Answers

From my understanding, this cannot be done using IronPython. Quoting niko from his answer to a similar question I had: Animating Data Changes in Tibco Spotfire "the IronPython engine locks Spotfire until execution is completed." So I approached your issue in the same fashion I approached my attempt to animate a scatterplot... using JS instead of IP. Since I don't have access to the dataset you are working with, I used a random dataset with an id column that ran from 1-100 instead of dates. I set a data limiting custom expression [id]=${FilterValue} where {FilterValue} is a document property with type of integer set to a default value of 1. I then used the following HTML and JS to iterate the property from 1-100. Note: I did this in SF 7.0 using the "dark" visual theme. In the "light" theme, or in SF 6.X, you will need to define different colors for the button in both the HTML and JS. Upon request I can upload the .dxp to dropbox and share it here. I hope this helps. HTML:

<div id="button1" style="padding: 2px; border: 3px outset grey; border-image: none; text-decoration: none; cursor:pointer;    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;position:relative;
    user-select: none;width:13em;display:block;;"><font color="white" size="2" style="margin:0px 0px 0px 1px">Cycle Filters</font>
</div>


<div id='FilterValue' style='display:none'>
<SpotfireControl id="b986fa43508a484da22f6b42d510061f" />
</div>

JS:

var button=document.getElementById(button1);
var doc=document.getElementById(doc);

t=0;
var CycleFilters = function(){
    if (t<=100)
    {       
        $("#FilterValue input").val(t).blur();
        t+=1;
    }

}




var mouseDown=function()
{
   button.style.background="#202020";
   button.style.border="3px inset grey";
   button.style.padding="4px 0px 0px 4px";
   button.onmouseup=mouseUp;
   button.onmouseout=mouseOut;
   button.onmouseover=mouseOver;

}

function mouseUp() {
    button.style.background="none";
    button.style.border="3px outset grey";
    button.style.padding="2px 2px 2px 2px";
    button.onmouseover=mouseOver2;
    t=0.00;
    setInterval(CycleFilters,1000)
    //document.getElementById('mySpotfireControlx').firstChild.value = 20;
    //$("#mySpotfireControlx input").val(20).blur();
    //document.getElementById('mySpotfireControly').firstChild.value = 10;
    //$("#mySpotfireControly input").val(10).blur();



}
function mouseOut()
{
    button.style.background="none";
    button.style.border="3px outset grey";
    button.style.padding="2px 2px 2px 2px";
}
function mouseOver()
{   
    button.style.background="#202020";
    button.style.border="3px inset grey";
    button.style.padding="4px 0px 0px 4px";
}
function mouseOver2()
{
    button.onmousedown=mouseDown;
}


button.onmouseover=mouseOver2;
button.onmouseout=mouseOut;

document.documentElement.addEventListener('mouseup', function(e)
{
button.onmouseover=mouseOver2;
})
like image 134
Kaorie Avatar answered Mar 19 '23 07:03

Kaorie


enter image description here

You can see the details here on how to animate a Spotfire visualization


  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>

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()

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()
}
s
$("#stopButton").button().on('click',stop)

$("#startButton").button().on('click',start)
like image 30
jleviaguirre Avatar answered Mar 19 '23 05:03

jleviaguirre