Custom Chart Tutorial Part Three
Welcome to part three of the custom chart tutorial. In this part, we explore how to integrate third-party libraries in custom charts, how to create a chart container, and how to use a library’s API to render a standard chart.
Identify Libraries
Zoomdata makes use of third-party libraries in the out-of-the-box charts provided with the product. Typically, these libraries fall into two categories: charting libraries and utility libraries. The charting libraries assist with the rendering of standard chart types like bar, line, pie, and scatter plot charts. The utility libraries assist with shaping datasets, formatting values, or providing useful JavaScript methods.
In custom charts, you can also use libraries to assist with rendering and formatting requirements. Since we are creating a chart from scratch, let’s pick a charting library like ECharts to assist with the rendering of this custom chart.
Add Libraries
The first step is to add ECharts as a dependency of the custom chart. You can do this by installing ECharts using npm.
npm install echarts --save
Check the contents of the file package.json
to ensure that echarts is part of the list of dependencies.
npm provides an easy-to-use software registry that can leveraged to install packages for your custom charts.
Test Libraries
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 in part one of this tutorial.
Open the src/index.js file in your preferred text editor or IDE. Let’s add the following line towards the top of the file:
/* global controller */
import echarts from 'echarts';
import styles from './index.css';
console.log(echarts ? 'The library is defined.' : 'The library is undefined');const groupAccessor = controller.dataAccessors['Group By'];const metricAccessor = controller.dataAccessors.Size;//...
Now check the contents of the browser console when adding the chart to a dashboard. The following image shows what the console should look like:
Once you confirm that the global variable is defined, you can remove the console.log statement.
Create a Chart Container
As part of its charting API, Zoomdata provides a <div> element that can hold the rendered contents of your custom chart. While it is perfectly fine to use that element as the chart container, we recommend that you create a separate container inside of that element to gain full control over its styles.
Add the following lines of code to the top of the src/index.js file:
/* global controller */
import echarts from 'echarts';
import styles from './index.css';
// create chart containerconst chartContainer = document.createElement('div');chartContainer.style.width = '100%';chartContainer.style.height = '100%';chartContainer.classList.add(styles.chartContainer);controller.element.appendChild(chartContainer);
const groupAccessor = controller.dataAccessors['Group By'];
const metricAccessor = controller.dataAccessors.Size;
//...
Notice the line: controller.element.appendChild(chartContainer);
. controller.element is the <div> Zoomdata provides with its API.
Let’s try modifying the background color of the newly added container. Open the src/index.css component file, clear its contents, and add the following lines to the top of the file:
.chartContainer {
background-color: #323232;
}
Refresh the dashboard with the custom chart, and you should see a dark gray background. The image below shows what your chart should look like:
If you were able to see the dark gray background, the chart container is working.
Change the background color to background-color: #ffffff;
to set it back to white.
Render the Chart
In part two of this tutorial, we defined a group-by variable and a metric variable to generate a grouped dataset with a single metric value. This data structure works well with bar and pie charts. Let’s use the ECharts API and its chart configuration option to create a pie chart with our dataset.
In the src/index.js file, let’s instantiate a variable to hold an instance of the pie chart. Additionally, let’s instantiate a second variable to hold the chart configuration option. The chart’s instance is created by using the echarts.init method and passing in a chart container. Let’s add it right below our data accessors:
//...
const groupAccessor = controller.dataAccessors['Group By'];
const metricAccessor = controller.dataAccessors.Size;
const chart = echarts.init(chartContainer);const option = { series: [ { name: metricAccessor.getLabel(), type: 'pie', }, ],};//...
Notice how we used the metric accessor to dynamically capture the name of the series.
Next, let’s specify the ‘pie’ series’ data and call the chart’s setOption
method inside of the controller.update function:
//...
controller.update = data => {
// Called when new data arrives
option.series[0].data = reshapeData(data); chart.setOption(option);};
//...
We have pie chart rendering! Your chart should look similar to this:
Hmm, there is a problem. The pie chart is slightly cut-off at the bottom. If we resize the window, the chart does not resize accordingly.
Handle Resizing
Zoomdata provides an API to notify the charts of a resize operation. Let’s add the controller.resize function at the end of the src/index.js file to handle resizing.
//...
controller.resize = (newWidth, newHeight) => {
// Called when the widget is resized
chart.resize();
};
Here we are calling the resize method of the EChart’s chart instance to tell the chart to fit the new dimensions of the chart container.
Now that we are handling chart resizing, our chart should look like the following image:
Feel free to play around and add some filters or change the chart’s default configuration. You should see the data re-render as you modify the query with the filter or time bar control.
Looking Good!
We now have a chart that we can reuse with any data source. Head over to Part Four to learn about adding and removing chart controls and integrating with Zoomdata tooltips and the radial menu.