Unlocking the power of Compose SDK to build and publish visualizations and add-ons

By Steven Griffith, Director of SDK

1 2 3 4 5 6 7 8 9 10 return ( <Histogram       dataSource={DM.DataSource}       dataOptions={{         category: [DM.Commerce.AgeRange],         value: DM.Commerce.Revenue,       }}       styleOptions={{ subtype: 'stacked' }}     /> );
1 2 3 4 5 6 7 8 9 10 export type HistogramProps = {   dataSource?: DataSource;   dataOptions: HistogramDataOptions;   filters?: Filter[];   styleOptions?: HistogramStyleOptions; }; export interface HistogramDataOptions {   value: Attribute;   category: Attribute[]; }
1 2 3 export interface HistogramStyleOptions {   binCount?: number | "auto"; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // construct a query to get min, max, and count of data points based on the input value   const minMeas = useMemo(() => measureFactory.min(dataOptions.value, 'min'), [dataOptions.value]);   const maxMeas = useMemo(() => measureFactory.max(dataOptions.value, 'max'), [dataOptions.value]);   const countMeas = useMemo(     () => measureFactory.count(dataOptions.value, 'count'),     [dataOptions.value],   );   const queryMinMax = useMemo(     () => ({       measures: [minMeas, maxMeas, countMeas],       filters,     }),     [minMeas, maxMeas, countMeas, filters],   );   const {     data: minMaxData,     isLoading: isMinMaxLoading,     error: isMinMaxError,   } = useExecuteQuery(queryMinMax);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const MAX_BARS = 60; const MIN_BARS = 3; let binCount =    !styleOptions?.binCount || styleOptions.binCount === 'auto'    ? Math.floor(Math.sqrt(count)) : styleOptions.binCount; binCount = Math.max(binCount, MIN_BARS); binCount = Math.min(binCount, MAX_BARS); const binRange = (maxValue - minValue) / binCount; const binMeasures = Array(binCount)       .fill(0)       .map((_v, index) => {         const min = minValue + index * binRange;         const max = min + binRange;         const binFilter = filterFactory.between(dataOptions.value, min, max);         return measureFactory.measuredValue(           countMeas,           [binFilter],           binLabel(min, max, styleOptions?.binSizePrecision),         ); });
1 2 3 4 5 6 7 8 9 10 const {   data: binData,   isLoading,   error, } = useExecuteQuery({     measures: binMeasures,     filters,     dimensions: dataOptions.category,   } );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 export const useProcessResults = ({   binData,   dataOptions, }: {   binData?: QueryResultData;   dataOptions: HistogramDataOptions; }) => {   return useMemo(() => {     if (!binData) return { columns: [], rows: [] };     const rows: (number | string)[][] = [];     binData.rows.forEach((_row, rowIndex) => {       binData.columns.forEach((column, colIndex) => {         if (colIndex >= dataOptions.category.length) {           const row: (number | string)[] = [];           const currentRow = binData.rows[rowIndex];           if (currentRow) {             dataOptions.category.forEach((_d, dimIndex) => {               row.push(currentRow[dimIndex]?.data as number);             });             row.push(currentRow[colIndex]?.data as number);             row.push(parseFloat(column.name));             rows.push(row);           }         }       });     });     return {       columns: [         ...dataOptions.category.map((d) => ({ name: d.name, type: d.type })),         { name: FREQUENCY, type: 'number', aggregation: 'sum' },         { name: dataOptions.value.name, type: 'number' },       ],       rows: rows,     } as Data;   }, [binData, dataOptions.value.name, dataOptions.category]); };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const columnStyleOptions = useMemo<StackableStyleOptions>(     () => ({       subtype: styleOptions?.subtype === 'stacked' ? 'column/stackedcolumn' : 'column/classic',     }),     [styleOptions?.subtype],   );  const columnChartDataOptions = useMemo(     () => ({       category: [dataOptions.value],       value: [{ name: FREQUENCY }],       breakBy: dataOptions.category,     }),     [dataOptions.value, dataOptions.category],   );   return (     <ColumnChart       dataSet={histogramData}       dataOptions={columnChartDataOptions}       onBeforeRender={onBeforeRender}       styleOptions={columnStyleOptions}     />   );
1 yarn add more-compose-sdk-charts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import React from "react"; import { Histogram } from "more-compose-sdk-charts"; import { filters } from "@sisense/sdk-data"; import * as DM from "./sample-ecommerce"; export default function App() {   const revenueFilter = filters.between(DM.Commerce.Revenue, 0.01, 1000);   const yearFilter = filters.members(DM.Commerce.Date.Years, ['2012-01-01']);   return (     <Histogram       dataSource={DM.DataSource}       dataOptions={{         category: [DM.Commerce.AgeRange],         value: DM.Commerce.Revenue,       }}       filters={[revenueFilter, yearFilter]}       styleOptions={{ subtype: 'stacked' }}     />   ); }

Get the latest in analytics right in your inbox.