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







Warning when upgrading to Spotfire 10

TIBCO has deprecated the JQueryUI Javascript library in the latest Spotfire 10.0 release

TIBCO Community pages show us how to use JQuery properly

Change a join after inserting a column

from Spotfire.Dxp.Data import *
from Spotfire.Dxp.Data.DataOperations import *
from System import *

#Join Types
i   = 'InnerJoin'
lo = 'LeftOuterJoin'
ro = 'RightOuterJoin'
fo = 'FullOuterJoin'
ls = 'LeftSingleMatchJoin'
rs = 'RightSingleMatchJoin'

joinType = lo
matchOnNull = 0

op = table.GenerateSourceView().GetAllOperations[AddColumnsOperation]()[0]
old = op.AddColumnsSettings;
newSettings = AddColumnsSettings(old.Map, Enum.Parse(JoinType, joinType), old.IgnoredColumns, matchOnNull)
op.AddColumnsSettings = newSettings

source: https://community.tibco.com/wiki/how-change-join-type-add-columns-operation-tibco-spotfire-using-ironpython

Simple popup




html

<ul>
  <li><a  href="#popup1">Filters</a>
  <li><a  href="#popup2">Inputs</a>
  <li><a  href="#popup3">About</a>
</ul>

<div id="popup1" class="overlay">
  <div class="popup">
    <h2>Filters</h2>
    <a class="close" href="#">&times;</a>
    <div class="content">
      Region:<br>
      <SpotfireControl id="4e267da24bbb4c0caaec3a001ed70c93" />
      <br>Rank:<br>
      <SpotfireControl id="4a5d98d3faae45cfb14beabd3338aeb1" />
      <br>Promotions:<br>
      <SpotfireControl id="7cd9afca669640dba8ef856d5ce227e4" />
      <br>Store Type:<br>
      <SpotfireControl id="634158287ec847808d07dab327b04cf3" />
    </div>
  </div>
</div>

<div id="popup2" class="overlay">
  <div class="popup">
    <h2>Inputs</h2>
    <a class="close" href="#">&times;</a>
    <div class="content">
      Enter discount amount:<br> 
      <SpotfireControl id="7965aff6ff4541ca8bf89464411cbfdc" />
      <br>Select state:<br> 
      <SpotfireControl id="c01e7f23d4e04c2bbedf7dac3f16a6da" />
      <br><a href="#"><button style='float:right'>apply</button></a>
    </div>
  </div>
</div>

<div id="popup3" class="overlay">
  <div class="popup">
    <h2>About</h2>
    <a class="close" href="#">&times;</a>
    <div class="content">
      Save real state with smart popups!
    </div>
  </div>
</div>

<style>
  .overlay {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.2);
  transition: opacity 500ms;
  visibility: hidden;
  opacity: 0;
  }
  .overlay:target {
  visibility: visible;
  opacity: 1;
  }
  .popup {
  margin: 70px auto;
  padding: 20px;
  background: whitesmoke;
  border-radius: 5px;
  width: 30%;
  position: relative;
  transition: all 5s ease-in-out;
  }
  .popup h2 {
  margin-top: 0;
  color: #333;
  font-family: Tahoma, Arial, sans-serif;
  }
  .popup .close {
  position: absolute;
  top: 20px;
  right: 30px;
  transition: all 100ms;
  font-size: 30px;
  font-weight: bold;
  text-decoration: none;
  color: #333;
  }
  .popup .close:hover {
  color: #06D85F;
  }
  .popup .content {
  max-height: 30%;
  overflow: auto;
  }
  @media screen and (max-width: 700px){
  .box{
  width: 70%;
  }
  .popup{
  width: 70%;
  }
  }
</style>

Rotate bullet graph vertically

Turn a bullet graph vertically


Example 1



html
<div class='thermometer1'> <SpotfireControl id="4e93c6fb1408420cbdf20066dceaa8ed" /></div>

