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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
<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 | |||
---|---|---|---|
|
...
<sb-dashlet [config]="config" (chartClick)="chartClickHandler($event)" (chartHover)="chartHoverHandler($event)"></sb-dashlet>
...
breakoutMode | wide |
---|
| |
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 | ||||
---|---|---|---|---|
| ||||
<sb-dashlet [type]="'line'" [data]="data" [config]="config" (chartClick)="chartClickHandler($event)" (chartHover)="chartHoverHandler($event)"></sb-dashlet> |
Code Block | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
<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: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' } }, rootStyle: { fillColor: '#007cbe' }, otherOptions: any }, rootStyle: {; </script> |
...
Table Example using Dashlet Component
...
Code Block | ||||
---|---|---|---|---|
| ||||
<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 | ||||
---|---|---|---|---|
| ||||
<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.
...