Integration with any charting library

This tutorial explains how to connect WebDataRocks to a third-party charting library, such as Chart.js, ApexCharts, ECharts, or D3.js.

WebDataRocks can be integrated with charting libraries using the getData() API call, which returns data displayed on the grid. Then, you need to preprocess the data to a format required by your charting library and pass it to the chart.

In this tutorial, we will integrate with Chart.js, but the steps are similar for other libraries.

Note that if you are integrating with amCharts, Highcharts, FusionCharts, or Google Charts, use our ready-to-use connectors that will automatically process the data. Check out the list of available tutorials.

Step 1. Add WebDataRocks to your project

Step 1.1. Complete the integration guide. Your code of the component with WebDatarocks should look similar to the following:

import * as WebDataRocksReact from "@webdatarocks/react-webdatarocks";

function App() {
return (
<div>
<WebDataRocksReact.Pivot
toolbar={true}
/>
</div>
);
}

export default App;

Step 1.2. Create a report for WebDataRocks — connect to the data source and define which fields should be displayed in rows, columns, and measures:

function App() {
const report = {
dataSource: {
filename: "https://cdn.webdatarocks.com/data/data.csv",
},
slice: {
rows: [
{
uniqueName: "Country",
},
],
columns: [
{
uniqueName: "Measures",
},
],
measures: [
{
uniqueName: "Price",
aggregation: "sum",
},
],
},
};

return (
<div>
<WebDataRocksReact.Pivot
toolbar={true}
report={report}
/>
</div>
);
}

The fields you’ve specified in the report will be shown on the chart.

Step 2. Get a reference to the WebDataRocks instance

Some of WebDataRocks methods and events are needed to create a chart. Using a reference to the WebDataRocks instance, we can access WebDataRocks API.

Get the reference with the useRef hook:

React + ES6

// ...
import { useRef } from "react";

function App() {
const pivotRef = useRef(null);

// ...

return (
<div>
<WebDataRocksReact.Pivot
ref={pivotRef}
toolbar={true}
report={report}
/>
</div>
);
}

export default App;

React + TypeScript

// ...
import { RefObject, useRef} from "react";

function App() {
const pivotRef: RefObject<WebDataRocksReact.Pivot> = useRef<WebDataRocksReact.Pivot>(null);

// ...

return (
<div>
<WebDataRocksReact.Pivot
ref={pivotRef}
toolbar={true}
report={report}
/>
</div>
);
}

export default App;

Now it’s possible to interact with the component through pivotRef.current.webdatarocks.

Step 3. Add a charting library

Note that this tutorial integrates WebDataRocks with Chart.js. The following steps may vary depending on your charting library.

Step 3.1. Install the npm package with your charting library. For example:

npm i react-chartjs-2 chart.js

Step 3.2. Import the charting library into your component:

// ...

import { PolarArea } from "react-chartjs-2";
import {
Chart as ChartJS,
RadialLinearScale,
ArcElement,
Tooltip,
Legend,
} from "chart.js";

ChartJS.register(RadialLinearScale, ArcElement, Tooltip, Legend);

Step 3.3. Add a container for your chart where your React element is returned:

<PolarArea/>

Step 3.4. Create a state variable to store chart data (e.g., chartData):

React + ES6

import { useRef, useState } from "react";

const [chartData, setChartData] = useState({
labels: [],
datasets: [
{
data: [],
},
],
});

We will pass the data from the component to chartData in step 4.3.

React + TypeScript

import { useRef, useState } from "react";

const [chartData, setChartData] = useState({
labels: [],
datasets: [
{
data: [],
backgroundColor: [
"rgba(255, 99, 132, 0.5)",
"rgba(54, 162, 235, 0.5)",
"rgba(255, 206, 86, 0.5)",
"rgba(75, 192, 192, 0.5)",
"rgba(153, 102, 255, 0.5)",
"rgba(255, 159, 64, 0.5)",
],
},
],
});

We will pass the data from the component to chartData in step 4.3.

Step 4. Integrate WebDataRocks with the charting library

In this step, we will use the getData() API call. This method was added especially for integration with third-part charting libraries; using it, you can request data from WebDataRocks and pass it to a charting library.
Step 4.1. If we call the getData() method before WebDataRocks is fully loaded, it will return an empty result. To know when WebDataRocks is ready to provide data for the chart, handle the reportcomplete event:

React + ES6

const onReportComplete = () => {
// Unsubscribing from reportcomplete
// We need it only to track the initialization of WebDataRocks
pivotRef.current.webdatarocks.off("reportComplete");
createChart();
};

return (
<div>
<WebDataRocksReact.Pivot
ref={pivotRef}
toolbar={true}
report={report}
reportcomplete={onReportComplete}
/>
<PolarArea data={chartData} />
</div>
);

