Tag: ironpython

Learn IronPython for Spotfire…Navigating the API

Welcome to my second IronPython post this week.  If you missed the first one, start here.  The first post introduced the code and provided information on how to modify it for other use cases.  This post builds on that by focusing on navigating the Spotfire API reference. The next post will then explain how and why the code is written.  A screenshot of the code is shown below, and then we’ll dive into the API.

Code

This code is grabbing a particular filter in the filter panel (a checkbox filter) and unchecking all the boxes.

Walking Thru the API

I am going to walk thru the API one reference at a time.  Note, I am NOT going to explain exactly what the code is doing (yet).  This section will show you where to find the API references, which in turn will show you how to navigate the API.  The next post will explain what the code is doing and why.

Lines 1, 3, 5

Lines 1, 3, and 5 import namespaces and classes from the Spotfire.Dxp.Application.Filters namespace.

Line 1 import Spotfire.Dxp.Application.Filters as filters

Line 1 imports the Spotfire.Dxp.Application.Filters namespace.  If you are in the API reference, this namespace is 8 lines down at the highest level of the hierarchy.  It is also mentioned/linked in the Spotfire.Dxp.Application namespace as shown below.  As you can see in the API reference, this namespace works with filters and filtering schemes in the filter panel.  That is exactly what we are doing – modifying a filter.

Location of namespace.
More specific namespace.

 

Line 3 import Spotfire.Dxp.Application.Filters.CheckBoxFilter

Line 5 from Spotfire.Dxp.Application.Filters import FilterTypeIdentifiers

Lines 3 and 5 import CheckBoxFilter and FilterTypeIdentifiers, which are classes in Spotfire.Dxp.Application.Filters namespace.  Once the class has been added, the developer can reference a class’ properties, methods, fields, etc.

Here’s where to find the classes in the namespace.

Line 7 

Line 7 myPanel = Document.ActivePageReference.FilterPanel

Line 7 references the Document class, which is a class in the Spotfire.Dxp.Application namespace.  The developer didn’t import this namespace because Spotfire imports most of it by default.  ActivePageReference is a property of the Document class. Now, the ActivePageReference gets or sets the currently active Page.  If you are in the API reference and click on Page as circled below, you’ll see this then takes you to the Page class, where Filter Panel is a property.  

Line 9

Line 9 myFilter = myPanel.TableGroups[4].GetFilter("BudgetNode")

Line 7 essentially ends in the Filter Panel.  Then, Line 9 calls the TableGroups property, which is in the FilterPanel class under the Spotfire.Dxp.Application.Filters namespace.  The code also uses the GetFilter method from the FilterGroup class.

Line 11

Line 11 myFilter.FilterReference.TypeId = FilterTypeIdentifiers.CheckBoxFilter

Line 11 references a lot of the API, and this one was a bit confusing at first because I didn’t understand how to move from the filter panel to the actual filter.  TIBCO support helped by showing me this flow chart.  In order to access filters in the filter panel, you must use the TableGroup, even if there is only one table in your DXP.  TableGroup is the path to the FilterHandle, which accesses the filter.

Now, when I was working thru the API, I saw references to the FilterSubGroup, and I wasn’t sure if it was referring to creating a subgroup in the filter panel (select filter in filter panel, right-click, New group) or if it was a different API reference.  Groups in the filter panel would be accessed via TableGroup.SubGroups, but they don’t have to be there.

So, line 11 hits three different classes and multiple properties.  First, it references the FilterReference property in the FilterHandle class.  If you go to the FilterHandle class, you will find the FilterReference property in the API.  This gets the Filter that fits this FilterHandle reference.  If you click on Filter (as circled below), it takes you to the Filter class.  Then the code uses the TypeId property in the Filter class.  That value should equal the CheckBoxFilter field from the FilterTypeIdentifers class.

Line 13

Line 13 checkBoxFilter = myFilter.FilterReference.As[filters.CheckBoxFilter]()

Line 13 is just as busy as Line 11.  It hits the FilterReference property in the FilterHandle class.  That connects with the As method from the Filter class.  Remeber, Line 1 created the filters object, which was equal to the Spotfire.Dxp.Application.Filters namespace, so filters.CheckBoxFilter = Spotfire.Dxp.ApplicationFilters.CheckBoxFilter, which is a reference to the CheckBoxFilter class.

Line 15

Line 15 checkBoxFilter.IncludeEmpty = False

This line uses the IncludeEmpty property, which is in the CheckBoxFilter class.   Can you find this on your own in the API?

Line 17

Line 17 for value in checkBoxFilter.Values:

Here, the code references the Values property of the CheckBoxFilter class. What about this one?  Can you find it on your own in the API?

Line 19

