Search code examples
angularangular11

Progress bar with breaks in angular


I am working on angular app and want to have a progress bar as shown in attached image.

progress_bar progress_bar2

I have seen many progress bar online but I am not able to find progress bar of this type. How I can get progress bar of this type?


Solution

  • I imagine can there're a better way to do it, but you can get it drawing the "separators" then you can make something like

    <div class="wrapper">
      <div class="progress" [style.width.%]="porc"></div>
      <div class="flex">
        <div *ngFor="let i of [0, 1, 2, 3, 4]" ></div>
      </div>
    </div>
    
    .wrapper
    {
     display:flex;
     flex-direction:column;
    }
    .wrapper div
    {
      height: 1rem;
    }
    .flex{
      display:flex;
      justify-content:space-evenly;
      margin-top:-1rem;
    }
    .flex div{
      width:.15rem;
      background: white;
    }
    .progress{
      background:steelblue;
    }
    

    If we want to show a gray "items", we can draw

    <div
      class="wrapper fade">
      <div *ngFor="let color of colors"></div>
    </div>
    

    And

    .wrapper.fade
    {
      margin-bottom:-1rem;
    }
    .wrapper.fade div
    {
      background:silver
    }
    

    See a stackblitz

    Update

    The idea is create a div that has a width in percent equal to a variable "porc", the [style.width.%]="porc"

    The "marks" are really a divs with width:.15rem (in the .css are the .flex div). You can replace background: white; by background: silver; to see that really the div are painted.

    When we use css-flex, we can indicate items are distributed so that the spacing between any two items (and the space to the edges) is equal using justify-content:space-evenly

    In the code I make that the margin-top of the div with class ".flex" was -1rem, the same heigth that the divs-. We can also use margin-bottom:-1rem applied to the progress bar

    If we want to create a component the only is that the variable "porc" was an @Input

    I updated the stackblitz with a component and with another .css that makes the same

    Update 2*

    If we can change the color of the progress bar according the "porc", we can use a "getter" of color

    get color(){
      if (this.porc>80)
         return 'red';
      if (this.porc>60)
         return 'orange';
      if (this.porc>40)
         return 'green';
      return yellow;
    }
    

    And use

    <div [style.background]="color" ...>
    

    Update 3

    There're another way to create a progress bar, using clip-path

    Using clip-path, we can do something like

    <div class="wrapper"
      [style.clip-path]="
        'polygon(0 0, ' + porc + '% 0, ' + porc + '% 100%, 0% 100%)'
      "
    >
       <div *ngFor="let color of colors" [style.background-color]="color"></div>
    </div>
    

    Now we can define an array of colors like

    colors=["yellow","yellow","yellow","orange","orange","orange","red","red","red"]
    

    The .css using css-flex

    .wrapper
    {
      display:flex;
      height: 1rem;
      margin-left:-.125rem;
    }
    .wrapper div
    {
      flex-grow: 1;
      height:100%;
      margin-left:.125rem;
    }
    

    If we want to see a items silver, we can draw another div

    <div
      class="wrapper fade">
      <div *ngFor="let color of colors" ></div>
    </div>
    
    .wrapper.fade
    {
      margin-bottom:-1rem;
    }
    .wrapper.fade div
    {
      background-color:silver;
    }
    

    And we can see how the "silvers" items are colored when the porc change

    Updated in the stackblitz under a component progress-bar-coloured