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 { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
    }
    <app-wbr-pivot
     [toolbar]="true">
    </app-wbr-pivot>

    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:

      import { Component} from "@angular/core";
      
      @Component({
        selector: "app-root",
        templateUrl: "./app.component.html",
        styleUrls: ["./app.component.css"],
      })
      export class AppComponent {
        report = {
          dataSource: {
            filename: "https://cdn.webdatarocks.com/data/data.csv",
          },
          slice: {
            rows: [
              {
                uniqueName: "Country",
              },
            ],
            columns: [
              {
                uniqueName: "Measures",
              },
            ],
            measures: [
              {
                uniqueName: "Price",
                aggregation: "sum",
              },
            ],
          },
        };
      }
      <app-wbr-pivot
       [toolbar]="true"
       [report]="report">
      </app-wbr-pivot>

      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.

      Import WebdatarocksComponent and get a reference to the <app-wbr-pivot> instance using a template variable and the @ViewChild decorator:

        import { Component, ViewChild } from "@angular/core";
        import { WebdatarocksComponent } from "@webdatarocks/ngx-webdatarocks";
        
        @Component({
          selector: "app-root",
          templateUrl: "./app.component.html",
          styleUrls: ["./app.component.css"],
        })
        export class AppComponent {
          @ViewChild("pivot") pivotRef!: WebdatarocksComponent;
        
          // ...
        }
        <app-wbr-pivot #pivot
         [toolbar]="true"
         [report]="report">
        </app-wbr-pivot>

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

        Note. If you are using the legacy @webdatarocks/ng-webdatarocks wrapper, import WebdatarocksComponent from it.

        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 your charting library. For Chart.js, run the following commands in the console:

        npm install chart.js

        Step 3.2. Import your charting library into the component:

          import { Chart, ChartConfiguration, registerables } from 'chart.js';
          
          Chart.register(...registerables);

          Step 3.3. Add a <canvas> tag for your chart in the HTML template of the component:

            <app-wbr-pivot
              #pivot
              [toolbar]="true"
              [report]="report">
            </app-wbr-pivot>
            
            <canvas></canvas>

            Step 3.4. Get a reference to the <canvas>  instance using a template variable and the @ViewChild decorator:

              import { Component, ViewChild, ElementRef } from "@angular/core";
              // ...
              
              @Component({
                selector: "app-root",
                templateUrl: "./app.component.html",
                styleUrls: ["./app.component.css"],
              })
              export class AppComponent {
                @ViewChild("pivot") pivotRef!: WebdatarocksComponent;
                @ViewChild('chartCanvas') chartCanvas!: ElementRef;
              
                // ...
              }
              <canvas #chartCanvas></canvas>

              Step 3.5. Create a variable that will store a chart:

                chart!: Chart<"polarArea">;

                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:

                  onReportComplete() {
                    // Unsubscribing from reportcomplete
                    // We need it only to track the initialization of WebDataRocks
                    this.pivotRef.webDataRocks.off("reportComplete");
                    this.createChart();
                  };
                  <app-wbr-pivot
                    #pivot
                    [toolbar]="true"
                    [report]="report"
                    (reportcomplete)="onReportComplete()">
                  </app-wbr-pivot>

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

                    createChart() {
                      this.pivotRef.webDataRocks.getData(
                        {}, 
                        // Function called when data for the chart is ready
                        this.drawChart.bind(this),
                        // Function called on report changes (filtering, sorting, etc.) 
                        this.drawChart.bind(this),
                      );
                    };

                    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:

                      drawChart(rawData: any) {
                        const { labels, values } = this.prepareData(rawData); // This function will be implemented in step 4
                      
                        // Configuring the chart and filling it with data
                        const chartConfig: ChartConfiguration<'polarArea'> = {
                          type: 'polarArea',
                          data: {
                            labels: labels,
                            datasets: [
                              {
                                data: values,
                              },
                            ],
                          },
                        };
                      
                        if (this.chart) {
                          this.chart.destroy();
                        };
                      
                        // Creating a new chart instance
                        this.chart = new Chart(this.chartCanvas.nativeElement, chartConfig);
                      };

                      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:

                        prepareData(rawData: any): { labels: string[]; values: number[] } {
                          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. Run the project

                        Run your project with the following command:

                        ng serve --open

                        Open http://localhost:4200/ in the browser to see how the pivot table looks in combination with amCharts.

                        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:

                          import { Component, ViewChild, ElementRef } from '@angular/core';
                          import { WebdatarocksComponent } from "@webdatarocks/ngx-webdatarocks";
                          
                          import { Chart, ChartConfiguration, registerables } from 'chart.js';
                          
                          Chart.register(...registerables);
                          
                          @Component({
                            selector: 'app-root',
                            templateUrl: './app.component.html',
                            styleUrl: './app.component.css'
                          })
                          export class AppComponent {
                            @ViewChild("pivot") pivotRef!: WebdatarocksComponent;
                            @ViewChild('chartCanvas') chartCanvas!: ElementRef;
                          
                            chart!: Chart<"polarArea">;
                          
                            report = {
                              dataSource: {
                                filename: "https://cdn.webdatarocks.com/data/data.csv",
                              },
                              slice: {
                                rows: [
                                  {
                                    uniqueName: "Country",
                                  },
                                ],
                                columns: [
                                  {
                                    uniqueName: "Measures",
                                  },
                                ],
                                measures: [
                                  {
                                    uniqueName: "Price",
                                    aggregation: "sum",
                                  },
                                ],
                              },
                            };
                            
                            onReportComplete() {
                              this.pivotRef.webDataRocks.off("reportComplete");
                              this.createChart();
                            };
                          
                            createChart() {
                              this.pivotRef.webDataRocks.getData(
                                {}, 
                                this.drawChart.bind(this),
                                this.drawChart.bind(this),
                              );
                            };
                          
                            drawChart(rawData: any) {
                              const { labels, values } = this.prepareData(rawData);
                          
                              const chartConfig: ChartConfiguration<'polarArea'> = {
                                type: 'polarArea',
                                data: {
                                  labels: labels,
                                  datasets: [
                                    {
                                      data: values,
                                    },
                                  ],
                                },
                              };
                          
                              if (this.chart) {
                                this.chart.destroy();
                              };
                          
                              this.chart = new Chart(this.chartCanvas.nativeElement, chartConfig);
                            };
                          
                            prepareData(rawData: any): { labels: string[]; values: number[] } {
                              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 };
                            };
                          
                          }
                          <app-wbr-pivot #pivot
                           [toolbar]="true"
                           [report]="report"
                           (reportcomplete)="onReportComplete()">
                          </app-wbr-pivot>
                          <canvas #chartCanvas></canvas>

                          See also