Create a pie chart using Angular and Springboot
Tags: springboot, webdev, angular, piechart
Published: 2022-12-24 20:05:38

**Introduction**

In this tutorial, we will learn how to create a pie chart in Angular using the ng2-charts library and retrieve data from a Springboot backend to populate the chart. The pie chart will display the number of patients in a hospital based on a particular visit type.


![The image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2mvf7irxqm6ddpd0pzs.jpg)

**Prerequisites**

- Basic knowledge of Angular and Springboot.
- Node.js and npm installed on your machine.
- Angular CLI installed on your machine.
- A PostgreSQL database set up and configured with Springboot.

**Step 1: Set up the Angular project**
First, let's create a new Angular project using the Angular CLI .Type the command  `ng new demoapp` 

Next, install the `ng2-charts` and `chart js` libraries by running the following command: `npm install ng2-charts chart.js --save`

This will install the latest version of both ng2-charts and Chart.js and save the dependencies in your `package.json` file.

Once the installation is complete, you can import the charts modules in your module where you want to use them. Here's an example of how you can do this:

```
import { NgChartsModule } from 'ng2-charts';

@NgModule({
  imports: [
    NgChartsModule
  ],
  // ...
})
export class MyModule {}
```
**Step 2: Create the an entity class in your backend.**
In your backend code, create an entity class called Patient to represent a patient in the database. Here i'm assuming you have already set up your springboot application to any database. The Patient class should have fields for the patient's ID and visit type.



```
@Entity
@Table(name = "patients")
public class Patient {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String visitType;

  // Getters and setters

}
```

**Step 3: Create the repository interface.**
Next, create a repository interface that extends JpaRepository and define a method to find the number of patients in each visit type.

```
public interface PatientRepository extends JpaRepository<Patient, Long> {
  
    @Query(value = "SELECT visit_type, COUNT(*) as count FROM patients GROUP BY visit_type", nativeQuery = true)
    List<Object[]> countByVisitType();
}
```
_Code explanation_

This is an interface that extends the `JpaRepository `interface and defines a custom method called `countByVisitType`.

The `JpaRepository` interface is a Spring Data interface that provides basic CRUD (create, read, update, delete) operations for a given entity type. By extending this interface, the `PatientRepository` interface is able to inherit these basic CRUD methods and use them to perform database operations on `Patient` objects.

The `countByVisitType` method is a custom method that has been defined in the `PatientRepository` interface. It is annotated with `@Query`, which allows you to specify a custom query to be executed when the method is called. 

The query in this case is `SELECT visit_type, COUNT(*) as count FROM patients GROUP BY visit_type`, which selects the `visit_type` column and the `count` of patients for each `visit_type` (`SELECT visit_type, COUNT(*) as count`) from the patients table (FROM patients) and groups the results by `visit_type` (GROUP BY visit_type).

The `nativeQuery = true` attribute indicates that the query is a native SQL query rather than a `JPQL` (Java Persistence Query Language) query.

The method is returning a `List<Object[]>` object, which is a list of arrays of objects. Each `Object[]` object in the list represents a row in the result set returned by the query, with the first element being the `visit_type `and the second element being the count of `patients` for that type.

When this method is called, it will execute the specified query and return a list of `Object[]` objects representing the results of the query.


**Step 4  Create the controller**
In the controller, define an endpoint that returns the number of patients in each visit type as a JSON object with the visit type as the key and the number of patients as the value.

 

```
@RestController
@RequestMapping("/api/test")
@AllArgsConstructor
public class TestController {
  @Autowired
    private  final PatientRepository patientRepository;
 @GetMapping("/home")
    public Map<String, BigInteger> countByVisitType() {
        Map<String, BigInteger> result = new HashMap<>();
        List<Object[]> counts = patientRepository.countByVisitType();
        for (Object[] row : counts) {
            result.put((String) row[0], (BigInteger) row[1]);
        }
        return result;
    }}
```
_Code explanation_ 

`@GetMapping("/home")`, which means that it will handle HTTP GET requests to the `/home` endpoint.

The method returns a `Map<String, BigInteger>` object, which is a map that maps string keys to `BigInteger` values. The keys will represent the different types of visits, and the values will represent the number of patients that have visited for each type.