Line 19 checkBoxFilter.Uncheck(value)

Line 19 uses the Uncheck method of the CheckBoxFilter class. Although, note that in this line, checkBoxFilter is an object, not a reference to the class.

Now you know where all of the API references came from!  Before wrapping up, I want to mention that I had to search the API quite a bit.  Now, searching would be easy if the API named all of the properties, methods, fields, classes, etc uniquely.  If my search returned an API result, I would know it is the right reference because there is only one.  Unfortunately, the API is not written that way.  Classes are distinctly named, but other pieces of syntax can have duplicates.  For example, Title is a property of Page, Panel, MapChart, and all other visualization types represented as classes. Keep that in mind as you are exploring (and checking my work).

Summary of API References

If you want to walk thru everything again, here is a summary of the namespaces, classes, properties, methods, and fields used in this code.

  • Spotfire.Dxp.Application namespace
    • Document class
      • ActivePageReference property
    • Page class
      • FilterPanel property
  • Spotfire.Dxp.Application.Filters namespace
    • CheckBoxFilter class
      • IncludeEmpty property
      • Values property
      • Uncheck method
    • Filter class
      • TypeId property
      • As method
    • FilterGroup class
      • GetFilter method
    • FilterHandle class
      • FilterReference property
    • FilterPanel class
      • TableGroups property
    • FilterTypeIdentifiers class
      • CheckBoxFilter field

Conclusion

Unfortunately, there’s a whole lot I haven’t addressed yet.  For example, what if you don’t know the difference between a namespace, property or class? Don’t worry, I’ll get there in a future post.  What if you don’t understand why each piece of the API was called.  I’ll get there too.  This learning process is a long game.  The next post explains how the code is written.

Spotfire Version

Content created with Spotfire 7.12.

Guest Spotfire blogger residing in Whitefish, MT.  Working for SM Energy’s Advanced Analytics and Emerging Technology team!

Learn IronPython for Spotfire…One Code Snippet At A Time

This is going to be a big week of posts, three posts to be exact.  I’m heading to Houston, which means a lot of time on planes and time for writing.  The foundation for the posts is a piece of IronPython code that checks and unchecks the checkboxes in a filter.  I needed code to do this for a project I was working on last week.  A Google search turned up this TIBCO community link.  The second response was exactly what I needed.

Now, I’m on a bit of a learn IronPython kick, and I wanted to understand to how this was written.  I started by looking up each piece of API in TIBCO’s API reference.  In the past, the API reference read like Greek to me.  But walking thru the API one piece at a time, combined with the other 16 hours I’ve put into IronPython, really helped me understand what each line of code was doing.  I got really excited and started writing it up.  Per usual, it was too long.  So, now I’m on a plane breaking it down into 3 posts, for ease of consumption.  Here’s how it’s going to go.

  1. Post 1 (this post) takes a high-level look at the code and explains how to modify it for different use cases. This will familiarize you with the code.  I’ll also talk about objects versus syntax to build on the post I wrote last week on Learning IronPython.
  2. Post 2 will talk about the API in detail by explaining where each piece of the API is and how to navigate to it.
  3. Post 3 (include link) will explain what the code is doing and why. This is something I have shied away from in the past because I didn’t have the understanding to do so.  I’m getting there one code snippet at a time, and you’re coming with me.

We are going to get to the code, but first, I want to clarify my requirements.

Requirements

Ideally, I wanted one piece of code to check and uncheck all the checkboxes.  The TIBCO article presented two code snippets, so I created two buttons with two sets of code, one for checking and another for unchecking.  I’m going with this even though a slightly better iteration would be one code snippet with “IF” logic that looks to see if the boxes are checked and if they are, it unchecks them and vice versa. I’m going with two buttons for now. Gotta walk before you run.

Code Screenshots

Now, you can copy and paste the code from the TIBCO link, so I won’t include that here.  I will show my screenshots so there is no question about spacing.

Check All

Uncheck All

Next, let’s talk about code syntax versus object.

Learning IronPython

Last week, I discussed how to figure out if a particular word in the code is an object the developer created or part of the syntax.  I suggested running a simple test by changing the name of the object.  If the code still runs, it’s an object, not syntax.  To build on that though, the equals sign usually signals an object.  Keywords, like “as”, “for”, and “in” are also indicative an object is coming.

For example, the words circled in the screenshot below were created by the developer.  They could be any word the developer chooses.  Also, all of the other references to Filters are uppercase, indicating they are API references.  That’s not to say that objects can’t be uppercase, but if all the API references are in uppercase, it makes sense to name objects in lowercase.

Now, I don’t want to just show you which parts of the code are objects.  I want to explain why the developer created the objects.  Generally speaking, developers create objects to make referencing things in code easier.  I’ll use “filters” as an example.  This object is only used one other time after creation in line 13.  So, the two lines of code shown below illustrate the difference with and without the object.

