Dashboards
Democratize the data in your application and deliver extended reporting and analytics capabilities to all your users with Dashboards you can build and deploy in a snap.
On this page:
- About the Dashboards Widget
- Setting Up Dashboards
- Props
- Functions
- Edit Mode
- Saving a Dashboard
- Examples
About the Dashboards Widget
A fully embeddable and editable Dashboard component. This is a flexible frontend widget that can be implemented and accessed within an existing application or software interface.
Dashboards contain a series of tiles, each housing a query and a corresponding visualization. Each tile is created using a collection of metadata stored in a JavaScript object. The objects with tile metadata are referred to as Tile Objects throughout this document. The Dashboard component takes an array of Tile Objects as a prop and provides an onChange callback when changes are made to the tile state. If the user wishes to save the Dashboard, the tile state can be stored in a database.
Throughout this document, the words "Dashboard" and "widget" are used interchangeably. All widget components are open source, so Dashboards are highly customizable in terms of both function and design.
Setting Up Dashboards
Controlled Component
This widget is a controlled component. It accepts a "tiles" prop and an "onChange" callback that are designed to work with each other using your own state. The Integrator is in full control of the state of Dashboards within their application, making it easy to fetch, manage, and store the current Dashboard Tile state.
The Dashboard component takes in an array of tile objects. To start, this array can be empty as the Dashboard can be dynamically created in Edit Mode. More details regarding Edit Mode can be found later in this doc.
import React, { Component } from 'react'
import { Dashboard } from 'react-autoql';
import 'react-autoql/dist/autoql.esm.css'
export default class App extends Component {
state = {
tiles: []
}
...
onTileChange = tiles => {
this.setState({ tiles })
}
render = () => {
return (
<Dashboard
authentication={{
token: "yourToken"
apiKey: "your-api-key"
domain: "https://yourdomain.com"
}}
ref={r => (this.dashboardRef = r)}
tiles={this.tiles}
onChange={this.onTileChange}
isEditing={this.state.isEditing}
/>
)
}
}
Props
Prop Name | Data Type | Default Value |
---|---|---|
tiles (Required) | Array of Tile Objects | - |
onChange | Function | () => {} |
authentication | Object | {} |
isEditing | Boolean | false |
startEditingCallback | Function | () => {} |
onErrorCallback | Function | () => {} |
onSuccessCallback | Function | () => {} |
executeOnMount | Boolean | true |
executeOnStopEditing | Boolean | true |
notExecutedText | String | 'Hit "Execute" to run this dashboard' |
enableDynamicCharting | Boolean | true |
autoChartAggregations | Boolean | true |
autoQLConfig | Object | {} |
dataFormatting | Object | {} |
themeConfig | Object | {} |
tiles
: Required prop to manage the state of the Dashboard. Used along with onChange below to control the state of the Dashboard. More details regarding the structure of this prop can be found in the Tile section below.
Tiles can be created through the widget using Edit Mode, or you can pass it in manually. The minimum required structure for a Dashboard Tile is as follows:
{
key: '0', // unique ID for each tile
w: 3, // width of the tile. A value of 1 represents 1/12 of the container width. 12 is the maximum (full width)
h: 2, // height of the tile. A value of 1 represents 60px
x: 0, // x position of the tile (in same increments as w)
y: 0, // y position of the tile (in same increments as h)
query: 'total profit per product per month', // query to be used for the tile
title: 'Profit by Product', // title to display in the tile outide of Edit Mode. If this isn't supplied, the query text will be used
}
Below are the additional options for structuring a Dashboard Tile:
{
...requiredOptions,
displayType: 'heatmap', // if this is omitted, "table" will be the default display type
splitView: true, // allows user to have 2 visualizations in one tile
secondDisplayType: 'pivot-table', // the display type of the second visualization if "splitView" is true. This also defaults to "table" when omitted
secondDisplayPercentage: 25 // the percentage of the tile that the second visualization will take up. If omitted, the default is 50%
}
onChange
: Callback used to update your Tile state in your own Dashboard React component. See example at the end of this doc for how to control the state of the Dashboard.
isEditing
: Toggles Edit Mode for the Dashboard component. If Edit Mode is active, the user can add, resize, reorder, or delete a tile. They can also change the natural language query, add a descriptive title, and adjust the visualization type.
startEditingCallback
: Called when the dashboard needs to enter edit mode from a user action (eg. link inside "Start building a New Dashboard"). The isEditing prop should be set to "true" in this callback.
onErrorCallback
: Called when an error occurs on the dashboard.
onSuccessCallback
: Called when an action has been successfully completed on the dashboard.
executeOnMount
: If this is set to true, the Dashboard will run as soon as the component is mounted. If it is false, the Dashboard will not run until the "executeDashboard" function is called.
executeOnStopEditing
: If this is set to true, the widget will detect when Edit Mode is no longer activated, and will re-execute the Dashboard to reflect all changes.
notExecutedText
: The text contained inside each Tile when a Dashboard has not yet been executed.
enableDynamicCharting
: Enables the ability to dynamically change the categories for the x and y axes in a chart by clicking on the axis label. If enableDynamicCharting is true and there are other category options available for that axis, an arrow will appear beside the axis label.
autoChartAggregations
: If autoChartAggregations is true, the default display type for aggregation queries will be a chart instead of a table.
authentication Prop
Key | Value Type | Description |
---|---|---|
token | String | Your valid JWT encrypted with your user ID and customer ID. For more information on how to create this token, please visit the "Security" section of our docs. |
apiKey | String | Your API key. For more information on how to obtain this, please visit the "Security" section of our docs. |
domain | String | For more information on how to obtain this, please visit the "Security" section of our docs. |
autoQLConfig Prop
Key | Value Type | Default |
---|---|---|
enableAutocomplete | Boolean | true |
enableQueryValidation | Boolean | true |
enableQuerySuggestions | Boolean | true |
enableDrilldowns | Boolean | true |
debug | Boolean | false |
enableAutocomplete
: Automatically populates similar query suggestions as users enter a query, so they get results more quickly and easily. If enabled, suggested queries will begin to appear above the Query Input bar as the user types.
enableQueryValidation
: Catches and verifies references to unique data, so users always receive the data they need. If enabled, the natural language query entered by a user will first go through a validate endpoint. If the query requires validation (ex. the input contains reference to a unique data label), suggestions for that label will be returned in a subsequent message, allowing the user to verify their input before executing their query.
For example: If you query, 'How much money does Nikki owe me?', validation may detect that there is no 'Nikki' label, but there are labels called 'Nicki', and 'Nik' in your database. The message will then let you select the appropriate label and run the corresponding query.
If this value is false, the query will bypass the validate endpoint and be sent straight to the query endpoint.
enableQuerySuggestions
: Enables option for user to clarify meaning in cases where their original query lacked context or could be interpreted in multiple separate ways. If enabled, in cases where the query input was ambiguous, a list of suggested queries will be returned for the user to choose from, leading to more efficient and accurate responses. If this is false, a general error message will appear in its place.
enableDrilldowns
: When a table or chart element is clicked by a user, a new query will run automatically, allowing the user to "drilldown" into the data to obtain a detailed breakdown of the figure returned by entry. If this is false, nothing will happen when a table or chart element is clicked.
debug
: If this value is true, the user can copy the full query language (QL) statement (ex. SQL statement) that was dynamically generated from their natural language query input by clicking "Copy generated query to clipboard".
dataFormatting Prop
Key | Value Type | Default |
---|---|---|
currencyCode | String | 'USD' |
languageCode | String | 'en-US' |
currencyDecimals | Number | 2 |
quantityDecimals | Number | 1 |
comparisonDisplay | String: 'PERCENT' || 'RATIO' | 'PERCENT' |
monthYearFormat | String | 'MMM YYYY' |
dayMonthYearFormat | String | 'll' |
currencyCode
: If your data is not in USD, you can specify a different currency code here. All visualizations (tables and charts) will show the default currency formatting for the specified code.
Currency
Setting a currency code does not perform a currency conversion. It only displays the number in the desired format.
languageCode
: If the currency code from your country requires letters not contained in the English alphabet in order to show symbols correctly, you can pass in a locale here. For more details on how to do this, click here.
currencyDecimals
: Number of digits to display after a decimal point for currencies.
quantityDecimals
: Number of digits to display after a decimal point for quantity values.
comparisonDisplay
: Format for displaying comparison types (ex. changes in data). "Percent" will multiply the number by 100 and display a "%" symbol. "Ratio" will display the original number as-is.
monthYearFormat
: The format to display the representation of a whole month. (ex. March 2020). AutoQL uses dayjs for date formatting, however most Moment.js formatting will work here as well. Please see the dayjs docs for formatting options.
dayMonthYearFormat
: The format to display the representation of a single day. (ie. March 18, 2020). AutoQL uses dayjs for date formatting, however most Moment.js formatting will work here as well. Please see the dayjs docs for formatting options.
themeConfig Prop
Key | Value Type | Default |
---|---|---|
theme | String: ‘light’ || ‘dark’ | ‘light’ |
dashboardBackground | String | '#fafafa' |
accentColor | String | light theme: '#28a8e0', dark theme: '#525252' |
fontFamily | String | 'sans-serif' |
chartColors | Array | ['#26A7E9', '#A5CD39', '#DD6A6A', '#FFA700', '#00C1B2'] |
theme
: Color theme for Dashboards. Currently there are two options: light theme and dark theme. In addition to changing the overall theme, you can also change the accent color using the accentColor prop.
dashboardBackground
: Background color used in Dashboards. This will only affect the space behind the tiles. If none is provided, the default is #FAFAFA.
accentColor
: Primary accent color used in Dashboards. This is the color of the header, speech-to-text button, and the messages displayed in the interface (both natural language query inputs from users and the associated responses that are generated and returned to the user). The visualization (table and chart) colors will not be affected here.
fontFamily
: Customize the font family to the provided font wherever possible. Accepts any CSS font family that is available, and if none is provided, will default to Sans-Serif.
chartColors
: Array of color options for the chart visualization themes, starting with the most primary. You can pass any valid CSS color format in here, however it is recommended that the color is opaque (ex. "#26A7E9", "rgb(111, 227, 142)", or "red"). Charts will always apply the colors in order from first to last. If the visualization requires more colors than provided, all colors will be used and then repeated in order.
Functions
ref.executeDashboard()
: A function to run the queries contained in a Dashboard. Use this function when you want to control exactly when a Dashboard is executed and re-executed.
ref.addTile()
: A function to add a new empty Tile to an existing Dashboard.
ref.undo()
: A function to undo the most recent change to a Dashboard. The following actions can be undone:
Actions that can be undone |
---|
Add Tile |
Delete Tile |
Move Tile |
Resize Tile |
Change Query Text Input |
Change Descriptive Title |
Edit Mode
Dashboards can be created and edited using the isEditing
prop. This enables the user to add tiles, drag and drop tiles, resize them, delete them, and edit the content inside of them. Using the suite of editing functions we've provided, you can also create your own edit toolbar to allow the users of your app to make and edit their own Dashboards.
To add a Dashboard Tile, call the "addTile" function from the Dashboard Ref (or bind it to a button). This will make a new Tile and place it at the bottom of the Dashboard with a default width and height of 6 and 5, respectively.
import React, { Component, Fragment } from 'react'
import { Dashboard } from 'react-autoql';
import 'react-autoql/dist/autoql.esm.css'
export default class App extends Component {
state = {
tiles: []
}
...
addTile = () => {
if (this.state.isEditingDashboard ? this.dashboardRef) {
this.dashboardRef.addTile()
}
}
render = () => {
return (
<Fragment>
<button onClick={this.addTile}>
Add Tile
</button>
<Dashboard
authentication={{
token: "yourToken"
apiKey: "your-api-key"
domain: "https://yourdomain.com"
}}
ref={r => (this.dashboardRef = r)}
tiles={this.state.tiles}
isEditing={true}
onChange={this.onTileChange}
/>
</Fragment>
)
}
}
Here's what a single Dashboard Tile looks like in Edit Mode:
Validation and Suggestions
Validation and Suggestions are only enabled in Edit Mode as the query is considered immutable once the Dashboard is live. Outside of Edit Mode, the Tile will display a general error message if the query that was entered and saved is failing to return a response from the database.
Saving a Dashboard
If you want to persist the Dashboard, simply store the Tile array in your own database. See the example below for how to manage the Dashboard Tile state.
You probably don't need the response!
When saving your Dashboard Tiles, you likely don't need to save the query response since Dashboards can be executed ad hoc. Simply exclude the queryResponse from the Tile objects in this case.
import React, { Component, Fragment } from 'react'
import { Dashboard } from 'react-autoql';
import yourSaveEndpoint from './yourService.js'
import 'react-autoql/dist/autoql.esm.css'
export default class App extends Component {
state = {
isEditingDashboard: false,
tiles: [],
}
onEditClick = () => {
this.setState({
isEditingDashboard: !this.state.isEditingDashboard
})
}
onTileChange = tiles => {
this.setState({ tiles })
}
saveDashboard = () => {
// Filter out query response and second query response if split view
const filteredTiles = this.state.tiles.map(tile => {
return {
...tile,
queryResponse: undefined,
secondQueryResponse: undefined
}
})
// Save tiles somewhere
yourSaveEndpoint(filteredTiles);
}
render = () => {
return (
<Fragment>
<button onClick={this.onEditClick}>
Toggle Edit
</button>
<button onClick={this.saveDashboard}>
Save Dashboard
</button>
<Dashboard
authentication={{
token: "yourToken"
apiKey: "your-api-key"
domain: "https://yourdomain.com"
}}
ref={r => (this.dashboardRef = r)}
tiles={this.state.tiles}
onChange={this.onTileChange}
isEditing={this.state.isEditingDashboard}
/>
</Fragment>
)
}
}
Examples
import React, { Component } from 'react'
import { Dashboard } from 'react-autoql';
import 'react-autoql/dist/autoql.esm.css'
export default class App extends Component {
state = {
tiles: [
{
key: '0',
w: 3,
h: 2,
x: 0,
y: 0,
query: 'total profit this month',
title: 'Profit - Current Month'
},
{
key: '1',
w: 3,
h: 2,
x: 3,
y: 0,
query: 'total profit last month',
title: 'Profit - Previous Month'
},
]
}
render = () => {
return (
<Dashboard
authentication={{
token: "yourToken"
apiKey: "your-api-key"
domain: "https://yourdomain.com"
}}
ref={r => (this.dashboardRef = r)}
tiles={this.tiles}
onChange={tiles => this.setState({ tiles })}
/>
)
}
}
Updated almost 3 years ago