<style>
.thermometer1{
    width: 200px; 
    height: 50px; 
    margin-top: 123px;
    -webkit-transform: rotate(-90deg);
    -moz-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    -ms-transform: rotate(90deg);
    /* transform: rotate(90deg); */
    /* text-align: center; */
}
.thermometer1 img{
    padding:10px;
width:20px;
    background-color: #fff;
    box-shadow: -5px 2px 13px 3px #8a6b6b;
    border-radius: 20px;
}
</style>




Example 2
No labels, no shadow




html

<div class='thermometer2 shadow'> <SpotfireControl id="4e93c6fb1408420cbdf20066dceaa8ed" /></div>


<style>
.thermometer2{
    -webkit-transform: rotate(-90deg);
    -moz-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    -ms-transform: rotate(90deg);

    /*position*/
    width: 100px; 
    margin-top: 100px;
}

/*height, width*/
.thermometer2 img{
    width: 140px !important; 
    height: 30px !important; 
    border-radius: 100px;
    /*box-shadow: -5px 5px 25px 2px #8a6b6b;*/  /*optional*/

}
</style>

Get Scripts

for s in Document.ScriptManager.GetScripts():
print "Script Name: \t"+s.Name
print "Description: \t"+s.Description
print "Parameters:"
for p in s.Parameters: print "\t\t"+p.Name
print "_"*50

Hide empty checkbox filter value on text area

A Quick and dirty way to hide the annoying but useful [] (empty) checkbox on a checkbox filter in a text area:


html
<div id=filter onmouseover=hideEmpty()>
<SpotfireControl id="7daf87b0152b448a8fa82353af350875" />
</div>


js
var hideEmpty = function(){
document.querySelectorAll("#filter .sf-element.sf-element-filter-item:last-child")[0].style.display='none'
}

if(this['ps']) clearInterval(ps)
ps = setInterval(hideEmpty,100)




Spinning refresh data table button



METHOD 1

How it works
Spotfire link control that refreshes data table through ironpython. The button starts to spin when clicked. When the data table finishes loading, a document property gets updated with current timestamp, which is rendered as a label in the text area. When this label changes, the button stop spinning.

html
The first Spotfire control is a link that runs a script that refresh the data table and updates a document property. The second control is a label from a document property of data type Date Time

<center>
<div size=3  id=spinner><SpotfireControl id="add6c340686046cb92e10c16ac96680c" /></div>
<br/>
<font id ='updateLabel' size=1 >
Last Reload : <SpotfireControl id="8d5975f94c9442ae8badec2f462aa8f2" />
</font>
</center>

<style>

.spinner {

  width:20px;

  animation-name: spin;

  animation-duration: 2000ms;
  animation-iteration-count: 20;
  animation-timing-function: linear; 
}

@keyframes spin {

    from {
        transform:rotate(0deg);
    }
    to {
        transform:rotate(720deg);
    }
}
</style>


script
from System import DateTime
dt.Refresh()
Document.Properties[dp]=DateTime.Now


js
 $("#spinner").on('click',function(){
var $this = $(this).addClass('spinner');
});
  
  
//function when label changes
var myFunction = function(oldValue,newValue){
$("#spinner").removeClass('spinner')
}
targetDomId = "updateLabel"

//no need to change after this line.
var target = document.getElementById(targetDomId)

//callback is the function to trigger when target changes
var oldVal = target.innerText.trim()
var callback = function(mutations) {
 newVal=$('#'+targetDomId+' ').text()
 if(newVal!=oldVal) myFunction(oldVal,newVal)
 oldVal = newVal;
}

//this is to glue these two together
var observer = new MutationObserver(callback);
var opts = {
    childList: true, 
    attributes: true, 
    characterData: true, 
    subtree: true
}
observer.observe(target,opts);



METHOD 2
ActiveVisual is a text area holding the animation. In this case is just a label. Thanks to Jolene Roberson!

script
from Spotfire.Dxp.Application.Visuals import *
from System.Collections.Generic import List, Dictionary
from Spotfire.Dxp.Data import DataTable
from Spotfire.Dxp.Application.Scripting import ScriptDefinition
from Spotfire.Dxp.Framework.ApplicationModel import NotificationService
import clr
import time

