Circular Progress Bar In Angular

In this article, we can see how to create a simple Circular progress bar using HTML, CSS in angular with dynamic value change. It can be used in any angular version.

Creating a component

Create a component for Circular progress bar using ng component or directly add the files using add new files. Name the folder CircleProgress and add fthe ollowing file as shown in the image. You can create it in shared folder to share with other components.

Create file using ng component 

ng generate component CircleProgress

or

ng g c CircleProgress

circleprogress.component.html

Add following code in .html 

<div id="progress">
  <span id="progress-value"></span>
</div>

circleprogress.component.scss

#progress {
  height: 17px;
  width: 17px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  float: left;
  margin-top: 3px;
  margin-right: 10px;
}

#progress-value {
  display: block;
  height: calc(100% - 4px);
  width: calc(100% - 4px);
  background-color: #ffffff;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 20px;
}

circleprogress.component.ts

import { Component,  ElementRef,  Input,  OnInit,  SimpleChanges,  ViewChild } from '@angular/core';
@Component({
  selector: 'circle-progress',
  templateUrl: './circleprogress.component.html',
  styleUrls: ['./circleprogress.component.scss'],
})
export class CircleProgress implements OnInit {
  @Input() progress: number;
  ngOnInit(): void {
    this.loadData();
  }
  loadData() {
    let scrollProgress = document.getElementById('progress');
    scrollProgress.style.background = `conic-gradient(#008fff ${this.progress}%, #f2f2f4 ${this.progress}%)`;
  }
  ngOnChanges(changes: SimpleChanges): void {
    this.loadData();
  }
}

In ngOninit we call the loadData() method which will pass the progress value to the CSS. And same method is called over on every change event of progress value. ngOnChanges is value change event fired on every progress value changes.

app.module.ts

Import the component in module and declare the component to use 

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { CircleProgress } from './shared/CircleProgress/circleprogress.component';

@NgModule({
  imports: [BrowserModule, FormsModule, ReactiveFormsModule],
  declarations: [
    AppComponent,
    CircleProgress,
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Now use the component in other component.

So as of now we have already imported the component in appmodule so we can directly use the component with selector as shown below. app.component.html

<div class="row">
  <p>Circular Progress bar</p>
</div>
<br />

<div class="row" *ngIf="!completed">
  <p>
    <span> <circle-progress [progress]="progress"></circle-progress></span>
    {{ progress }} %
  </p>
</div>
<br />

<div class="row" *ngIf="completed">Progress completed</div>

app.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
  progress: number = 0;
  noOfFiles: number = 13;
  completed: boolean = false;

  public ngOnInit(): void {
    this.updateProgress();
  }

  delay(ms: number) {
    return new Promise((resolve, reject) => setTimeout(resolve, ms));
  }

  async updateProgress() {
    this.completed = false;
    let n = 100 / this.noOfFiles;
    for (let i = 0; i <= this.noOfFiles; i++) {
      await this.delay(500);
      this.progress = Math.round(i * n);
      console.log(i);
    }
    this.completed = true;
  }
}

I have used delay() method to show the progress, so the for loop will work as async call with await.

Output

Conclusion

In this article, we have created a simple circular progress bar with HTML, CSS in angular. We can adjust the size and colour of the progress by changing in CSS. Hope this will be simple and easy to create and access. Thanks to all.