This JavaScript adds a search bar to the bookmark panel.
Search Bookmarks
Warning / Notice Popup or Banner
This script is useful for announcements. A floating button is visible to bring the popup again if needed. Includes a checkbox to turn it off next time the script is triggered.
Incrementally add new rows without reloading the entire dataset
Suppose that you have a main table with all your data and you want to bring new records. You will need to setup a temporary table pointing to the same data source but just brings new records that are not yet on your main table. The temporary table has to be setup on-demand to bring new records that do not exists on the main table. Something like: >= Max([MainTable].[id]) + 1 id is a sequence.
step by step setup procedure:
- Add two data tables in memory on your analysis
- destination Table contains all the data. Could be millions of records
- source Table comes from the same source. Set on-demand parameters:
- Set a min range expression input to be : Max([destinationTable].[id]) + 1
- That will take new records
- At this point nothing is shown, unless you refresh sourceTable with new records
- The iron python script programmatically reloads only the sourceTable and appends those rows to the main table.
- To keep a fair amount of records and prevent the data canvas to have unlimited number of transformations, you can delete old records.
Tooltips for column headers
Enable html tooltips with this simple script and power up your cross table, graphical table or data tables
(() => { let i = 0; let tooltipTimeout = null; // Tooltips dictionary with lowercase keys const tooltips = { 'city': 'Another big city!', 'state': 'The inner text or textContent for this item is "state"', 'population': 'Population in millions<br>Look, we can use images!<br><img style="background:white" src="https://img.icons8.com/ios-filled/100/000000/crowd.png">', 'country': 'Tooltip for country', 'latitude': 'Geographical latitude.', 'longitude': 'Geographical longitude.', 'average temperature (f)': 'Average temperature data.', 'air quality index': 'Current air quality index.', 'observation date': 'Date of observation.', 'bullet graph':'This bullet graph represnts the air quality index min and max' }; const tooltip = document.createElement('div'); tooltip.id = 'tooltip'; tooltip.style.position = 'absolute'; tooltip.style.backgroundColor = 'black'; tooltip.style.color = 'white'; tooltip.style.padding = '5px'; tooltip.style.borderRadius = '5px'; tooltip.style.fontSize = '12px'; tooltip.style.visibility = 'hidden'; tooltip.style.opacity = '0'; tooltip.style.transition = 'opacity 0.2s'; tooltip.style.pointerEvents = 'none'; // Ensures the tooltip doesn't trigger any events document.body.appendChild(tooltip); const hasColumnHeaderClass = (element) => { while (element) { if ([...element.classList].some(cls => cls.includes('column-header'))) { return true; } element = element.parentElement; } return false; }; // Function to handle mouseover event const handleMouseOver = (event) => { const target = event.target; const textContent = target.textContent.trim().toLowerCase(); // Clear any existing timeout to avoid overlapping timeouts if (tooltipTimeout) { clearTimeout(tooltipTimeout); } tooltipTimeout = setTimeout(() => { if (tooltips[textContent] && hasColumnHeaderClass(target)) { tooltip.innerHTML = tooltips[textContent]; tooltip.style.visibility = 'visible'; tooltip.style.opacity = '1'; i++; console.log(i); } else { tooltip.style.visibility = 'hidden'; tooltip.style.opacity = '0'; } }, 800); // 0.8 seconds delay }; // Function to handle mousemove event const handleMouseMove = (event) => { tooltip.style.left = `${event.pageX + 10}px`; tooltip.style.top = `${event.pageY + 10}px`; }; // Function to handle mouseout event const handleMouseOut = () => { // Clear any existing timeout when mouse leaves if (tooltipTimeout) { clearTimeout(tooltipTimeout); } tooltip.style.visibility = 'hidden'; tooltip.style.opacity = '0'; }; // Attach event handlers using 'on' properties document.body.onmouseover = handleMouseOver; document.body.onmousemove = handleMouseMove; document.body.onmouseout = handleMouseOut; })();
Range Slider
Convert a regular Spotfire Input field Property Control as a Range Slider in Spotfire text area
html
<div id='slider'>
<SpotfireControl id="Input Field Property Control" /> <SpotfireControl id="label Property Control" />
</div>
js
(()=>{
const slider=document.querySelector('#slider input');
slider.type="range";
slider.min = 10;
slider.max = 50;
slider.step = 0.5;
slider.oninput = () => {
slider.blur();
slider.focus();
}
})()
Confirmation Dialog
html
<div id="confirmExecute">
<SpotfireControl id="2fe15f7fd4174c08b40c0ee27c5591c1" />
</div>
<div id="actualExecute" style="position:fixed;top:-100px">
<SpotfireControl id="7475a74b91ae474c80bf4f979bd1f56a" />
</div>
JavaScript
//setup the first spotfire sleep button (that does nothing) show a confirm dialog
document.querySelector("#confirmExecute input").onclick=function(){
Spotfire.ConfirmDialog.showYesNoCancelDialog("Confirm Execution","Do you really want to execute?",okClick,noClick,null)
}
//programatically click on spotfire control when confirming
okClick = function(x){
document.querySelector("#actualExecute input").click();
}
//display a friendly message if
noClick = function(x){
//alert("OK, no worries")
Spotfire.ConfirmDialog.showDialog("OK","No worries!",[])
}
Get Image Layer dimensions on Map Visualization
Just uncheck the marker layer or remove the Positioning markers (geocoding or coordinate columns) from the marker layer, go back to the image layer and hit the reset button
Autocomplete
Add autocomplete to an existing Spotfire input control (webplayer and cliente )
html
<div id="autocomplete">
<SpotfireControl id="spotfire_Input" />
</div>
<div id="autocomplete-data" hidden>
John Doe,Jane Smith,Robert Johnson,Michael Brown,Emily Davis,Sarah Miller,James Wilson,Patricia Moore,Richard Taylor,Linda Anderson
</div>