Custom Chart Tutorial Part Two
Welcome to part two of the custom chart tutorial. In this part, we are going to learn how to work with query variables to instruct Zoomdata how to query the data to power our charts.
Modify Query Variables
Zoomdataâs front end client communicates with the backend data repositories by leveraging a WebSocket API designed to translate query messages into the appropriate native query language. To generate query messages, a chart must define the data variables that specify the query type and required fields.
Letâs build off of the chart created in part one of the tutorial and find the list of query variables created with the default (âSingle-Groupâ) chart template.
Enter the following command in the terminal window from the chartâs root directory window and hit ENTER.
zd-chart edit
Use arrow keys to follow the prompts and press ENTER to select the following options:
- Variables
- List variables
The output of the terminal window should look like the following image:
Notice the group and metric variable listed in the table. A group variable indicates that the chart generates a request for âgrouped/aggregatedâ data in the query. In this case, the chart defines a single group by field. A metric variable indicates that the chart will perform an aggregation function on a numeric field as part of the âgrouped/aggregatedâ data query. In this chart, we have a single metric specified. The chartâs default configuration defines the actual group-by and metric fields at the source level. We visit the chartâs configuration a little later in this tutorial.
Answer âYâ to the prompt, âWould you like to make additional edits?â and make the following selections:
- Variables
- Edit a variable
- Metric |metric|
For the remaining prompts, enter the following information:
- What would you like to edit: Name
- Please enter a new name for the variable: Size
Enter âNâ when prompted if you would like to make additional edits.
If you are still running âwatch modeâ in the terminal window from part one of this tutorial, the variable change will be automatically pushed to the server.
If necessary, you can run zd-chart push
to ensure the change is pushed to the server.
At this point, we have defined a group query variable named âGroup Byâ and a metric query variable named âSizeâ in the chart.
Set the Chartâs Default Configuration
Letâs now define what the query variables should be set to when adding the chart to a dashboard. Navigate to the âSourcesâ page in Zoomdata by clicking on the gear icon on the navigation bar and selecting Sources.
Click on the data source selected during the chart preview step in part one and continue with the following steps:
- Click on the âChartsâ tab
- Click on the âCustomâ tab
- Select: âMy First Custom Chartâ
On the right-hand side of the page, you see the inputs set for the different variables defined in the chart. Some variables types like group expose multiple inputs:
- Group By
- Group By Limit
- Group By Sort
- Sorting direction
These indicate the field used to group results, the total number of group values, the sorting field used with the limit parameter and the sort direction. Make a selection for a group-by field, set the limit to 10, and select the same metric for the group-by sort and size. The default settings should look similar to the following image:
Data Preview
It is time to edit the chart code and preview the data retrieved as a result of the defined query variables.
In a terminal window, change directories to the local directory of âMy First Custom Chartâ and enter zd-chart watch
to
set the CLI to Watch mode.
In another terminal window, run the command npm start
.
For a refresher on this topic, visit the âEdit the Chartâs Codeâ section part one of this tutorial.
Open the src/index.js file in your preferred text editor or IDE. Letâs modify the code of the controller.update function to output the data received into the console.
// ...
controller.update = data => {
// Called when new data arrives
console.log(data);};
// ...
Letâs also remove the code that creates the chart container and âAxis Labels / Pickersâ on the chart. We will introduce these concepts later in the tutorial.
// Remove the code below
const chartContainer = document.createElement('div');
chartContainer.classList.add(styles.chartContainer);
controller.element.appendChild(chartContainer);
controller.createAxisLabel({
picks: 'Group By',
orientation: 'horizontal',
position: 'bottom',
popoverTitle: 'Group',
});
controller.createAxisLabel({
picks: 'Metric',
orientation: 'horizontal',
position: 'bottom',
});
Upon saving the changes of src/index.js, the CLI updates the serverâs copy with latest changes. Letâs preview the chartâs data by adding the chart to a new dashboard. Since we are outputting the data to the browserâs console, we need to open the browserâs developer tools to get to console. See instructions for Google Chrome and Mozilla Firefox browsers. The following image shows what the results might look like:
Notice the JSON array with multiple objects in the result. Each object contains a group property with an array of strings (one per group by field) and current object with a nested count property (# of records) and a metrics property (an object with the metrics requested). Each metric objects contains an aggregation function property, like sum and its resulting value.
Some of you may be wondering, âHow do we make flexible charts, which can be used across data sources if the objects have hardcoded property names?â Continue reading to find out.
Data Accessors
Now that we have to capture the results of the chartâs query, we need to find a way to reshape the result set in a format that can be consumed by a charting library. We also want tTo ensure our charts remain flexible and applicable to multiple data sources, we do not want to hard-code any object properties in the code. Zoomdata data accessors, exposed via the chart API, can be used to avoid hard-coding property names. Zoomdata has a concept known as Data Accessors, exposed via the chart API, that comes in handy when need to avoid hard-coding property names.
Letâs start out by instantiating some variables to hold the data accessors. We use one per query variable.
const groupAccessor = controller.dataAccessors['Group By']; // Group By is the name given to variable of type group.
const metricAccessor = controller.dataAccessors.Size; // Size is the name we gave to the variable of type metric.
The API is simple: controller.dataAccessors[<variable-name>]
.
Each data accessor holds the information about the field defined for the variable and provides a raw method that can be used to extract data values given a datum object.
A datum refers to the objects inside the returned data array.
Assume we want to reshape our data array so that the contained JSON object looks like:
{
name: STRING
value: NUMBER
}
With this information, letâs create a reshapeData function that takes the original Zoomdata data array and returns a new array with the desired object structure.
function reshapeData(data) {
return data.map(d => ({
name: groupAccessor.raw(d),
value: metricAccessor.raw(d),
}));
}
Finally, letâs use the new reshapeData function to output the reshaped results into the console. Up to this point, the chartâs code should look like:
/* global controller */
import styles from './index.css';
const groupAccessor = controller.dataAccessors['Group By'];
const metricAccessor = controller.dataAccessors.Size;
controller.update = function(data) {
// Called when new data arrives
console.log(reshapeData(data));
};
function reshapeData(data) {
return data.map(d => ({
name: groupAccessor.raw(d),
value: metricAccessor.raw(d),
}));
}
Refresh the dashboard with a copy of the chart and check the contents of the browser console. The array object should look just like we specified, with a name and value property.
Well Done!
We completed part two of the custom chart tutorial. We introduced the concepts of query variables and data accessors, and we learned how to reshape data to make the chart flexible and dynamic.
Now continue to Part Three where you learn how to integrate third-party libraries into your custom charts.