Line 13 without an object —

checkBoxFilter = myFilter.FilterReference.As[Spotfire.Dxp.Application.Filters.CheckBoxFilter]()

versus Line 13 with an object —

checkBoxFilter = myFilter.FilterReference.As[filters.CheckBoxFilter]()

Here’s another example using “myPanel” from line 9.

Line 9 without an object —

myFilter = Document.ActivePageReference.FilterPanel.TableGroups[4].GetFilter("BudgetNode")

versus Line 9 with an object —

myFilter = myPanel.TableGroups[4].GetFilter("BudgetNode")

Next, let’s talk about how to modify this code for your own use cases.

Modifying for Different Scenarios

There are four modifications you might want to make to this code.

  1. Obviously, you’ll want to change the column name to your own columns of data.
  2. If there is more than one table in your analysis, you will most likely need to change the TableGroup index.
  3. You might want to account for Empty values.
  4. You might need to check and uncheck more than one filter.

First & Second Modifications

The first modification is the simplest to make.  Just change the column name circled below.  Next, the code “myPanel.TableGroup[4] is telling Spotfire which table to get BudgetNode from.  The number four is an index of table positions in the filter panel. The index values start at zero.  My table is the 5th in the list as shown in the second screenshot below, so I need 4 in the index to get the column from the correct data table in the filter panel.

Third Modification

The third modification relates to what happens when there are empty values in the filter. 

If the Boolean value is set to False, (Empty) will not be unchecked when the button is clicked.  If you want (Empty) to be unchecked, set the value to True.

Line 15 checkBoxFilter.IncludeEmpty = False

Change to…

Line 15 checkBoxFilter.IncludeEmpty = True

 

Modification 4

If you need to uncheck multiple filters, copy and paste lines 9 thru 19.  Then modify the myFilter, checkBoxFilter, and value objects.  Rename them something like mFilter1, checkBoxFilter1, and value1 so that they are their own distinct objects and don’t conflict with previously defined objects. Now, I am going to walk thru the API via this code example.

 

Conclusion

Lastly, you might have noticed the post introduced two code snippets but only followed one thru to this conclusion.  The code snippets are similar enough that you should be able to make the same modifications described for both pieces of code.

The next post is going to dive deep into the API.  Be ready to follow along.  Click here to jump straight to it.

Spotfire Version

Content created with Spotfire 7.12.

 

 

Guest Spotfire blogger residing in Whitefish, MT.  Working for SM Energy’s Advanced Analytics and Emerging Technology team!

Exporting Spotfire to PDF with Action Control Button

Recent Spotfire versions include the ability to export visualizations, pages, or the entire analysis into a PDF from the File menu or even with an Action Control button.  Finally!  Version 7.12 includes extremely user friendly customization options while previous versions require some IronPython code:  we will address both here.

The 7.12 version gives the user an interface for customization that we could previously only access via IronPython.  Spotfire has delivered what many users for years have clamored for, so check it out after the break…

Read More

Jason is a Junior Data Scientist at Ruths.ai with a Master’s degree in Predictive Analytics and Data Science from Northwestern University. He has experience with a multitude of machine learning techniques such as Random Forest, Neural Nets, and Hidden Markov Models. With a previous Master’s in Creative Writing, Jason is a fervent believer in the Oxford comma.

Unscrambling the Spotfire Text Area

  • Are you frustrated with the Spotfire Text Area?
  • Are you just getting started with HTML, CSS, JavaScript, or jQuery?
  • Do you find all the different languages that can be implemented in Text Areas confusing?

Read More

Guest Spotfire blogger residing in Whitefish, MT.  Working for SM Energy’s Advanced Analytics and Emerging Technology team!

During Development, Version-Saving is Key

One of the most frustrating things about Spotfire is when it crashes unexpectedly. This could be a result of a multitude of things unbeknownst to the user. In addition, there is no report to describe what caused the error and crash. Recently, I ran into this issue with a tab (or page) in my dashboard. Spotfire would crash if I:

  • left-clicked on the tab name,
  • tried to navigate to the page using a control property button,
  • or right-clicked on the tab to access the “delete page” option.
Since it’s not a good idea to leave this tab in the dashboard, I had to find a way to delete it. Fortunately, there is a way to do this in IronPython.
By running the following script, I was able to easily delete this “page”.
from Spotfire.Dxp.Application import Document
for page in Application.Document.Pages:</div>
     if (page.Title == 'Page'):
     print page.Id
     Application.Document.Pages.Remove(page)
Luckily, I had been saving previous versions during development and could reference an older version to rebuild this tab.