React + TypeScript

const onReportComplete = () => {
// Unsubscribing from reportcomplete
// We need it only to track the initialization of WebDataRocks
pivotRef.current?.webdatarocks.off("reportComplete");
createChart();
};

return (
<div>
<WebDataRocksReact.Pivot
ref={pivotRef}
toolbar={true}
report={report}
reportcomplete={onReportComplete}
/>
<PolarArea data={chartData} />
</div>
);

Step 4.2. Implement the createChart() function using the getData() API call:

React + ES6

const createChart = () => {
if (pivotRef.current) {
pivotRef.current.webdatarocks.getData(
{},
// Function called when data for the chart is ready
drawChart,
// Function called on report changes (filtering, sorting, etc.)
drawChart
);
};
};

React + TypeScript

const createChart = () => {
if (pivotRef.current) {
pivotRef.current?.webdatarocks.getData(
{},
// Function called when data for the chart is ready
drawChart,
// Function called on report changes (filtering, sorting, etc.)
drawChart
);
};
};

Step 4.3. Implement the drawChart() function specified in the previous step. This function will initialize the chart, set all the configurations specific to this chart type, and fill it with the data provided by WebDataRocks:

React + ES6

const drawChart = (rawData) => {
const { labels, values } = prepareData(rawData); // This function will be implemented in step 4

// Configuring the chart and filling it with data
setChartData({
labels: labels,
datasets: [
{
data: values,
backgroundColor: [
"rgba(255, 99, 132, 0.5)",
"rgba(54, 162, 235, 0.5)",
"rgba(255, 206, 86, 0.5)",
"rgba(75, 192, 192, 0.5)",
"rgba(153, 102, 255, 0.5)",
"rgba(255, 159, 64, 0.5)",
],
},
],
});
};

React + TypeScript

const drawChart = (rawData: any) => {
const { labels, values } = prepareData(rawData); // This function will be implemented in step 4

// Configuring the chart and filling it with data
setChartData({
labels: labels,
datasets: [
{
data: values,
backgroundColor: [
"rgba(255, 99, 132, 0.5)",
"rgba(54, 162, 235, 0.5)",
"rgba(255, 206, 86, 0.5)",
"rgba(75, 192, 192, 0.5)",
"rgba(153, 102, 255, 0.5)",
"rgba(255, 159, 64, 0.5)",
],
},
],
});
};

Step 5. Prepare the data

getData() API call returns an object (e.g., rawData) that contains the data from the grid and its metadata. The metadata includes a number of fields in rows and columns in the slice, an array of format objects, etc. Read more about the getData() response.

Here is an example of the rawData.data array returned by getData(). This data is based on the slice that was defined in the step 1.2:

data: [
{ v0: 6221870 }, // Grand total
{ r0: "Australia", v0: 1372281 },
{ r0: "France", v0: 1117794 },
{ r0: "Germany", v0: 1070453 },
{ r0: "Canada", v0: 1034112 },
{ r0: "United States", v0: 847331 },
{ r0: "United Kingdom", v0: 779899 }
]

This raw data now must be transformed to match the data format required by your charting library, in our case — Chart.js. Let’s create a function that will preprocess the data, for example, prepareData().

We are passing data to the data.labels and data.datasets properties, where data.labels contains field members and data.datasets contains values. Read more in the Chart.js documentation.

The prepareData() function for Chart.js will look similar to the following:

React + ES6

const prepareData = (rawData) => {
const labels = rawData.data.filter((rec) => rec.r0 && rec.v0).map((rec) => rec.r0);
const values = rawData.data.filter((rec) => rec.r0 && rec.v0).map((rec) => rec.v0);

return { labels, values };
};

React + TypeScript

const prepareData = (rawData: any) => {
const labels = rawData.data.filter((rec: any) => rec.r0 && rec.v0).map((rec: any) => rec.r0);
const values = rawData.data.filter((rec: any) => rec.r0 && rec.v0).map((rec: any) => rec.v0);

return { labels, values };
};

prepareData() must return an object with the data that can be used by your charting library. The example shows the returned object for Chart.js:

{ 
labels: ["Australia", "France", "Germany", "Canada", "United States", "United Kingdom"],
values: [1372281, 1117794, 1070453, 1034112, 847331, 779899]
}

Step 6. Pass the data to the chart

When the data is ready to be used by your charting library, pass the data to the chart container that was created in step 3.3:

<PolarArea data={chartData} />

Step 7. Run the project

Run your project with the following command:

npm run dev

Open http://localhost:5173/ in the browser to see how the pivot table looks in combination with Chart.js.

Try filtering the data, changing measures, and adjusting aggregation functions — the chart will be updated at once.

Check out the full code

After completing this tutorial, the full code of the integration should look as follows:

React + ES6

