roymckrank
roymckrank

Reputation: 699

Change mat-progress-bar color depending on value

I have a progress bar that gets its value from an array, like this:

    users = [
    {
      "name": "Tim Jones",
      "email": "[email protected]",
      "photo": "assets/images/tim-jones.jpg",
      "progress": "50"
    },

And the progress bar

    <mat-progress-bar mode="determinate" value="{{user.progress}}"></mat-progress-bar>

I want to display different colors depending on progress value:

Progress from 0% to 20% = red<br>
Progress from 21% to 50% = yellow<br>
Progress from 51% to 100% = green<br>

Thanks for your help!

Upvotes: 1

Views: 9828

Answers (3)

roymckrank
roymckrank

Reputation: 699

Well, if anyone struggles with custom colors, I have added something like this to my component:

<div [ngClass]="{
            'danger-bar': oa.areaProgress <= 20,
            'warn-bar': oa.areaProgress > 21,
            'ok-bar': oa.areaProgress > 51
          }">
            <mat-progress-bar class="" mode="determinate" value="{{user.progress}}"></mat-progress-bar>
          </div>

And in the theme's CSS:

.danger-bar .mat-progress-bar-buffer {
    background-color: #ffd7d0!important;
}
.danger-bar .mat-progress-bar-fill::after {
    background-color: #ff6859!important;
}

.warn-bar .mat-progress-bar-buffer {
    background-color: #fff8e5!important;
}
.warn-bar .mat-progress-bar-fill::after {
    background-color: #ffcf44!important;
}

.ok-bar .mat-progress-bar-buffer {
    background-color: #b6fff2!important;
}

.ok-bar .mat-progress-bar-fill::after {
    background-color: #1eb980!important;
}

And I have a nice progress bars without the limitation of primary/accent colors.

Upvotes: 5

ChillyWilly
ChillyWilly

Reputation: 41

Derived and modified code from Change angular material progress bar color from code Utilizing a value of an element you can plug it into a directive to modify the color of a progress bar.

In your HTML

    <mat-progress-bar 
      value="{{ element.percent_complete }}"
      [appProgressBarColor]="(element.percent_complete)"
      mode="determinate">
    </mat-progress-bar>

Create a new TS file I made one in the same directory as the component utilizing mat-progress-bar. I named it progress-bar-color.ts Note the logic to change the color, you can modify the thresholds and colors.

    import { Directive, Input, OnChanges, SimpleChanges, ElementRef } from '@angular/core';

    @Directive({
    selector: '[appProgressBarColor]'
    })
    export class ProgressBarColor implements OnChanges{
    static counter = 0;
    color: string;
    @Input() appProgressBarColor;
    styleEl:HTMLStyleElement = document.createElement('style');
  
    //generate unique attribule which we will use to minimise the scope of our dynamic 
    style 
    uniqueAttr = `app-progress-bar-color-${ProgressBarColor.counter++}`;

    constructor(private el: ElementRef) { 
    const nativeEl: HTMLElement = this.el.nativeElement;
    nativeEl.setAttribute(this.uniqueAttr,'');
    nativeEl.appendChild(this.styleEl);
    }

    ngOnChanges(changes: SimpleChanges): void{
    this.updateColor();
    }


    updateColor(): void{
    if (this.appProgressBarColor > 75){
      this.appProgressBarColor = 'green'
    } 
    else if (this.appProgressBarColor > 50){
      this.appProgressBarColor = 'gold'
    }
    else if (this.appProgressBarColor > 25){
      this.appProgressBarColor = 'orange'
    }
    else{
      this.appProgressBarColor = 'red'
    }
    console.log(this.appProgressBarColor)

    // update dynamic style with the uniqueAttr
    this.styleEl.innerText = `
      [${this.uniqueAttr}] .mat-progress-bar-fill::after {
        background-color: ${this.appProgressBarColor};
      }
    `;
    console.log(this.appProgressBarColor)  
    }}

Upvotes: 2

Wandrille
Wandrille

Reputation: 6811

Have you tried:

    <mat-progress-bar 
       mode="determinate" 
       [color]="updateColor(user.progress)"
       value="{{user.progress}}">
    </mat-progress-bar>

with:

    updateColor(progress) {
       if (progress<21){
          return 'primary';
       } else if (progress>80){
          return 'accent';
       } else {
         return 'warn';
       }
    }

Upvotes: 1

Related Questions