Styles for Tooltip

Tooltips in Spotfire are great for showing insights on mouse over. We use them a lot for showing information which should appear only when we need. But what if you feel that their look and feel is not matching with you theme ?
Question here is - How to add Style to tooltips ? 🤔🤔
Answer is, below code in a HTML TextArea -
<style id="AlienBox">
 .sf-tooltip {
background-color:chocolate !important;
color: white !important;
border: 2px solid white!important;
border-radius: 8px 0px 8px 0px !important;
    font-variant: petite-caps;
    font-style: italic;
    font-weight: lighter;
    font-size: x-small;
}
 </style>
If you are victim of HTML Sanitization issue, use JavaScript below -
if(!$('#AlienBox').length){
 $('body').append($(`<style id="AlienBox">
 .sf-tooltip {
background-color:chocolate !important;
color: white !important;
border: 2px solid white!important;
border-radius: 8px 0px 8px 0px !important;
    font-variant: petite-caps;
    font-style: italic;
    font-weight: lighter;
    font-size: x-small;
}
 </style>`, {
        id: 'AlienBox' 
   })); 
}
This is what I was able to achieve so far -

Share:

Conditional Coloring of Spotfire Buttons

My friend was willing to color Spotfire Action buttons based on a value. 
It is a small but effective way of representation. You will actually come to know what are your expectations even before clicking on a color coded button.
Challenge here, This color should be picked automatically  
Challenge Accepted !
Lets Start -
  1. Create a calculated value or Label property which evaluates into a single color (e.g. red) or into a color code value (e.g. #454545). Enclose it is a span with id property-
    <span id='property' style="display:none">
       <SpotfireControl id="c281364f0af947c38752561b38be631e" />
    </span>
  2. Now enclose your action button inside another span with id ConditionalButtonColor like below. This way you are letting your code know - which button you are going to style 🧐
    <span id='ConditionalButtonColor'>
    <SpotfireControl id="edf0f3c8a1b945cb840cd0235fce8d66" />
    </span>
  3. Now you simply need this JavaScript code to be added to the text area. It retrieves value from property and set it a background color of action button inside ConditionalButtonColor .
    var flag=0
    function conditionalColor() {  
     colorValue=$("#property").text()
     if(flag!=colorValue){
      $('#ConditionalButtonColor .sfc-action-button').css({
        background:colorValue,
    color:"white"
        ,textAlign:"center"
        ,margin:"10px"
        ,padding:"5px"
        ,borderStyle:"outset"
        ,width:"100px"
      });
     }
      flag=colorValue
    }

    setInterval(conditionalColor,500)
  4. Save the text are and you are done ✅
For demonstration, I am updating color value a drop down property. You can update it via a Label Document Property, Calculated value or even from simple sting as well. Here is a screenshot with results -
Share:

Show/Hide Pages with a Button

A friend from Community asked for a Button to toggle visibility of a Spotfire page.  
So, this post is about same 😎
Lets Start -


  1. Create a button in TextArea with id Hider. If you are suffering from HTML Sanitization, you can use my alternative code. This one re-purposes span as button 😜
    <span id="Hider" style="background-color:chocolate;
    color:white;
    display:inline-block;
    border: 1px solid rgb(128,128,128);
    border-radius : 8px;
    padding     : 8px;
    line-height : 24px;
    text-shadow : 0 0 2px black;
    font-size:larger;
    margin:5px;
    cursor: pointer;">Toggle Visibility
    </span>
  2. Add below JavaScript to TextArea. Here [1] is page index of Second page. You can adjust it as you need.
    $('#Hider').click(function(){
    var state =$('.sf-element-page-tab')[1].style.display;
    console.log(state);
    if(state =='none') {
    $('.sf-element-page-tab')[1].style.display = "";}
    else{$('.sf-element-page-tab')[1].style.display = "none";}
    });
  3. Save TextArea and you are done ✅
This is a Before vs After comparison of Page Navigation Area -

Share:

Capturing Hierarchy Axis Changes to Document Property

My friend recently asked an Interesting Question -
I have a chart where I am using a Hierarchy as Category Axis. I want to capture changes in that Axis (Hierarchy) to a Property Control. Is there a way to do this ?
Sounds interesting  🙃
Well , Let's start doing it !
  1. Add a Input field property enclosed in a span like below. Code in red is optional based on whether you need to display document property on not.
    <span id='AxisTracker' style='display:none;'>
      <SpotfireControl id="635a7ae743a14feb865833e75f3e9b4d" />
    </span>
  2. Add below JavaScript to capture changes. Here code in red indicates the possible states of Hierarchy Axis of interest

    function updateProperty(){
    $('.sf-element-text-box').each(function(index){
    //console.log($(this).text());
    switch($(this).text()){
        case "Geo (Region)":
        case "Geo (State)":
        case "Geo (City)":
    console.log($(this).text());
    $('#AxisTracker input').val($(this).text()).blur()
    break;
    }
    });}
    setInterval(updateProperty,500)
  3. This is pretty much all 🤓 
Using this approach helps in tracking changes to the Axis and we can trigger IronPython code as well on Document property change. 
Share:

Adding some styles to Notifications

Default Notifications Dialog is boring!

Agree?
If yes, then this post is for you. Try Adding below code to a text area and then have a look at notifications again-
<style id="AlienBox">
.sf-modal-dialog-content textarea {
    color: azure;
    background-color: brown;
}
.sfc-default-theme.sf-element-modal-dialog .sf-element-modal-dialog-footer {
    font-size: 14.5px;
    background-color: #1e264e;
    color: #BDBFC3;

}
.sfc-default-theme.sf-element-modal-dialog .sf-element-modal-dialog-header {
    background-color: #134373;
}
.sfc-default-theme.sf-element-modal-dialog {
    background-color: #772323;
}
.sf-element-modal-dialog .sf-element-modal-dialog-header-title-text {
    font-size: x-large;
    color: blanchedalmond;
}
.sfc-default-theme.sf-element-modal-dialog .sf-element-modal-dialog-header .sf-element-modal-dialog-header-close {
    color: #ffffff;
    font-size: xx-large;
}
.sfc-default-theme.sf-element-modal-dialog .sf-element-button.sfpc-secondary {
    background-image: linear-gradient(to bottom, #7b3939, #206bb7);
    border-top-color: #234996;
    border-right-color: #4d6ba7;
    border-bottom-color: #AFB2B7;
    border-left-color: #586d96;
    border-bottom-color: #546580;
    color: #ffffff;
    font-size: large;
}
.sfc-default-theme.sf-element-modal-dialog .sf-element-button {
    background-image: linear-gradient(to bottom, #7b3939, #206bb7);
    border-top-color: #234996;
    border-right-color: #4d6ba7;
    border-bottom-color: #AFB2B7;
    border-left-color: #586d96;
    border-bottom-color: #546580;
    color: #ffffff;
    font-size: large;
}
</style>
For HTML Sanitization, I have a JavaScript code too -

if(!$('#AlienBox').length){
$('body').append($(`<style id="AlienBox">
.sf-modal-dialog-content textarea {
    color: azure;
    background-color: brown;
}
.sfc-default-theme.sf-element-modal-dialog .sf-element-modal-dialog-footer {
    font-size: 14.5px;
    background-color: #1e264e;
    color: #BDBFC3;

}
.sfc-default-theme.sf-element-modal-dialog .sf-element-modal-dialog-header {
    background-color: #134373;
}
.sfc-default-theme.sf-element-modal-dialog {
    background-color: #772323;
}
.sf-element-modal-dialog .sf-element-modal-dialog-header-title-text {
    font-size: x-large;
    color: blanchedalmond;
}
.sfc-default-theme.sf-element-modal-dialog .sf-element-modal-dialog-header .sf-element-modal-dialog-header-close {
    color: #ffffff;
    font-size: xx-large;
}
.sfc-default-theme.sf-element-modal-dialog .sf-element-button.sfpc-secondary {
    background-image: linear-gradient(to bottom, #7b3939, #206bb7);
    border-top-color: #234996;
    border-right-color: #4d6ba7;
    border-bottom-color: #AFB2B7;
    border-left-color: #586d96;
    border-bottom-color: #546580;
    color: #ffffff;
    font-size: large;
}
.sfc-default-theme.sf-element-modal-dialog .sf-element-button {
    background-image: linear-gradient(to bottom, #7b3939, #206bb7);
    border-top-color: #234996;
    border-right-color: #4d6ba7;
    border-bottom-color: #AFB2B7;
    border-left-color: #586d96;
    border-bottom-color: #546580;
    color: #ffffff;
    font-size: large;
}
</style>`, {
        id: 'AlienBox' 
   }));
}
This is what I got with my code -

Share:

Interacting with Subsets with IronPython

What if you have to compare All Data with current Selections (Marking, Filtering etc.) ?
What if you have to compare your two selections?

I know answer will be - using (Subsets).
But, What If you want to make this comparison on-Demand only ?

My Answer is below IronPython code -
from Spotfire.Dxp.Application.Visuals import *
vsc = v.As[VisualContent]().Data.Subsets
vsc.Clear()# To Clear all subsets except defaults
#Use below 2 rows if you need to add additional Subsets
#vsc.AddDataSelection(Document.Data.Markings["Marking Name"])
#vsc.AddDataSelection(Document.Data.Filterings["Filtering Scheme Name"])
for ss in vsc:
print ss.DisplayName,"\n\tEnabled ? ",ss.Enabled,"\n\tInteractive? ",ss.Interactive
if ss.DisplayName =='All data':#Toggle between one selection Enabled status
ss.Enabled = not ss.Enabled
ss.Interactive=False
With above code, we are expecting these results -

Share:

Adding Styles to Legend Area

Recently I have posted a few ways to style different Spotfire elements. Now I have one more, for Legends this time.
This is what I have been able to achieve so far -
Here is the code you need to Add to one of the HTML Text Area -
<style id="AlienBox">
.StyledScrollbar.LegendScroll {
    background-color: darkcyan;
    border: 2px solid darkmagenta;
    border-radius: 12px;
}
.sfc-style-root .sf-element-legend-item {
    padding-top: 1px;
    padding-right: 10px;
    padding-bottom: 6px;
    padding-left: 10px;
    background-color: blueviolet;
    border: 2px solid blue;
    border-radius: 12px;
}
.sf-element.sf-element-title.sf-legend-item-elem {
    background-color: darkblue;
    border-radius: 12px;
}
.sf-element-document .sf-element-axis-tray .sf-element-text-box {
    vertical-align: top;
    color: deepskyblue;
    font-weight: bold;
    font-size: x-small;
}
.sf-element.sf-element-sub-item-section.sf-legend-item-elem {
    font-variant: petite-caps;
    font-style: italic;
    font-weight: lighter;
    font-size: x-small;
}
</style>
For HTML Sanitization issue, we have a solution as always as a JavaScript code -
if(!$('#AlienBox').length){
$('body').append($(`<style id="AlienBox">
.StyledScrollbar.LegendScroll {
    background-color: darkcyan;
    border: 2px solid darkmagenta;
    border-radius: 12px;
}
.sfc-style-root .sf-element-legend-item {
    padding-top: 1px;
    padding-right: 10px;
    padding-bottom: 6px;
    padding-left: 10px;
    background-color: blueviolet;
    border: 2px solid blue;
    border-radius: 12px;
}
.sf-element.sf-element-title.sf-legend-item-elem {
    background-color: darkblue;
    border-radius: 12px;
}
.sf-element-document .sf-element-axis-tray .sf-element-text-box {
    vertical-align: top;
    color: deepskyblue;
    font-weight: bold;
    font-size: x-small;
}
.sf-element.sf-element-sub-item-section.sf-legend-item-elem {
    font-variant: petite-caps;
    font-style: italic;
    font-weight: lighter;
    font-size: x-small;
}
</style>`, {
        id: 'AlienBox' 
   }));
}

Share:

Display Current User Information on Menu Bar

I recently posted about how to add Information to Menu Bar . I have been asked on LinkedIn - "How to display Current Logged in Username here ?"
I will not say it is difficult, but involves a little more number of steps, because we have to use some extra steps to get current user details as well.
So, Lets Start !
  1. Create 2 Document Properties time and UserName . We will use time to trigger a IronPython Script to get current user details.
  2. Add script to Document Property time .
    You can use any script to get user information. I used approach from my post on LinkedIn-
    from Spotfire.Dxp.Framework.ApplicationModel import UserContext
    r=Application.GetService[UserContext]()
    Document.Properties["UserName"] = r.Username
  3. Now, create a Data Function with Simple script.
    output=input
  4. Define Output Parameter to Document Property time to trigger IronPython code from step 2.
  5. Define Input Parameter to expression below-
    String(DateTimeNow())
  6. In HTML Text Area, create a Div with Property User enclosed -
    <span id='userDet' style="visibility:hidden;">
    <SpotfireControl id="52ea70f998bb46c985e49a1d0ca03ada" />
    </span>
  7. Add JavaScript for final touch-
    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' 
       })); 
    }
    innerHTML=`<div id="Brand">
     <center> Current User is <br><b>`;
    innerHTML+=$("#userDet").text();
    innerHTML+=`</b> </center>
     </div>`;

    if(!$('#Brand').length){
     $('body').append($(innerHTML, {
            id: 'Brand' 
       })); 
    }
  8. Save the Analysis and Close.
  9. Open Analysis again to see the desired output.
I am not including any screenshot this time, Just give a try and see the results yourself. 

Share: