Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Component

Title

DashletsDashlet

Selector

<sb-dashlet>

Use Case

Dashlets are reporting widgets that can be embedded in any contextual workflow - whether on a consumption, creation or administration screen. Any solution that needs to use dashlets can configure the dashlet with a data source, type of visualisation (bar, line, pi, table, map etc), legends, filters etc.

Description

This generic component/widget will be used to render a chart, table, dataset, map or any other report type. It can make use of multiple libraries & also support building custom components with a common interface.

...

  • This is the interface that every chart component should implement and extends the IBase interface

  • config takes the required metadata to render a chart like label datasets/series, tooltips legend, title, axes detailes etc. Please refer to the below . image to know most commonly used chart concepts. Interface also allows additional metadata if required.

  • labelExpr - refers to the column name or key in the JSON which can be used as x axis labels

  • dataExpr - refers to the key in the JSON to be used on y axis as dataset.

...

Code Block
breakoutModewide
interface IChart extends IBase {
    
    readonly reportType: IReportType = "chart"
  
    readonly _defaultConfig: IChartConfig; // default config for tooltips colors legend etc.
    
    type: IChartType;

    config: IChartConfigIChartOptions; 

    chartClick: EventEmitter<any>;
    chartHover: EventEmitter<any>;

    chartBuilder(config); // (prepares / converts) input chart config as per the underlying chart library used.

    refreshChart(); // refreshes and updates the chart either at specific interval or explicitly triggerd

    addData({ label, data, config }); //appends the label and data at the end;

    removeData(); //pops the last data and label
    removeData(label: string) // removes a specific label

    getTelemetry();

    // mergeData(data1, data2, ...dataN): any[];

    getCurrentSelection(); 
    
    getDatasetAtIndex(index: number);
}

/*
##########################################################################
*
*.         depenedent interfaces are as follows:-
*
##########################################################################
*/


interface IChartConfig {
    type: IChartType;
 


options?: IChartOptions;
    [key: string]: any;
}

type IChartType = "bar" | "line" | "pie" | "etc";

type IChartOptions = {
    labels? : string[], // if labels are passed explicitely
    labelExpr ? : string; // column name to use as x-axis labels;
    datasets: IDataset[]; // datasets - y axis data
    tooltip?: object;
    legend?: object
    animation?: object;
    colors?: object;
    title?: string;
    description: string;
    subtitle?: string;
    caption?: object;
    filters?: IFilterConfig;
    scales?: {
        axes: any;
        [key: string]: any;
    };
    [key: string]: any;
};

type IDataset  = {
    label: string;
    dataExpr?: string;
    data: any[];
}

...

Code Block
breakoutModewide
interface ITable extends IBase {

    readonly reportType: IReportType = "table"

    readonly _defaultConfiguration: ITableConfig;

    config: ITableConfig[];

    getRowsCount(); // rows count
    getRowAtIndex(index: number);   //get row at index number
    rowSelector(selectors); //fetch first row matching the config
    rowSelectorAll(selectors); // fetch rows matching a config

    addRow(data: object); // add a new row to the table by passing row configuration
    removeRow(index?: string); //removes row from the end or  at specific index;
    addColumn(config: ITableConfiguration); // adds a new column at the end
    removeColumn(columnName: string); // removes a column

    rowClick: EventEmitter<any>; // row click  event emitter
    rowHover: EventEmitter<any>; // mouse over event emitter

    exportTable(exportType: string); // exports the table into a type
    sortTable(sortByColumnName: string, orderBy: "asc" | "desc");
}


/*
##########################################################################
*
*.         depenedent interfaces are as follows:-
*
##########################################################################
*/

interface ITableConfig {
  paging:  titleboolean; // to show pagination below the table
  info: boolean; // to show count or other info below the table
  columnConfig: {
      title?: string;    // header name for the column
      searchable?: boolean; // if the column is searchable or not - will be used by the search bar at the top
      orderable?: boolean;  // if the column can be ordered or sorted in asecending or descending fashion
      data?: string;  // key in the input JSON to be used as column
      visible?: boolean; // hides or shows a column within a table
      render?: () => any;  // method to override the view and customise it like showing a button or chip instead of normal text
      autoWidth?: boolean;
      widthSize?: string; // customised width either in percentage or fixed width
      [key: string]: any; //any other metadata
      }
}

...

Filters Config and Component Design

...

This component and interface it to make a generic filter which will serve all for all the reportTypes.

...

Code Block
breakoutModewide
languagejs
abstract class Filter<T> {

    data: T[];

    config: IFilterConfig[];

    filteredDataEventEmitter: EventEmitter<T[]>

    abstract init(config: IFilterConfig); //Get the initialisation options to render the filters;

    abstract filterData(data: T, config): object[];
}


interface IFilterConfig {
    reference: string;
    label: string;
    placeholder: string;
    controlType: "single-select" | "multi-select" | "date";
    searchable?: boolean;
    filters: IFilterConfig[];
    default?: string;
}

/* Questions

    Nested Filter Capability..

*/

🧐 Implemenation Approach

Dashlet Main Component Proposed Structure

...

Code Block
breakoutModewide
languagehtml
<sb-dashlet [type]="string" [config]="config" [data]="data | IDataLocation" , [id]="string | uuid" [height]="string"
    [width]="string" (...anyOtherEvent)="eventListener($event)">

</sb-dashlet>

Example of a Pie Chart using the Component

...

Code Block
breakoutModewide
language

...

<sb-dashlet [config]="config" (chartClick)="chartClickHandler($event)" (chartHover)="chartHoverHandler($event)"></sb-dashlet>

...

breakoutModewide
json
let data =  [
    

...

 

...

 

...

 

...

 {
        

...

    "District": "

...

Ariyalur",
        

...

 

...

   "Unique Devices on app": "6443.0",
   

...

 

...

        "Unique Devices on portal": "1332.0"

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

},

...

 

...

 

...

 

...

     {
       

...

 

...

 

...

 

...

  "District": "Chennai",
            "Unique Devices on app": "81222.0",
  

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

"Unique Devices on portal": "12349.0"
        

...

},
        {
 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

    "District": "Coimbatore",
     

...

 

...

      "Unique Devices on app": "49100.0",
  

...

 

...

         "Unique Devices on 

...

portal": 

...

"5690.0"
        },
       

...

 

...

{
            "District": "Cuddalore",
     

...

 

...

      "Unique Devices on app": "4330.0",
          

...

  "Unique Devices on portal": "6524.0"
        },
        {

...

 

...

           

...

"District": "Dharmapuri",
            "Unique Devices on app": "7133.0",
   

...

         "Unique Devices on portal": "8236.0"
   

...

     

...

}
    

...

]

Example of a Line Chart using the Component

...

Code Block
breakoutModewide
languagehtml
<sb-dashlet [type]="'line'" [data]="data" [config]="config" (chartClick)="chartClickHandler($event)" (chartHover)="chartHoverHandler($event)"></sb-dashlet>

Code Block
breakoutModewide
languagejs
let config: IChartConfig = {
    "title": {
        "text": "Unique Count on App backgroundColor: 'rgba(148,159,177,0.2)',and Portal",
        "display": true,
        borderColor"fontSize": 'rgba(148,159,177,1)',16
    },
    "legend": {
     pointBackgroundColor: 'rgba(148,159,177,1)',  "display": true
    },
    "tooltips": {
  pointBorderColor: '#fff',     "bodySpacing": 5,
          pointHoverBackgroundColor"titleSpacing": '#fff',5
    },
    "responsive": true,
     pointHoverBorderColor: 'rgba(148,159,177,0.8)'"colors": [
        {
    }         ]"backgroundColor": "rgba(148,159,177,0.2)",
          legends: true  "borderColor": "rgba(148,159,177,1)",
        }     }

Component specs:-

Properties

  • type: string - indicates the type of charts, it can be: line, bar, radar, pie, polar area, doughnut

  • datasets ({data: SingleDataSet, label: string}[]) - data see about, the label for the dataset which appears in the legend and tooltips

  • labels (Label[]) - x-axis labels. It's necessary for charts: line, bar, and radar. And just labels (on hover) for charts: polar area, pie, and a doughnut. The label is either a single string, or it may be a string[] representing a multi-line label where each array element is on a new line.

  • options (ChartOptions) - chart options as per the IChartConfig for title, legend, tooltips configuration.

  • colors (Color[]) - data colors, will use the default and|or random colors if not specified (see below)

  • legend: (boolean = false) - if true show legend below the chart, otherwise not be shown

Events

  • chartClick: fires, when click on a chart, has occurred, returns information regarding active points and labels

  • chartHover: fires when mousemove (hover) on a chart has occurred, returns information regarding active points and labels

Map Using Dashlet Component

...

...

"pointBackgroundColor": "rgba(148,159,177,1)"
        }
    ],
    "datasets": [
        {
            "label": "Total unique plays on App",
            "dataExpr": "Unique Devices on app"
        },
        {
            "label": "Total unique plays on Portal",
            "dataExpr": "Unique Devices on portal" 
        }
    ],
    "labelsExpr": "District"
}

More Information :-

labelExpr - key in the JSON which will act as x-axis labels.

dataExpr - key in the JSON which will act as y-axis dataset/Series

Map Using Dashlet Component

...

Code Block
breakoutModewide
languagehtml
<sb-dashlet [type]="'map'" [configdata]="optionsdata" [mapDataconfig]="mapDataconfig" (featureClicked)="eventListener($event)">
</sb-dashlet>

<script>

    let mapDataconfig = {
        state: 'KarnatakaTamil Nadu',
        districts: ['BengaluruAriyalur', 'Chennai', 'Coimbatore', 'Cuddalore', 'MysuruDharmapuri'],
        reportDatametrics: [{}, {}],
     'Unique Devices on app', Unique Devices on portal],
  reportLoc: 'url',     title: 'Tamil Nadu Weekly metrics: [''],Usage'
        // country: 'India', // Optional - to show india map with states
        // states: ['Karnataka'], // Optional - list of states to show on the map
    }


  // default config and can be overridden with new configurations...

     let optionsotherOptions = {
        initialCoordinate: [20, 78],
        latBounds: [6.4626999, 68.1097],
        lonBounds: [35.513327, 97.39535869999999],
        initialZoomLevel: 5,
        controlTitle: 'IndiaTamil Nadu HeatWeekly MapUsage',
        tileLayer: {
            urlTemplate: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
            options: {
                attributions: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
            }
        },
        rootStyle: {
            fillColor: '#007cbe'
        },
        otherOptions: any
    },
        rootStyle: {;
</script>

...

Table Example using Dashlet Component

...

Code Block
breakoutModewide
languagehtml
<sb-dashlet type="'table'" [data]="data" [config]="config" (rowClickHandler)="eventListener($click)"> 
</sb-dashlet>

<script>

    let    columnsConfiguration = {
 fillColor: '#007cbe'        paging: }true,
        otherOptions: any info: true,
  };
</script>

Table Example using Dashlet Component

...

Code Block
breakoutModewide
languagehtml
<sb-dashlet [data]="[{}]" [config]="columnsConfiguration" (rowClickHandler)="eventListener($click)">  </sb-dashlet>  <script>  columnConfig: [
  let  columnsConfiguration = [{        { title: string"District", data: "District", searchable: true, orderable: true, autoWidth: true, searchablevisible: true boolean},
        orderable: boolean,     { title: "Unique App Count", data: 'key',
        visible: boolean,
    "Unique Devices on app", searchable: true, orderable: true, autoWidth: true, visible: true },
   render: () => {},        { pagingtitle: boolean,"Unique Portal Count", data: "Unique Devices on portal",  infosearchable: booleantrue, orderable: true, autoWidth: true, visible:    autoWidth: boolean,true },
         others: any]
    }]

</script>

...

Notes

  • If there are more charts in a single report, then each graph should be lazy-loaded to improve page performance.

  • client-side caching for the datasets.

...