The method first creates an empty `Map` object called `result` and then retrieves a List of `Object[]` objects from the `patientRepository` object. Each `Object[]` object in the list represents a row in the result set returned by the repository's `countByVisitType()` method, which is likely a custom method that returns the number of patients that have visited for each type of visit.

The controller method then iterates over each `Object[]` object in the list and adds an entry to the result map by casting the first element of the array to a `String` (the type of visit) and the second element to a `BigInteger`(the number of patients that have visited for that type of visit). Finally, the method returns the result map.

**Step 5: Create the pie chart component in Angular**
In the Angular project, create a Home component to display the pie chart.To do this run the command `ng g c home` in your angular cli terminal. Then, declare properties `pieChartData` and `pieChartLabels`:

```
export class HomeComponent implements OnInit {
  pieChartData!: ChartData<ChartType, number[], string>;
  pieChartLabels: string[] = [];
}
```

`pieChartData`: This is a property of type `ChartData<ChartType, number[], string>`, which is a type provided by the `Chart.js` library.
`ChartData` represents the data for a chart, and is generic type that takes three type arguments:`ChartType `(the type of chart), `number[]` (the data), and `string` (the labels). In this case, `pieChartData` will be used to store the data for a pie chart.

`pieChartLabels`: This is an array of strings that will be used to label the slices of the pie chart.

**Step 6: Get the data from the api**
Use http client to fetch data from your endpoint.

```
...
constructor(private http : HttpClient){}
ngOnInIt(): void{
 this.http.get<any>('http://localhost:8080/api/test/home').subscribe(data => {
    this.pieChartLabels = Object.keys(data);
    this.pieChartData = {
      labels: this.pieChartLabels,
      datasets: [
        {
          data: Object.values(data),
          backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56' , 'grey'],
          hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56' , 'grey'],
        },
      ],
    };
  });

}
```

The method `ngOnInIt` makes an HTTP GET request to the `http://localhost:8080/api/test/home` URL using the `HttpClient` service, which is a service provided by Angular for making HTTP requests. The response from the server is expected to be an object with `string` as keys and `BigInteger` as values, and is stored in a variable called `data`.

The method then sets the `pieChartLabels` property to the keys of the data object using the `Object.keys` method, which returns an array of the keys of an object.

The `pieChartData` property is then set to an object with the following structure:

`labels`: An array of strings that will be used to label the slices of the pie chart. This is set to the `pieChartLabels` property.

`datasets`: An array of objects that represent the data for the chart. Each object in the array has the following properties:

`data`: An array of numbers that represents the data for the chart. This is set to the values of the data object using the `Object.values` method.

`backgroundColor`: An array of strings that represents the background color for each slice of the pie chart.

`hoverBackgroundColor`: An array of strings that represents the background color for each slice of the pie chart when the mouse is hovering over it.
This `pieChartData` object is then used to configure and display a pie chart using the Chart.js library.

**Step 7: Display the pie chart in the template**
Finally, we can display the pie chart in the template by using the baseChart directive from the `ng2-charts` library.

```
<div style="width: 440px; height: 440px;" >
       <canvas class="pie-chart"  baseChart  
          [data]="pieChartData"
          [labels]="pieChartLabels"
          [type]="'pie'" 
          >  
        </canvas>
  </div>
```

Now run your springboot application and navigate to the Home component of your demoapp and a piechart will displayed.

Here is the full HomeComponent class

```
export class HomeComponent implements OnInit {
  pieChartData!: ChartData<ChartType, number[], string>;
  pieChartLabels: string[] = [];
  constructor(private http : HttpClient)   { }
  ngOnInit(): void {
  this.http.get<any>('http://localhost:8080/api/test/home').subscribe(data => {
    this.pieChartLabels = Object.keys(data); 
    this.pieChartData = {
      labels: this.pieChartLabels,
      datasets: [
        {
          data: Object.values(data),
          backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56' , 'grey'],
          hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56' , 'grey'],
        },
      ],
    };
  });

  }


  }


```

**Conclusion**
In this tutorial, we learned how to create a pie chart in Angular using the ng2-charts library and retrieve data from a Springboot backend to populate the chart. We also learned how to create a repository interface and a controller to fetch the data and return it as a JSON object.

I hope this tutorial was helpful. If you have any questions or comments, please let me know in the comments section below. Happy coding!