Utilizing Space under Legends for Additional Information

Have you ever struggled for little space for placing information and Just observed -"Hey! I have some under Legends!". But, That area is not available for editing
What to do ?
Well, Remember I have shared a post about adding Information to Menu bar ? I have customized that to add some extra stuffs. We will create a button on Menu bar, which will bring some extra information under selected legend (eq(2)in code is 3rd legend item of the page here).

Add this code to a JavaScript -
if(!$('#AlienBox').length){
$('body').append($(`<style id="AlienBox">
#Brand {
    position: absolute;
    top: 0px;
    right: 40%;
    height: 30px;
    width: 150px;
    z-index: 99;
border: 1px solid chocolate;
border-radius :5px;
color:chocolate;
}

</style>`, {
        id: 'AlienBox' 
   }));
}

if(!$('#Brand').length){
$('body').append($(`<div id="Brand">
<center> For Information  <br> <button onclick="alienLegendFn()" style="background-color: chocolate;border: none;  color: white;   text-decoration: none;  display: inline-block; ">Click Here</button> </center>
<script >
  function alienLegendFn() {
  if(!$('#AlienLegend').length){
$('.sf-element-legend-item:eq(2)').append($('<div id="AlienLegend" style = "border: 1px solid chocolate; border-radius :5px; color:chocolate;"> You can place addional information here </div>', {
        id: 'AlienLegend' 
   }));
}

   </script>
</div>
`, {
        id: 'Brand' 
   }));  
}

Here is what you expect after clicking newly created button -
Share:

Add a Little Information to the Menu Bar

When I launched Spotfire today, I saw this menu bar-
Everything is right, but I felt I should add a little fun to this space. I tried to to add some information to it, and I think we can use same for Adding Dashboard Title as well (Anyways this bar remains there regardless of we use it or not) -

Here is how to achieve this -

  1. Add JavaScript to text area.
  2. Customize segment <div id="Brand"> as per your need.
  3. Paste below code (after customization) and save.

if(!$('#AlienBox').length){
$('body').append($(`<style id="AlienBox">
#Brand {
    position: absolute;
    top: 0px;
    right: 40%;
    height: 30px;
    width: 100px;
    z-index: 99;
border: 1px solid chocolate;
border-radius :5px;
color:chocolate;
}

</style>`, {
        id: 'AlienBox' 
   }));
}

if(!$('#Brand').length){
$('body').append($(`<div id="Brand">
<center> Designed by <br><b>Vivek Kumar</b> </center>
</div>`, {
        id: 'Brand' 
   }));
}
Share:

Deleting All visualizations meeting a Specific Condition

How to remove all visualizations meeting one criteria ?
Deleting Visualizations may be very useful in many situations. One example is, if we want to remove all Line Charts (may be I am not interested in trends at the moment). This is how it can be achieved -
from Spotfire.Dxp.Application.Visuals import *
for p in Document.Pages:
for v in p.Visuals:
if str(v.TypeId) == "TypeIdentifier:Spotfire.LineChart": # Criteria
print v.Title
p.Visuals.Remove(v)
In case you want to keep it restricted to currently active page only,code is more simple -
from Spotfire.Dxp.Application.Visuals import *
for v in Document.ActivePageReference.Visuals:
if str(v.TypeId) == "TypeIdentifier:Spotfire.LineChart": # Criteria
print v.Title
Document.ActivePageReference.Visuals.Remove(v)
Share:

Search within column - Limiting values in Property Control

Before we begin, I have a question. Why List Box filter is so special ?
Yes, you got it right! The search within column values. What if we want to implement something similar for List Box Property Control ?
We are going to do it today !!
Let's Start.

  1. We are going to create a Input Field property first to capture our search string. In this example, I am going to call it - ${CountrySearch}. This is going to search values in [Country Name] column.
  2. Create a Calculated column [Country] to hold search results with expression below -If(Len('${CountrySearch}')>0,
         If(Find(Lower('${CountrySearch}'),Lower([Country Name]))>0,
                 [Country Name]) ,
         [Country Name])
  3. Now create your Property Control using column [Country]. I have given a search button, just to move focus out of search box; however hitting enter also works well.
Here is what we have in the end -
Share:

Removing Duplicates - Efficient Way

Duplicates in any source are always painful. We are expecting unique records and we get a lot of duplicates there.

How to deal with them ?
Well, there are many ways bur most of the times they involve a lot of steps.
Here, I am going to give you an approach which involves just one Filter Rows Transformation 👊 . For this use below expression in transformation after replacing columns according to your data -
If(
Rank(Rowid(),"asc",[Primary Key])=1
,TRUE 
,FALSE 
)
Here, if you want to identify unique rows based on more than one columns - Just add them like this :
If(
Rank(Rowid(),"asc",[Primary Key],[Data])=1
,TRUE 
,FALSE 
)
Want to see what happens ? Have a look -