import React, { useRef, useState } from "react";
import * as WebDataRocksReact from "@webdatarocks/react-webdatarocks";
import { PolarArea } from "react-chartjs-2";
import {
Chart as ChartJS,
RadialLinearScale,
ArcElement,
Tooltip,
Legend,
} from "chart.js";

ChartJS.register(RadialLinearScale, ArcElement, Tooltip, Legend);

function App() {
const pivotRef = useRef(null);
const [chartData, setChartData] = useState({
labels: [],
datasets: [
{
data: [],
},
],
});

const report = {
dataSource: {
filename: "https://cdn.webdatarocks.com/data/data.csv",
},
slice: {
rows: [
{
uniqueName: "Country",
},
],
columns: [
{
uniqueName: "Measures",
},
],
measures: [
{
uniqueName: "Price",
aggregation: "sum",
},
],
},
};

const onReportComplete = () => {
pivotRef.current.webdatarocks.off("reportcomplete");
createChart();
};

const createChart = () => {
if (pivotRef.current) {
pivotRef.current.webdatarocks.getData(
{},
drawChart,
drawChart
);
};
};

const drawChart = (rawData) => {
const { labels, values } = prepareData(rawData);
setChartData({
labels: labels,
datasets: [
{
data: values,
backgroundColor: [
"rgba(255, 99, 132, 0.5)",
"rgba(54, 162, 235, 0.5)",
"rgba(255, 206, 86, 0.5)",
"rgba(75, 192, 192, 0.5)",
"rgba(153, 102, 255, 0.5)",
"rgba(255, 159, 64, 0.5)",
],
},
],
});
};

const prepareData = (rawData) => {
const labels = rawData.data.filter((rec) => rec.r0 && rec.v0).map((rec) => rec.r0);
const values = rawData.data.filter((rec) => rec.r0 && rec.v0).map((rec) => rec.v0);

return { labels, values };
};

return (
<div>
<WebDataRocksReact.Pivot
ref={pivotRef}
toolbar={true}
report={report}
reportcomplete={onReportComplete}
/>
<PolarArea data={chartData} />
</div>
);
}

export default App;

React + TypeScript

import { RefObject, useRef, useState } from "react";
import * as WebDataRocksReact from "@webdatarocks/react-webdatarocks";
import { PolarArea } from "react-chartjs-2";
import {
Chart as ChartJS,
RadialLinearScale,
ArcElement,
Tooltip,
Legend,
} from "chart.js";

ChartJS.register(RadialLinearScale, ArcElement, Tooltip, Legend);

function App() {
const pivotRef: RefObject<WebDataRocksReact.Pivot> = useRef<WebDataRocksReact.Pivot>(null);
const [chartData, setChartData] = useState({
labels: [],
datasets: [
{
data: [],
backgroundColor: [
"rgba(255, 99, 132, 0.5)",
"rgba(54, 162, 235, 0.5)",
"rgba(255, 206, 86, 0.5)",
"rgba(75, 192, 192, 0.5)",
"rgba(153, 102, 255, 0.5)",
"rgba(255, 159, 64, 0.5)",
],
},
],
});

const report = {
dataSource: {
filename: "https://cdn.webdatarocks.com/data/data.csv",
},
slice: {
rows: [
{
uniqueName: "Country",
},
],
columns: [
{
uniqueName: "Measures",
},
],
measures: [
{
uniqueName: "Price",
aggregation: "sum",
},
],
},
};

const onReportComplete = () => {
if (pivotRef.current) {
pivotRef.current?.webdatarocks.off("reportcomplete");
createChart();
}
};

const createChart = () => {
if (pivotRef.current) {
pivotRef.current?.webdatarocks.getData(
{},
drawChart,
drawChart
);
};
};

const drawChart = (rawData: any) => {
const { labels, values } = prepareData(rawData);
setChartData({
labels: labels,
datasets: [
{
data: values,
backgroundColor: [
"rgba(255, 99, 132, 0.5)",
"rgba(54, 162, 235, 0.5)",
"rgba(255, 206, 86, 0.5)",
"rgba(75, 192, 192, 0.5)",
"rgba(153, 102, 255, 0.5)",
"rgba(255, 159, 64, 0.5)",
],
},
],
});
};

const prepareData = (rawData: any) => {
const labels = rawData.data.filter((rec: any) => rec.r0 && rec.v0).map((rec: any) => rec.r0);
const values = rawData.data.filter((rec: any) => rec.r0 && rec.v0).map((rec: any) => rec.v0);

return { labels, values };
};

return (
<div>
<WebDataRocksReact.Pivot
ref={pivotRef}
toolbar={true}
report={report}
reportcomplete={onReportComplete}
/>
<PolarArea data={chartData} />
</div>
);
}

export default App;

See also