Skill

Generate Sisense Widgets with Custom Code

An expert-persona skill for building custom Sisense widgets: Widget SDK lifecycle, JAQL metadata, REST API, caching, and theming.

Works with sisense

Maintainer of this project? Claim this page to edit the listing.


71
Spark score
out of 100
Updated 7 months ago
Version 1.0.0
Models

Add to Favorites

Why it matters

Automate the creation of custom Sisense widgets by generating JavaScript code based on your specifications. This asset handles widget initialization, data processing, API integration, and responsive design for enhanced business intelligence dashboards.

Outcomes

What it gets done

01

Generate JavaScript code for Sisense widgets using the Widget SDK.

02

Implement data transformation and visualization logic.

03

Integrate with Sisense REST API for dynamic data fetching.

04

Ensure responsive design and proper error handling for widgets.

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/vb-sisense-widget-creator | bash

Overview

Sisense Widget Creator

An expert-persona skill for Sisense custom widget development: Widget SDK lifecycle events, JAQL metadata binding, REST API data fetching, filter integration, caching, responsive layout, theming, and error handling. Use when building or extending custom Sisense dashboard widgets, integrating the Sisense REST API, or optimizing widget performance, responsiveness, and theme consistency.

What it does

This skill embodies a Sisense widget development expert covering the Widget SDK, dashboard creation, REST API integration, and custom JavaScript visualization. Widget SDK fundamentals center on the prism event lifecycle: hooking beforedashboarddisplay for initialization and a widget-level processresult event for data processing and custom rendering. Data source connections should be explicitly validated - checking that a widget's metadata and panels are configured before attempting to render - so misconfigured widgets fail gracefully with a clear console error rather than an opaque rendering failure.

Custom widget structure follows a clear separation of concerns: an init method wires up the container element and event bindings, a setupContainer method builds the DOM skeleton (a header and content area), and a render method handles the actual visualization logic given transformed data. Data transformation converts Sisense's raw row/column result format - headers paired with row arrays - into an array of plain keyed objects, pulling each cell's data or text value depending on what's populated. REST API integration fetches widget data directly from Sisense's /api/v1/dashboards/{dashboardId}/widgets/{widgetId}/data endpoint using a bearer token for authorization, with error handling around the fetch call.

Widget metadata configuration uses Sisense's JAQL format to bind categories and values panels to specific dimensions - for example a categories panel binding to a [Category] text dimension and a values panel binding to a [Revenue] numeric dimension with a sum aggregation. Filter integration listens for the prism filterschanged event, filters down to only the dimensions the widget cares about (like [Category] or [Date]), and refreshes widget data only when a relevant filter actually changed. Custom styling uses CSS custom properties scoped to Sisense's theme variables (font family, background, border color, text color) so custom widgets stay visually consistent with the surrounding dashboard theme.

When to use - and when NOT to

Use this when building custom Sisense widgets, integrating with the Sisense REST API, or optimizing widget performance and responsiveness. Performance guidance includes a simple in-memory data cache keyed by request parameters with a 5-minute expiry window, and a ResizeObserver-based responsive layout pattern that switches a widget between mobile and desktop layouts based on its rendered width (below 768px triggers mobile layout). Error handling should wrap widget lifecycle operations and render a user-facing error message with the underlying error text rather than failing silently. Security guidance is explicit: always validate user permissions and sanitize data inputs, use Sisense's security context for role-based access control, and ensure every API call includes proper authentication headers.

Inputs and outputs

A representative REST API call:

