1

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

    users = [
    {
      "name": "Tim Jones",
      "email": "timjones_1965@gmail.com",
      "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!

raaaay
  • 496
  • 7
  • 14
roymckrank
  • 689
  • 3
  • 12
  • 27

3 Answers3

5

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.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
roymckrank
  • 689
  • 3
  • 12
  • 27
2

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)  
    }}
raaaay
  • 496
  • 7
  • 14
1

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';
       }
    }
raaaay
  • 496
  • 7
  • 14
Wandrille
  • 6,267
  • 3
  • 20
  • 43
  • It worked well with the theme colors, but what if I want different colors than primary, accent and warn, is there any option to do that? – roymckrank Sep 05 '18 at 17:42
  • 1
    That will be really annoying. You will have to override all the classes of material to achieve that. – Wandrille Sep 05 '18 at 19:09
  • @roymckrank you can solve that problem using ::ng-deep .mat-progress-bar-fill::after { background-color: ; } – Lorenzo Vincenzi Mar 17 '21 at 12:03