Sisense Community logo
    • Community Feedback
    • Chapters
    • Events
    • Forums
      • Help and How To
      • Product Feedback Forum
      • Strategy & Use Cases
    • Blogs
    • KB Docs
      • KB Docs
      • Add-Ons & Plug-Ins
      • APIs
      • Best Practices
      • Blox
      • CDT
      • Cloud Managed Service
      • Data Models
      • Data Sources
      • Embedding Analytics
      • How-Tos & FAQs
      • Onboarding
      • PySisense
      • Security
      • Sisense Administration
      • Sisense Intelligence & AI
      • Troubleshooting
      • Widget & Dashboard Scripts
    • Support
    • Learning
      • Sisense Academy: Free Courses and Certifications
      • Official Developer Documentation
      • Official Product Documentation
      • Official Sisense Youtube Channel
      • Sisense Compose SDK Playground
      • Official Sisense Discord
    • Use Case Gallery
    Discussions
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
    Discussions
    • TagsChevronRightIcon
    CSV
    • Blog banner
      • Use Case GalleryChevronRightIcon

      Tracking ElastiCube size over time

                                               

      What the solution does ✏️ This solution leverages Custom Code Notebooks and the Sisense REST API to capture ElastiCube size on a desired interval, making the data available for historical analysis.  This analysis can be performed via Dashboards, Pulse, or any other method that benefits from a basic flat file structure. Why it’s useful ✅ As mentioned in the Introduction, ElastiCube size is important because it directly impacts performance, hardware resource consumption, build times, and scalability. Efficiently managing cube size is key to maintaining a fast and stable analytics environment. There may also be licensing considerations, requiring the deployment to remain below a sizing threshold.  However, it can be challenging to monitor this data on a historical basis for purposes of trending, forecasting, or capturing anomalies.  This solution aims to remove that challenge and provide your team with this data in an easy-to-use format. 🔨How it's achieved Create a new ElastiCube and add a Custom Code table. Import the attached Notebook file, getElasticubeSize.ipynb (inside .zip) -- the raw code can also be found below Infer the schema from the Notebook Ensure LastBuildDate and SnapshotDate_UTC are set to DateTime data type “Apply” the schema changes Save the Custom Code table and rename it as desired # Test Cell # When the notebook is executed by the Build process, this cell is ignored. # See the `Test Cell` section below for further details. additional_parameters = '''{}''' from init_sisense import sisense_conn import os import json import requests import pandas as pd from datetime import datetime # Construct the Sisense server base URL server = ( "http://" + os.environ["API_GATEWAY_EXTERNAL_SERVICE_HOST"] + ":" + os.environ["API_GATEWAY_EXTERNAL_SERVICE_PORT"] ) required_columns = [ "ElasticubeName", "TenantId", "SizeInMb", "SizeInGb", "LastBuildDate", "SnapshotDate_UTC", ] def get_elasticube_size(server): """Retrieve Elasticube size and metadata from Sisense API with error handling.""" endpoint = "/api/v1/elasticubes/servers/next" # API call try: response = sisense_conn.call_api_custom("GET", server, endpoint, payload=None) response.raise_for_status() response_json = response.json() except Exception as e: print(f"API error: {e}") return pd.DataFrame(columns=required_columns) # Validate JSON list structure if not isinstance(response_json, list): print(f"Unexpected response format: {type(response_json)}") return pd.DataFrame(columns=required_columns) # Compute snapshot timestamp once for all rows snapshot_timestamp = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") ec_size_data = [] for item in response_json: size_mb = item.get("sizeInMb", 0) size_gb = (size_mb or 0) / 1024 ec_size_data.append( { "ElasticubeName": item.get("title") or pd.NA, "TenantId": item.get("tenantId"), "SizeInMb": size_mb, "SizeInGb": size_gb, "LastBuildDate": item.get("lastBuildUtc"), "SnapshotDate_UTC": snapshot_timestamp, } ) df = pd.DataFrame(ec_size_data) # Convert LastBuildDate if not df.empty: df["LastBuildDate"] = pd.to_datetime( df["LastBuildDate"], errors="coerce", utc=True ) # Format to ISO 8601 df["LastBuildDate"] = df["LastBuildDate"].dt.strftime("%Y-%m-%dT%H:%M:%SZ") # Ensure correct column order return df[required_columns] # === Main Execution === df_result = get_elasticube_size(server) print(df_result.head()) # === Write DataFrame to CSV === output_folder = "/opt/sisense/storage/notebooks/ec_size" os.makedirs(output_folder, exist_ok=True) ts = datetime.utcnow().strftime("%Y%m%d_%H%M%S") file_name = f"elasticube_sizes_{ts}.csv" output_path = os.path.join(output_folder, file_name) df_result.to_csv(output_path, index=False) print(f"CSV written: {output_path}") print("Program completed successfully.") This Custom Code hits the Sisense REST API to capture ElastiCube size, along with the capture date (for historical trending purposes).  It only serves as a starting point and can be freely edited.  Every time the cube is built, it will generate a csv of the data and place it under /opt/sisense/storage/notebooks/ec_size .  This location can be accessed in the Sisense UI via File Management – the ec_size folder may need to be created manually. To leverage the data in the csv files, I recommend creating a separate ElastiCube with a csv connection.  In the connection: Select “Server Location” Define the Input Folder Path: /opt/sisense/storage/notebooks/ec_size/ Ensure “Union Selected” is enabled.  This will combine all of the csv files into a singular data set. The reason I recommend creating a separate data model is so you don’t have to worry about table build order.  For example, if the Custom Code and CSV tables exist in the same model, it’s possible for the CSV table to be built before the Custom Code builds/executes, so the latest CSV file’s data would be missed until the next build (and so on).  By keeping the Custom Code and csv data models separate, you have more control over the build order by scheduling the builds sequentially. This dataset can be used as-is to build basic historical analyses, or you can enhance it by building separate custom tables that sit on top of it.  Further, you can modify the Custom Code table itself to pull whatever data is needed from the Sisense REST API , such as ElastiCube row counts and more.   NOTE : Similar data can be sourced from the Usage Analytics data model, using the SummarizeBuild table.  But the Custom Code solution provides more flexibility in what is pulled, when, and how long it is retained, without affecting anything else.  Additionally, each csv is available for independent review/modification as needed.

      akaplan
      akaplanPosted 6 months ago
      0
               
      • APIsChevronRightIcon

      Exporting Options in SisenseJS

                       

      Exporting Options in SisenseJS SisenseJS is a powerful tool that allows embedding widgets from Sisense into external applications. Despite it being a very straightforward way of embedding, SisenseJS has some missed functionality. For example, there are no OOTB methods to export widget's data into CSV and Excel. In this article, we will implement this functionality.  We will use a combination of Sisense REST API endpoints for exporting and capabilities of SisenseJS in order to prepare payloads. In our sample, we will create the required logic for one widget. You can replicate this logic for every widget in your implementation. Common logic When you load a dashboard, you need to save its object. For these purposes we will use a variable [currentDashboard]:     Sisense.connect('https://example.com').then(function (app) { app.dashboards.load(dashboardId).then(function (dashboard) { currentDashboard = dashboard; //Further logic to render widgets on the page }); });     In terms of our task we need to get the widget’s object we are going to export. To get this object you can run the following logic:     const getWidget = (widgetId) => { return currentDashboard.widgets.get(widgetId).$$model; }     This function returns the widget’s object. We do have the widget’s object, so we know the widget’s metadata and also we have information about the dashboard’s filters. We could use this to build a query manually, but it would be quicker to utilize the SisenseJS capabilities. When we call the function getWidget() we need to provide the widget’s identifier as an argument:     const currentWidget = getWidget('63cfd64645e8ec00324a13aa'); //Replace "63cfd64645e8ec00324a13aa" with your widget's identfier. Note, that it should be loaded and rendered     As a result, we will get the widget’s model. Later we will use it to prepare the payload. Also, we need to implement some functions to generate unique identifiers. This is not a mandatory step, but it can be useful if you want to cancel queries. Sample of the function:     function uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); }     Excel To generate payload for Excel we will use the function below:     const prepareExcelPayload = (widget) => { const query = widget.dashboard.$query.buildWidgetQuery(widget); //Use Sisense capabilities to prepare query query.queryGuid = uuidv4(); //Generate queryGuid query.dashboard = widget.dashboardid || widget.dashboard.oid; query.culture = "en-us"; //This can be set from navigator.language query.format = 'pivot'; query.metadata.forEach(function(m) { if (m.jaql && m.jaql.dim) { //We need to remove [table] and [column] delete m.jaql.table; delete m.jaql.column; } }) return JSON.stringify({ query: query, options: {} }); //Return payload for exporting in Excel }     Once the payload is prepared, we can send it to Sisense’s endpoint /engine/excelExport to retrieve the prepared Excel file. After this, we need to load the generated Excel file explicitly. Code:     function getExcel(widget) { const xhttp = new XMLHttpRequest(); xhttp.withCredentials = true; //This will be cross-domain request, so we force the browser to add cookies xhttp.onreadystatechange = function () { if (xhttp.readyState === 4 && xhttp.status === 200) { const a = document.createElement('a'); a.href = window.URL.createObjectURL(xhttp.response); a.download = widget.title ? `${widget.title}.xlsx` : 'Details.xlsx'; a.style.display = 'none'; document.body.appendChild(a); a.click(); } }; xhttp.open("POST", `${sisenseUrl}/engine/excelExport`); xhttp.setRequestHeader("Content-Type", "application/json"); xhttp.responseType = 'blob'; xhttp.send(payload); }     CSV A function to generate query:     const prepareCSVPayload = (widget) => { let query = widget.$query.buildWidgetQuery(widget, 'exportToCSV'); query = Object.assign(query, { format: "csv", isMaskedResponse: true, download: true, count: 0, offset: 0 }); query = widget.dashboard.$query.createJaqlRequestConfig(query); query.metadata.filter((item) => { return defined(item.format); }) return { data: encodeURIComponent(JSON.stringify(query)) }; }     This function returns a payload, which can be sent at the endpoint `/api/datasources/${ widget.datasource.title }/jaql/csv`. As you can see, this endpoint depends on the datasource’s title. Since the dashboard’s datasource can differ from the widgets’ datasources, I do recommend getting the correct datasource from the widget itself and for sure you need to avoid any hardcoded values.     function getCSV(widget) { let csvDownloader = new XMLHttpRequest(); csvDownloader.open('POST', `/api/datasources/${widget.datasource.title}/jaql/csv`); csvDownloader.responseType = 'arraybuffer'; csvDownloader.onload = function () { if (this.status === 200) { let filename = ""; const disposition = csvDownloader.getResponseHeader('Content-Disposition'); if (disposition && disposition.indexOf('attachment') !== -1) { const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; const matches = filenameRegex.exec(disposition); if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, ''); } const type = csvDownloader.getResponseHeader('Content-Type'); const blob = typeof File === 'function' ? new File([this.response], filename, { type: type }) : new Blob([this.response], { type: type }); if (typeof window.navigator.msSaveBlob !== 'undefined') { // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed." window.navigator.msSaveBlob(blob, filename); } else { const URL = window.URL || window.webkitURL; const downloadUrl = URL.createObjectURL(blob); if (filename) { const a = document.createElement("a"); if (typeof a.download === 'undefined') { window.location = downloadUrl; } else { a.href = downloadUrl; a.download = filename; document.body.appendChild(a); a.click(); } } else { window.location = downloadUrl; } setTimeout(() => { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup } } }; csvDownloader.withCredentials = true; csvDownloader.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); $.param(payload); csvDownloader.send(payload); }   I hope you find this article useful and leverage the knowledge shared about exporting widgets data in different formats. Please share your experience in the comments!

      Oleksii Demianyk
      Oleksii DemianykPosted 3 years ago • Last reply 1 year ago
      5
               
      • Embedding AnalyticsChevronRightIcon

      Exporting a Dashboard Into PDF with SisenseJS

                       

      Exporting a Dashboard Into PDF with SisenseJS This article explains how to develop the functionality of generating PDF with the shown widgets when Sisense dashboard is embedded with SisenseJS.   When the dashboard is exported into PDF, the report is generated on the Sisense server. When a dashboard is embedded with SisenseJS, then developers can create their own layout, which can differ from the layout created by the dashboard’s designer. SisenseJS does not provide an option to export the shown widgets to PDF, because Sisense will not be able to render the same layout that is used in the parent application. Nevertheless, the shown dashboard can be easily exported into PDF. For exporting we need to use the external library [html2pdf.js]. More information about this library can be found at this link . This library should be added to the page:         <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>         Once this library is loaded and Sisense widgets are rendered on the page, you can call methods from this library in order to generate PDF reports. To utilize the methods of this library, I created a function exportToPDF() and variable [opt]. Variable [opt] stores settings that will be used to initiate exporting to PDF. In the sample below, the returned file will be named “myfile.pdf”. Function exportToPDF() expects a DOM element that contains the rendered widgets. HTML of the given element will be rendered in the returned PDF:         const opt = { filename: 'myfile.pdf', //File name }; function exportToPDF(lmnt) { const dashboardContainer = document.getElementById(lmnt); html2pdf().set(opt).from(dashboardContainer).save(); }         Sample of this logic execution:         exportToPDF('sisenseApp');          In the generated PDF the widgets will be placed as the developer placed them. Using this approach you can easily implement the functionality of generating PDF reports.  Feel free to use this logic and modify them according to your needs! 

      Oleksii Demianyk
      Oleksii DemianykPosted 3 years ago • Last reply 2 years ago
      1
               
    • Blog banner
      • TroubleshootingChevronRightIcon

      Workaround for "File exceeds Limitation of 500 MB"

                               

      Workaround for "File exceeds Limitation of 500 MB" If you try to import a CSV file to Elasticube and receive a message "File exceeds the limitation of 500 MB" As a workaround, you may upload large .csv files to the File Manager and then point to them. To point to a file in the File Manager you need to choose 'Input File Path' option  and have the prefix: '/opt/sisense/storage/' before the file path. You can create a separate folder for this or use the root directory.

      OleksandrB
      OleksandrBPosted 2 years ago
      0
               
      • How-Tos & FAQsChevronRightIcon

      How to Hide Export to Excel Option On a Pivot Table (Linux)

                               

      How to Hide Export to Excel Option On a Pivot Table (Linux) This article provides an example of a code snippet that could be used to hide a specific option from the Download menu on a widget level. If you find yourself needing to hide the export to Excel option for some widgets, it might be possible to achieve it with the help of JavaScript.  Note:   The script was developed on L2023.3 Sisense Linux-based version.  This is an example JavaScript code snippet that could be used for hiding the export to Excel option from the Download menu. In order to apply it, open the pivot in edit mode and click the 3 dots menu:     Paste the following code snippet and Save the changes:       widget.on('beforewidgetindashboardmenu', (se, ev) => { ev.items.find(i => i.id === 'download').items = ev.items.find(i => i.id === 'download').items.filter(i => !i.command || (i.command && i.command.title !== "dashboard.widget.commands.excel.title")) });     After that press "Apply" on the widget. That's it! Before:     After:     Feel free to use this code snippet as an example and enhance it further to achieve similar goals and share such solutions with us! Disclaimer: Please note, that this blog post contains one possible custom workaround solution for users with similar use cases. We cannot guarantee that the custom code solution described in this post will work in every scenario or with every Sisense software version. As such, we strongly advise users to test solutions in their own environment prior to deploying them to ensure that the solutions proffered function as desired in their environment. For the avoidance of doubt, the content of this blog post is provided to you “as-is” and without warranty of any kind, express, implied or otherwise, including without limitation any warranty of security and or fitness for a particular purpose. The workaround solution described in this post incorporates custom coding which is outside the Sisense product development environment and is therefore not covered by not covered by Sisense warranty and support services.

      Liliia Kislitsyna
      Liliia KislitsynaPosted 3 years ago • Last reply 2 years ago
      3
               
      • TroubleshootingChevronRightIcon

      Error exporting to PDF

                               

      Sisense allows you to generate a PDF report of your dashboard when you need to take copies of your dashboards with you for meetings or sharing them with others. This article gives detailed  troubleshooting steps on how to handle PDF export failures on all Sisense versions. How Does It Work?   When you click  Download PDF  or the PDF icon in the menu bar , a preview of your report is opened. After you have defined the appearance of your report, you can save the layout of the dashboard by clicking  Save . The next step is to click  Download PDF , your saved layout will be downloaded into a PDF file. Disable All Plugins One of the most common causes of a PDF export failure is due to a faulty plugin. If you cannot export any report to PDF, then the issue is most likely due to plugins. Firstly, disable all the plugins. To do so, go to  Admin →  Plugins  under  System Configuration  and toggle the switch to disable each plug-in. To disable all plugins at once, select each Plug-in and toggle the  Disable Selected  switch:   If the report is exported to PDF successfully, then you can switch on the plug-ins one-by-one to find the problematic one. When you find a problematic plug-in, make sure you have the latest version of the plug-in installed. If disabling all plugins does not work we recommend going to the actual "plugins" folder on the Sisense server and removing all the plugin folders manually.   For versions 7.2 and higher the "plugins" folder can be found in C:\Program Files\Sisense\app\plugins   For versions 7.1 and lower the "plugins" folder can be found in C:\Program Files\Sisense\PrismWeb\plugins Disable All Scripts An easy way to determine where the issue is, is to create a new simple widget and try to export it. If the dashboard is exported successfully, it means that the issue is local, and you need to check the scripts applied to your widgets and dashboards.   Try to disable your scripts to understand if it affects your PDF exports. Once you find the broken script, you will need to fix it.   To disable a script, you need to open the Script Editor and disable your script by commenting it out. It can be commented out by adding ‘//’ to the beginning of each row.     For dashboard scripts, for the dashboard, in your dashboard, click  Edit Script   For a specific widget, click on the widget in  Edit  mode. 7.2 And Later Further Troubleshooting If you are using Sisense installation which is on V7.2 and above and still experiencing errors with PDF exports, it is possible that it is related to a Configuration Manager setting.   To troubleshoot this, on a Sisense webserver take the following steps: (please note that this could make your site unavailable for a short period of time so take care to do this off-hours if in a production environment) In a web browser (Chrome is preferred but any of the supported web browsers are OK), navigate to http://localhost:3030 You will see the Configuration Manager appear Scroll down to the "Domain Binding" section. If this field is populated, remove the entry. There are only a few specific reasons to have this set. If your Sisense domain is attached to the server via a DNS entry you typically do not need to set this. Click the 'Save' button at the top right-hand corner 7.1 And Earlier Further Troubleshooting If you are using Sisense installation which is below V7.2 and still experiencing errors with PDF exports, it is possible that it is related to a local configuration file issue.    To verify the configuration is correct, please follow the below: If you have an domain defined on your server, make sure the setting in 'Admin'-->'system configuration' does not include "http://" Make sure that you have access to the domain URL from the local server (ie. http://bi.my.company.com/ ) If you have SSL configured  - please make sure you can browse to the secure site locally as well  (ie. https://bi.my.company.com/ ) Check bindings: Open the Windows IIS Manager -> Navigate to each of the websites -> "Bindings" and make sure that no two websites bind to same port (double bindings) Go to "Add or Remove Programs" -> Right click on Sisense and choose "Change..." -> In installation window "Continue" -> "Change Settings" and verify that the port configured matches the port specified in the IIS Manager for Sisense Web   If these troubleshooting steps do not fix the issue, you may need to edit the exporting section of the default.yaml file. Find the file here: C:\Program Files\Sisense\PrismWeb\vnext\config The exporting section is located at the end of the file, and there are 3 variables you may have to change- host, port, and protocol. Please set these variables to the values that are used to access Sisense Web on the server. For example, if you access Sisense Web by going to http://test.dashboards.com , you would set the variables tohost: "test.dashboards.com" port: 80 protocol: "http" After making the changes, save the file, and restart IIS. Log Files For further investigation detailed logs on the any PDF related errors can be found below For Sisense V7.1.3 and earlier: C:\Program Files\Sisense\PrismWeb\vnext\iisnode For Sisense V7.2 and later: C:\ProgramData\Sisense\application-logs If you are still seeing issues after following this guide please feel free to contact Sisense Support for further assistance

      intapiuser
      intapiuserPosted 3 years ago
      0