Share:

Tracing Data Transformations from IronPython

Have you ever needed to gather details about transformations used in all Data Tables ? I know, you will go to Data Panel 👴
Now a twist - What If you have 20+ Data Tables ? Now you are getting irritated !
That's why we have IronPython ✌.
Although it is programmed to look for very basic details, but can be customized for more stuffs 💪

from Spotfire.Dxp.Data import *
from Spotfire.Dxp.Data.Transformations import *
from Spotfire.Dxp.Data.DataOperations import *
from System.Collections.Generic import List

for table in Document.Data.Tables:
    sourceview=table.GenerateSourceView()
    for op in sourceview.GetAllOperations[DataTransformationsOperation]():
        for t in op.GetTransformations():
            print t.Name
            #print t.GetType() #Un-comment & Google for this row's output for Documentation when you need
            if t.Name=='Filter rows':
                print "\tExpression : ",t.Expression
            if t.Name=='Replace value':
                print "\tColumn :",t.Column
                print "\tOriginal Value : ",t.OriginalValue
                print "\tNew Value : ",t.NewValue
Share:

Executing IronPython Codes with Progress Bar

I had a code to reload data table (which takes long time) and end users were keep on hitting Action button as they were not sure if something is happening. Sounds familiar to you as well ?
What to do ?
Probably if they see a progress bar it will be better, right ? Well TIBCO Community already have a post about it. Then why this post ?
Because you need keep a few things in mind -

  1. I don't like code - fewer lines would have done the thing 👲
  2. No error stack-trace 
  3. Some extra precautions needed.💀
Let's start. First of all, my code -

from Spotfire.Dxp.Framework.ApplicationModel import *
import traceback , time

proc=Application.GetService[ProgressService]()
def ex():
try:
# Wait for 5 seconds, Just to keep progress screen up for demo - remove from actual code
time.sleep(5)
proc.CurrentProgress.ExecuteSubtask("Refreshing Data")
Document.Data.Tables.ReloadAllData()
proc.CurrentProgress.ExecuteSubtask("Refresh is Complete")
except:
traceback.print_exc()
proc.ExecuteWithProgress("Refreshing Data Manually","Trying to refresh all Data Tables with a progress bar", ex)

Now coming back to precautions; this thing should be unchecked if you don't want to struggle with an error -
Also, please handle the exceptions wisely, using default except block may help in debug; but a well handled code brings robustness.
Regarding additional wait- do not use if you don't need it.
This is what you can expect in client -

Share:

Be Fair with Filters Panel

I was looking at custom theme option in Spotfire -

Wait, What  ?? I cannot customize Filters Panel from here !!
But, You already know I will 👽

With CSS code

<style>
.VirtualListBox .sf-element-list-box-item {
    background-color: cadetblue;
    color: floralwhite;
    border-left: 3px solid chocolate;
}
.sfc-style-root .sf-element-panel-content.sfc-filter-panel .sf-element-search-field .sf-element-input {
    padding-left: 5px;
    padding-right: 18px;
    color: #72eca6;
    background-color: blueviolet;
    border: 2px solid #72eca6;
    border-radius: 4px;
}
.sf-element-panel-content.sfc-filter-panel .sf-element-filter {
    position: absolute;
    overflow: hidden;
    color: #e0ec3b;
    background-color: #454545;
    border-color: darkorange;
    border-radius: 18px 0px 0px 0px;
}
.sf-element-panel-content.sfc-filter-panel .sfpc-active .ContextButton {
    visibility: visible;
    background: #26a2ed;
    border: 1px solid white;
}
</style>

JavaScript For HTML Sanitization Victims💃

if(!$('#AlienFilter').length){
$('body').append($(`<style id="AlienFilter">
.VirtualListBox .sf-element-list-box-item {
    background-color: cadetblue;
    color: floralwhite;
    border-left: 3px solid chocolate;
}
.sfc-style-root .sf-element-panel-content.sfc-filter-panel .sf-element-search-field .sf-element-input {
    padding-left: 5px;
    padding-right: 18px;
    color: #72eca6;
    background-color: blueviolet;
    border: 2px solid #72eca6;
    border-radius: 4px;
}
.sf-element-panel-content.sfc-filter-panel .sf-element-filter {
    position: absolute;
    overflow: hidden;
    color: #e0ec3b;
    background-color: #454545;
    border-color: darkorange;
    border-radius: 18px 0px 0px 0px;
}
.sf-element-panel-content.sfc-filter-panel .sfpc-active .ContextButton {
    visibility: visible;
    background: #26a2ed;
    border: 1px solid white;
}
</style>`, {
        id: 'AlienFilter' 
   }));
}
I got this so far -

Share:

Elder Brothers of Table : Cross Table, Summary Table and Graphical Table

