Introduction This article demonstrates how to build an auto-rotating KPI carousel using a BloX widget in Sisense. The solution is tested on Sisense L2026.1.2 and works for both cloud and on-premises deployments. This BloX can stack multiple metric cards into a single widget footprint and automatically cycle through them every 6 seconds using a smooth fade transition. Each card is independently styled with a coloured left border, making it easy to visually distinguish metrics at a glance. The carousel is driven entirely by the BloX script field, with no external plugins or additional dashboard scripts required. Step-by-Step Guide 1. Prepare your environment Open an existing dashboard or create a new one. You will need at least two measures available in your data panel to populate the metric cards β for example, Total Revenue, Total Cost, and Total Quantity. The carousel can display any number of metrics; the example below uses three. 2. Add a BloX widget Click + Add Widget on your dashboard and select BloX from the widget type list (advanced configuration). Open the BloX editor. 3. Set up your data panel In the BloX data panel, add the measures you want to display as separate panels. In the example below, three panels are used: Total Revenue Total Cost Total Quantity These are referenced in the BloX body using the {panel: <Panel Name>} syntax. 4. Paste the full BloX JSON Replace the contents of the BloX editor with the following JSON: {
"style": "",
"script": "if(window.metricTimer) clearInterval(window.metricTimer); setTimeout(function() { var slides = $('.blox-metric-slide'); if(slides.length === 0) return; slides.parent().css({ 'position': 'relative', 'min-height': '140px' }); slides.css({ 'position': 'absolute', 'top': 0, 'left': 0, 'width': '100%', 'height': '100%', 'box-sizing': 'border-box', 'opacity': 0 }); slides.eq(0).css('opacity', 1); var curr = 0; window.metricTimer = setInterval(function() { slides.eq(curr).animate({opacity: 0}, 800); curr = (curr + 1) % slides.length; slides.eq(curr).animate({opacity: 1}, 800); }, 6000); }, 500);",
"title": "",
"showCarousel": false,
"body": [
{
"type": "Container",
"class": "master-metric-wrapper",
"style": {
"background-color": "#ffffff",
"border-radius": "12px",
"box-shadow": "0px 8px 24px rgba(0, 0, 0, 0.08)",
"margin": "15px",
"padding": "0"
},
"items": [
{
"type": "Container",
"class": "blox-metric-slide",
"style": { "padding": "30px", "border-left": "8px solid #2ecc71", "border-radius": "12px" },
"items": [
{
"type": "TextBlock",
"text": "TOTAL REVENUE",
"size": "small",
"weight": "bolder",
"color": "dark",
"isSubtle": true,
"style": { "letter-spacing": "1.5px", "text-transform": "uppercase" }
},
{
"type": "TextBlock",
"text": "{panel:Total Revenue}",
"size": "extraLarge",
"weight": "bolder",
"style": { "font-size": "38px", "margin-top": "8px", "color": "#2c3e50" }
}
]
},
{
"type": "Container",
"class": "blox-metric-slide",
"style": { "padding": "30px", "border-left": "8px solid #3498db", "border-radius": "12px" },
"items": [
{
"type": "TextBlock",
"text": "TOTAL COST",
"size": "small",
"weight": "bolder",
"color": "dark",
"isSubtle": true,
"style": { "letter-spacing": "1.5px", "text-transform": "uppercase" }
},
{
"type": "TextBlock",
"text": "{panel: Total Cost}",
"size": "extraLarge",
"weight": "bolder",
"style": { "font-size": "38px", "margin-top": "8px", "color": "#2c3e50" }
}
]
},
{
"type": "Container",
"class": "blox-metric-slide",
"style": { "padding": "30px", "border-left": "8px solid #e74c3c", "border-radius": "12px" },
"items": [
{
"type": "TextBlock",
"text": "TOTAL QUANTITY",
"size": "small",
"weight": "bolder",
"color": "dark",
"isSubtle": true,
"style": { "letter-spacing": "1.5px", "text-transform": "uppercase" }
},
{
"type": "TextBlock",
"text": "{panel: Total Quantity}",
"size": "extraLarge",
"weight": "bolder",
"style": { "font-size": "38px", "margin-top": "8px", "color": "#2c3e50" }
}
]
}
]
}
],
"actions": []
} 5. Adapt the JSON to your data There are three areas you will typically need to customise: Panel references β Replace {panel:Total Revenue}, {panel: Total Cost}, and {panel: Total Quantity} with the exact panel names as they appear in your BloX data panel. The name must match exactly, including spacing. Card labels β Update the "text" value in the first TextBlock of each container (e.g. "TOTAL REVENUE") to match your metric names. Border colours β Each card has a "border-left" style property with a hex colour. The example uses green (#2ecc71), blue (#3498db), and red (#e74c3c). Replace these with any colours that suit your dashboard theme. 6. Add or remove metric cards To add a new metric card , copy any existing container block (from { "type": "Container" ...} to its closing }) and paste it as a new item in the body array. Make sure to: Set "display": "none" in its style object (only the first card should omit this, as it is the one shown on initial load). Update the label text and panel reference. Assign a new border colour. To remove a card , simply delete its container block from the body array. 7. Adjust the rotation speed The carousel rotates every 6000 milliseconds (6 seconds) by default. To change this, find the number 6000 in the script field and replace it with your preferred interval in milliseconds. For example, use 3000 for 3 seconds or 10000 for 10 seconds. The fade transition duration is set to 500 milliseconds . This appears twice in the script as fadeOut(500, ...) and fadeIn(500). You can reduce or increase this value to make the transition faster or slower. 8. Save and test Click Save in the BloX editor. The widget will display the first metric card immediately, then begin cycling through the remaining cards automatically. Applying dashboard filters will update the displayed values in real time β the carousel continues rotating with the filtered data. Important notes Timer persistence: The window.metricTimer variable is stored on the global window object so it persists across widget re-renders and can be cleared reliably. If you have multiple BloX carousel widgets on the same dashboard, give each timer a unique variable name (e.g. window.metricTimer1, window.metricTimer2) to prevent them from interfering with each other. Initial card visibility: Only the first container in the body array should be visible on load. All subsequent containers must include "display": "none" in their style object. If this is missing, multiple cards will stack on top of each other before the script runs. Export behaviour: Because the carousel animation is script-driven, PDF and image exports will capture only whichever card is currently visible at the moment of export. Conclusion By combining BloX's flexible JSON layout with a lightweight JavaScript timer, this solution turns a single widget into a space-efficient rotating KPI display β ideal for executive dashboards, TV/kiosk screens, or any scenario where screen real estate is limited. The pattern is fully modular: cards can be added, removed, or restyled independently, and the rotation speed can be tuned to match the pace of your audience. The same approach can be extended to rotate more complex card layouts, such as cards containing multiple metrics, sparkline images, or conditional colour indicators. References / Related content BloX Overview β Sisense Documentation Disclaimer: This post outlines a potential custom workaround for a specific use case or provides instructions regarding a specific task. The solution may not work in all scenarios or Sisense versions, so we strongly recommend testing it in your environment before deployment. If you need further assistance with this, please let us know.