activeVisual.As[HtmlTextArea]().HtmlContent = "Please wait.."

activeVisual = Document.ActivePageReference.ActiveVisualReference

Document.Properties['refreshStatus'] = 'Loadng'

if Document.Properties['refreshStatus'] != 'Ready':

    notify = Application.GetService[NotificationService]()

    # Refresh Callback function
    def execCallBack(exception, Document=Document, notify=notify):
        if not exception:
            Document.Properties['refreshStatus'] = 'Ready'
            activeVisual.As[HtmlTextArea]().HtmlContent = 'Done!'
        else:
            activeVisual.As[HtmlTextArea]().HtmlContent = 'Error!'
            notify.AddErrorNotification('Error refreshing table(s)','Error details', str(exception))

    # Note that more than one table can be added to the List object. Repeat the Add() method if needed for multiple tables to refresh.
    dataTables = List[DataTable]()
    dataTables.Add(Document.Data.Tables['Table1'])
    dataTables.Add(Document.Data.Tables['Table2'])

    Document.Data.Tables.RefreshAsync(dataTables, execCallBack)

Remove (Empty) from cross table without messing number formatting

Normally I use a sn([column],"") to hide "(Empty)" but if my column data type is other than string, it affects the formatting (i.e. currency).

For that reason, Jquery to the rescue. This will replace all divs with class cell-text that contains the "(Empty)" string with "". Here is how:

$('div.cell-text:contains("(Empty)")').text("")

Thanks Jolene Robertson!

Hide crosstable header columns or rowheaders

from Spotfire.Dxp.Application.Visuals import *
from Spotfire.Dxp.Application.Visuals.Miniatures import *

#gt = VisualTypeIdentifiers.GraphicalTable
ct = VisualTypeIdentifiers.CrossTable


def hideColums(x,n,w):
   for vis in Document.ActivePageReference.Visuals:
     if vis.TypeId==x:
         vis = vis.As[Visualization]()
                          for i in range(0,n): 
                              vis.RowHeaderWidths[i] = w


hideColums(ct, 2, 0) #vis type, n=number of headers, width 




Thanks Jolene Robertson!

Comments in custom expressions

Currently is not possible to add comments or comment a line in custom expressions. The only way I can think of is to wrap the expression with an if or case statement like this:


Original expression

 First(If(UniqueCount([ProjectName])=1,[ProjectName],Concatenate(UniqueCount([ProjectName])," projects selected")))


Expression with comment

case "comment"<>"this expression shows the full name when only one item is marked. Else it shows the item count"
when true then 
  First(If(UniqueCount([ProjectName])=1,[ProjectName],Concatenate(UniqueCount([ProjectName])," projects selected")))
end



Show / Hide Panels

script
for Filter Panel

#show hide FilterPanel across all tabs
#pages to ignore toogling filter panel
xTabs = ['HOME','css']

thisPagePanelState = Document.ActivePageReference.FilterPanel.Visible

for p in Document.Pages:
if p.Title not in xTabs:
p.FilterPanel.Visible = not thisPagePanelState 





script
for DoD Panel

#show hide DetailsOnDemandPanel across all tabs
#pages to ignore toogling filter panel
xTabs = ['HOME','css']

thisPagePanelState = Document.ActivePageReference.DetailsOnDemandPanel.Visible

for p in Document.Pages:
if p.Title not in xTabs:
p.DetailsOnDemandPanel.Visible = not thisPagePanelState  





css tabs

No jquery, no js. Just edit html on text area and paste the code below. It can handle spotfire conttrols too



