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.

Add 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. A chart must define data variables that specify the query type and the fields to request to generate these query messages.

Let’s build off of the chart created in part one of the tutorial and find the list of query variables created with Blank template.

Type the following command into the terminal window and hit ENTER.

zd-chart edit "My First Custom Chart"

Follow the prompts and select the following options:

  1. Variables
  2. List variables

The output of the terminal window should look like the following image:

List of Variables

Notice the group 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. The chart’s default configuration defines the actual group-by field 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:

  1. Variables
  2. Add a new variable
  3. metric

For the remaining prompts, enter the following information:

  1. Variable name: Size
  2. Description: Leave it empty
  3. Will this variable drive color?: N

Enter “N” when prompted if you would like to make additional edits.

At this point, we have defined a group query variable and a metric query variable 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 creation step and continue with the following steps:

  1. Click on the “Charts” tab
  2. Click on the “Custom” tab
  3. 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:

  1. Group By
  2. Group By Limit
  3. Group by Sort
  4. 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:

Default Chart Settings

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. For a refresher on this topic, visit the “Edit the Chart’s Code” section part one of this tutorial.

Open the Visualization.js file in your preferred text editor or IDE. Let’s modify the code of the controller.update to output the data received into the console.

// ...
controller.update = function(data) {
    // Called when new data arrives
    console.log(data);
};
// ...

Upon saving the changes Visualization.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:

Data Preview in Console

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 to make sure we do not hard-code object properties in our code to ensure our charts remain flexible and applicable to multiple data sources. 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.

var groupAccessor = controller.dataAccessors['Group By']; // Group By is the name given to variable of type group.
var 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(function(d) {
    return {
      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 */

var groupAccessor = controller.dataAccessors['Group By'];
var metricAccessor = controller.dataAccessors.Size;

controller.update = function(data) {
  // Called when new data arrives
  console.log(reshapeData(data));
};

function reshapeData(data) {
  return data.map(function(d) {
    return {
      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’s flexible and dynamic.

Now continue to Part Three where you learn how to integrate 3rd party libraries into your custom charts.