DEV Community

Patrick Lusaya
Patrick Lusaya

Posted on • Updated on

Create a pie chart using Angular and Springboot

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

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 {}
Enter fullscreen mode Exit fullscreen mode

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

}
Enter fullscreen mode Exit fullscreen mode

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();
}
Enter fullscreen mode Exit fullscreen mode

Code explanation

This is an interface that extends the JpaRepositoryinterface 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_typeand 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;
    }}
Enter fullscreen mode Exit fullscreen mode

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[] = [];
}
Enter fullscreen mode Exit fullscreen mode

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'],
        },
      ],
    };
  });

}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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'],
        },
      ],
    };
  });

  }


  }


Enter fullscreen mode Exit fullscreen mode

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!

Top comments (0)