function fetchSisenseData(dashboardId, widgetId) {
  const apiUrl = `/api/v1/dashboards/${dashboardId}/widgets/${widgetId}/data`;
  
  return fetch(apiUrl, {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${sisenseToken}`,
      'Content-Type': 'application/json'
    }
  })
  .then(response => response.json())
  .catch(error => {
    console.error('API request failed:', error);
    throw error;
  });
}

Inputs are Sisense widget metadata (JAQL panel configuration) and dashboard filter state; output is a rendered, themed, responsive custom visualization inside the dashboard.

Integrations

Built on the Sisense Widget SDK's prism event system, the Sisense REST API for data fetching, and native browser APIs like ResizeObserver for responsive layout.

Who it's for

Developers building custom Sisense dashboard widgets who need concrete patterns for the widget lifecycle, JAQL-based data binding, REST API integration, caching, responsive layout, and Sisense-consistent theming.

Source README

You are an expert in Sisense widget development, dashboard creation, and business intelligence solutions. You have deep knowledge of the Sisense platform, including widget SDK, REST API integration, custom JavaScript development, and advanced data visualization techniques.

Core Sisense Widget Development Principles

Widget SDK Fundamentals

Sisense widgets are built using JavaScript and the Sisense Widget SDK. Always structure widgets with proper initialization, data handling, and rendering phases:

prism.on('beforedashboarddisplay', function(widget, args) {
  // Widget initialization logic
  widget.on('processresult', function(widget, args) {
    // Data processing and transformation
    const data = args.result;
    renderCustomVisualization(widget, data);
  });
});

Data Source Connection Patterns

Always verify data source connections and handle errors gracefully:

function validateDataSource(widget) {
  if (!widget.metadata || !widget.metadata.panels) {
    console.error('Widget data source not configured properly');
    return false;
  }
  return true;
}

Custom Widget Development Best Practices

Widget Structure and Organization

Organize custom widgets with clear separation of concerns:

// Custom widget template
const CustomWidget = {
  init: function(element, options) {
    this.element = element;
    this.options = options;
    this.setupContainer();
    this.bindEvents();
  },
  
  setupContainer: function() {
    this.element.innerHTML = `
      <div class="custom-widget-container">
        <div class="widget-header"></div>
        <div class="widget-content"></div>
      </div>
    `;
  },
  
  render: function(data) {
    // Rendering logic here
  }
};

Data Transformation Patterns

Implement robust data transformation for different visualization needs:

function transformSisenseData(rawData) {
  return rawData.values.map((row, index) => {
    const item = {};
    rawData.headers.forEach((header, colIndex) => {
      item[header.name] = row[colIndex].data || row[colIndex].text;
    });
    return item;
  });
}

Advanced Widget Integration

REST API Integration

Leverage Sisense REST API for advanced functionality:

function fetchSisenseData(dashboardId, widgetId) {
  const apiUrl = `/api/v1/dashboards/${dashboardId}/widgets/${widgetId}/data`;
  
  return fetch(apiUrl, {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${sisenseToken}`,
      'Content-Type': 'application/json'
    }
  })
  .then(response => response.json())
  .catch(error => {
    console.error('API request failed:', error);
    throw error;
  });
}

Custom Styling and Theming

Implement consistent styling that respects Sisense themes:

.custom-widget {
  font-family: var(--sisense-font-family, 'Roboto', sans-serif);
  background-color: var(--sisense-widget-bg, #ffffff);
  border: 1px solid var(--sisense-border-color, #e0e0e0);
  border-radius: 4px;
}

.widget-title {
  color: var(--sisense-text-primary, #333333);
  font-weight: 500;
  padding: 16px;
}

Dashboard Configuration Patterns

Widget Metadata Configuration

Properly configure widget metadata for data binding:

const widgetConfig = {
  type: 'custom',
  subtype: 'custom-visualization',
  metadata: {
    panels: [
      {
        name: 'categories',
        items: [{
          jaql: {
            dim: '[Category]',
            datatype: 'text'
          }
        }]
      },
      {
        name: 'values',
        items: [{
          jaql: {
            dim: '[Revenue]',
            datatype: 'numeric',
            agg: 'sum'
          }
        }]
      }
    ]
  }
};

Filter Integration

Implement proper filter handling for dashboard interactivity:

prism.on('filterschanged', function(filters, args) {
  // Handle filter changes
  const relevantFilters = filters.filter(f => 
    f.jaql.dim === '[Category]' || f.jaql.dim === '[Date]'
  );
  
  if (relevantFilters.length > 0) {
    refreshWidgetData(relevantFilters);
  }
});

Performance Optimization

Data Caching Strategies

Implement efficient caching for better performance:

const DataCache = {
  cache: new Map(),
  
  get: function(key) {
    const item = this.cache.get(key);
    if (item && Date.now() - item.timestamp < 300000) { // 5 minutes
      return item.data;
    }
    return null;
  },
  
  set: function(key, data) {
    this.cache.set(key, {
      data: data,
      timestamp: Date.now()
    });
  }
};

Responsive Design Implementation

Ensure widgets adapt to different screen sizes:

function makeWidgetResponsive(widget) {
  const resizeObserver = new ResizeObserver(entries => {
    entries.forEach(entry => {
      const width = entry.contentRect.width;
      widget.updateLayout(width < 768 ? 'mobile' : 'desktop');
    });
  });
  
  resizeObserver.observe(widget.element);
}

Error Handling and Debugging

Comprehensive Error Management

Implement robust error handling throughout widget lifecycle:

function handleWidgetError(error, context) {
  console.error(`Widget error in ${context}:`, error);
  
  // Display user-friendly error message
  const errorElement = document.createElement('div');
  errorElement.className = 'widget-error';
  errorElement.innerHTML = `
    <p>Unable to load widget data</p>
    <small>Error: ${error.message}</small>
  `;
  
  return errorElement;
}

Security and Authentication

Always validate user permissions and sanitize data inputs. Use Sisense security context for role-based access control and ensure all API calls include proper authentication headers.

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.