html
<div class="tab_container"> <input id="tab1" type="radio" name="tabs" checked> <label for="tab1"><i class="far fa-arrow-alt-circle-right"></i> <span>Highlights & Forward Look</span></label> <input id="tab2" type="radio" name="tabs"> <label for="tab2"><i class="fas fa-bullseye"></i><span> Scope</span></label> <input id="tab3" type="radio" name="tabs"> <label for="tab3"><i class="fas fa-user-tie"></i><span> Ejecutive Summary</span></label> <section id="content1" class="tab-content"> <h3>Highlights</h3> <p> <ul> <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </li> <li>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, </li> <li> sunt in culpa qui officia deserunt mollit anim id est laborum. </li> </ul> </p> <h3>Forward Look</h3> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. </p> </section> <section id="content2" class="tab-content"> <h3>Scope</h3> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo. </p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> </section> <section id="content3" class="tab-content"> <h3>Ejecutive Summary</h3> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> </section> <section id="content4" class="tab-content"> <h3>Headline 4</h3> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. </p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p> </section> <section id="content5" class="tab-content"> <h3>Headline 5</h3> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo. </p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> </section> </div> <p class="no_wrap"> something static here </p> <style> @import url('https://use.fontawesome.com/releases/v5.7.0/css/all.css'); .clearfix:before, .clearfix:after { content: " "; display: table; } .clearfix:after {clear: both;} .tab_container { width: 90%; margin: 0 auto; padding-top: 10px; position: relative; } .tab_container input, .tab_container section { clear: both; padding-top: 10px; display: none; } .tab_container label { font-size: 12px; display: block; float: left; xwidth: 100%; padding: 1.0em; color: #757575; cursor: pointer; text-decoration: none; text-align: center; background: #f0f0f0; } #tab1:checked ~ #content1, #tab2:checked ~ #content2, #tab3:checked ~ #content3, #tab4:checked ~ #content4, #tab5:checked ~ #content5 { display: block; padding: 20px; background: #fff; color: #999; border-bottom: 2px solid #f0f0f0; } .tab_container .tab-content p, .tab_container .tab-content h3 { -webkit-animation: fadeInScale 0.7s ease-in-out; -moz-animation: fadeInScale 0.7s ease-in-out; animation: fadeInScale 0.7s ease-in-out; } .tab_container .tab-content h3 { text-align: center; } .tab_container [id^="tab"]:checked + label { background: #fff; box-shadow: inset 0 3px #0CE; } .tab_container [id^="tab"]:checked + label .fa { color: #0CE; } .tab_container label .fa { font-size: 1.3em; margin: 0 0.4em 0 0; } /*Media query*/ @media only screen and (max-width: 900px) { .tab_container label span { display: none; } .tab_container { width: 98%; } } /*Content Animation*/ @keyframes fadeInScale { 0% { transform: scale(0.9); opacity: 0; } 100% { transform: scale(1); opacity: 1; } } .no_wrap { text-align:center; color: gray; } .link { text-align:center; } </style>

Create a document property

from Spotfire.Dxp.Data import DataProperty
from Spotfire.Dxp.Data import DataType
from Spotfire.Dxp.Data import DataPropertyClass

propName = "docProp"
attr = DataProperty.DefaultAttributes

prop = DataProperty.CreateCustomPrototype(propName, DataType.String, attr)

Document.Data.Properties.AddProperty(DataPropertyClass.Document, prop)
prop.Value = "test"

Editing text area in text mode removes CSS

When editing text area in html mode sometimes you can no longer edit in regular text mode. Spotfire "cleans" the code by removing the css style and other tags. That is inconvenient for end users who wants to change typos or text in Spotfire text area in text mode. 

BUT If you put the <style>or <link> tags at the end of your html code, Spotfire does not removes the tags!

Happy styling



html

<textarea rows=3 style='width:333px'id=hidden>&lt;style&gt; and &lt;link&gt; tags should be at the end of the html code </textarea>

<H3>Try again to edit in text mode. <BR><BR> </H3>

<H2><I class=material-icons style="FONT-SIZE: 36px; COLOR: #e65400">mail_outline</I> contact us </H2>


<LINK href="https://fonts.googleapis.com/icon?family=Material+Icons" rel=stylesheet>

<STYLE>
#hidden{display:none}
h2{font-style:arial;font-weight:bold;font-size:30px;}
</STYLE>