Recently I published an article about Styling Tables ,and then I observed something. Spotfire reuses the same class elements for most of Cross Table, Summary Table and Graphical. (Now we can understand why there are only a few customization options under Theme 😏)
Anyways, when we are styling stuffs already, why not to do it for all three of them in one go ? Code for you -
<style>
.sfc-style-root .sf-element-table-cell.sfpc-odd-row {
   background-color: chocolate;
   color: white;}
.sfc-style-root .sf-element-table-cell {
background-color: burlywood;
}
.sfc-style-root .sf-element-table-cell.sfpc-total-value {
    font-weight: Bold;
color:white;
background-color: chocolate;
}
.sfc-style-root .sf-element-visual-content.sfc-cross-table .sf-element-table-cell.sfc-column-header {
background-color: #858585;
color:white;
}

.sf-element-table-cell.sfc-row-header {
background-color: #454545;
color:white;
}
.sfc-style-root .sf-element-visual-content.sfc-summary-table .sf-element-table-cell.sfc-column-header {
background-color: #858585;
color:white;
}
.sfc-style-root .sf-element-table-cell.sfc-column-header {
    color:white;
    background-color: #454545;
}
</style>
I know, you may be struggling with HTML Sanitization. So don't worry, you can use JavaScript too -
if(!$('#AlienBox').length){
$('body').append($(`<style id="AlienBox">
.sfc-style-root .sf-element-table-cell.sfpc-odd-row {
   background-color: chocolate;
   color: white;}
.sfc-style-root .sf-element-table-cell {
background-color: burlywood;
}
.sfc-style-root .sf-element-table-cell.sfpc-total-value {
    font-weight: Bold;
color:white;
background-color: chocolate;
}
.sfc-style-root .sf-element-visual-content.sfc-cross-table .sf-element-table-cell.sfc-column-header {
background-color: #858585;
color:white;
}

.sf-element-table-cell.sfc-row-header {
background-color: #454545;
color:white;
}
.sfc-style-root .sf-element-visual-content.sfc-summary-table .sf-element-table-cell.sfc-column-header {
background-color: #858585;
color:white;
}
.sfc-style-root .sf-element-table-cell.sfc-column-header {
    color:white;
    background-color: #454545;
}
</style>`, {
        id: 'AlienBox' 
   }));
}
Here is what we got in the end :

Share:

Styling Table Visualization

Question : How to add CSS Styles to a Spotfire Table ?
Answer   : I have a Code 😊
We need to add below code in a TextArea -
<style>
.sfc-style-root .sf-element-table-cell.sfpc-odd-row {
   background-color: chocolate;
   color: white;}
.sfc-style-root .sf-element-table-cell {
background-color: burlywood;
}

</style>
Now, for poor guys with HTML Sanitization issues 😐 : Add a JavaScript (below). It is basically same code as above with a trick to add css.
if(!$('#AlienBox').length){
$('body').append($(`<style id="AlienBox">
.sfc-style-root .sf-element-table-cell.sfpc-odd-row {
   background-color: chocolate;
   color: white;}
.sfc-style-root .sf-element-table-cell {
background-color: burlywood;
}
</style>`, {
        id: 'AlienBox'
   }));
}
Look, What I got (I know its basic - but more can be done, right ??)

Share:

Beat that HTML Sanitization

I never liked HTML Sanitization in TIBCO Spotfire. Ever time I have a new CSS code to use, and damn -


What to do now ?
We have our savior : JavaScript. Wrap the style in this code and throw it as a JavaScript code -
if(!$('#AlienBox').length){
$('body').append($(`<style id="AlienBox">
//My CSS Code
</style>`, {
        id: 'AlienBox' 
   }));
}
This code basically adds the <style id="AlienBox"> to the <body> tag of Spotfire HTML.
Share:

New Spotfire X Transformations - Loading Filtered Data

As a Spotfire Developer, we use Data Limit using expressions many time. sometimes we feel "What if we can Limit whole Dashboard with a Simple Expression ?"
Well .. Spotfire X have made it possible. How ? Follow below steps -

  1. Load Data.
  2. Enable Data Canvas.
  3. Select Data Table
  4. Add Transformation
  5. Select Filter Rows and Insert.
  6. Hope you are able to see something familiar now. Just put your expression and hit OK
  7. Congratulations !!
Share:

Styling Spotfire Action Buttons

Question: How to add Styles to Spotfire Action Buttons ?
Answer :
Just add this code to your text area and you are ready to customize from first moment -

<style> 

.sfc-action-button {                       

color: #ffffff !important;                 

font-size: 26px !important;                

height: 36px !important;                   

background-color: #858585!important;       

background-image: none !important;         

}                                          

</style> 

In case, just in case, If HTML Sensitization is enabled by your admin - You are bit unlucky. Still you can do a few stuffs using JavaScript codes. A Small Example code here-

$(".sfc-action-button").css({
 "width":"600 px",
 "font-size": "200%"});
Share: