...
Title | Dashlets |
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. |
🧐 Interface Design
...
Interface Diagrams
...
IBase<T> if the base interface providing common properties and behaviours.
IChart , ITable or any report Type interface will extend the IBase<T> interface and will add it’s own properties and behaviours with respect to it’s use case.
Any Chart Component will implement IChart interface whereas table Components will implement ITable interface and will provide their own implementation of the specified properties and methods.
Detailed Explaination of the Interfaces
IBase Interface
IBase. - This is the base interface that every report Type component should implement.
It deals with provides the base common attributes and behaviours for each dashlet component like height, width , fetching the data , initialization of the component.
Code Block | ||||
---|---|---|---|---|
| ||||
interface IBase <T> { reportType: IReportType; readonly _defaultConfig: object; // default configurations as per the reportType height: string; width: string; id: string; config: object; // input metaconfiguration for the dashlets component. It should be as per the report type. Refer to next sections for more details as per the report Type data: <T>[] | IDataLocation; // input data either in JSON format, url or API configuration; state: EventEmitter<IReportState>; initialize(config: object, data: T[]); // Get the initialisation options used for rendering. reset(): void; // resets the component to initial view destroy(): void; // performs cleanup post the component is destroyed; update(config); // updates and re renders the view fetchData<T>(): Promise<T[]> | Observable<T[]>; /* genetic methods for addition and removal of data; addData(); removeData */ } type methodType/* =########################################################################## "GET" | "POST";* *. interface IApiConfig { depenedent url:interfaces string;are as follows:- * ########################################################################## headers:*/ { type IReportType = "chart" | "table" | "etc" type methodType = "GET" | "POST"; interface IApiConfig { url: string; headers: { [header: string]: string | string[]; }; methodType: methodType; params: { [param: string]: string | string[]; }; response: { path: string; //Gets the value at path of response object; } } interface IDataSchema { type: string, enum?: string[], default?: string, format?: string; //url, date etc items?: IDataSchema // if type is array } interface IDataLocation { location?: { apiConfig?: IApiConfig; url?: string; }, dataSchema?: { [key: string]: IDataSchema; } } type IReportState = "initialized" | "rendered" | "destroyed" | "etc"; // pending or done state; interface EventEmitter<T>{ emit(value? : T); subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription; } |
...
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 parts concepts. Interface also takes 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 _defaultConfig: IChartConfig; // default config for tooltips colors legend etc. config: IChartConfig; readonly reportType: IReportType = "chart" readonly _defaultConfig: IChartConfig; // default config for tooltips colors legend etc. config: IChartConfig; 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); } /* ########################################################################## * *. chartClick: EventEmitter<any>;depenedent interfaces are as chartHoverfollows:- EventEmitter<any>;* ########################################################################## */ interface chartBuilder(config); // (prepares / converts) input chart config as per the underlying chart library used.IChartConfig { type: IChartType; options?: IChartOptions; [key: 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); } 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; scales?: { axes: any; [key: string]: any; }; [key: string]: any; }; type IDataset = { label: string; dataExpr?: string; data: any[]; } |
ITable Interface - Base Interface for Table Components. <ReportType = Table>
...
breakoutMode | wide |
---|
...
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;
scales?: {
axes: any;
[key: string]: any;
};
[key: string]: any;
};
type IDataset = {
label: string;
dataExpr?: string;
data: any[];
} |
...
ITable Interface - Base Interface for Table Components. <ReportType = Table>
This interface is implemented by every table report type and extends the IBase Interface.
Code Block | ||
---|---|---|
| ||
interface ITable extends IBase { readonly reportType: IReportType = "table" readonly _defaultConfiguration: ITableConfig; config: ITableConfiguration[]; 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 { 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; paging?: boolean; any; // method to override the view and customise it like showing a button or chip instead of normal text infoautoWidth?: boolean; autoWidthwidthSize?: booleanstring; // customised width either widthSize?: string;in percentage or fixed width [key: string]: any; //any other metadata } |
...
Filters Config and Component Design <WIP>
This component and interface it to make a generic filter which will serve all for all the reportTypes.
This will also handle nested filters implementation or heirarchical filters implementation.
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.. */ |
🧐 Proposed Design
Dashlet Main Component Proposed Structure
...