I want to fill the background of a cell in a Material table with color. The cell should be filled in a way that it represents the cells value. It would kind of look like a bar chart in the end.
Is there a way to either make the div height fit the parent cell or apply the same behavior directly to the cell without using divs?
I prefer the last one more, but I don't even know if that is possible.
I took the current table from the Angular Material examples.
HTML:
<ng-container *transloco="let t; read: 'dashboard'">
<div >
// other cards
<table mat-table [dataSource]="dataSource" >
<ng-container [matColumnDef]="column" *ngFor="let column of displayedColumns">
<th mat-header-cell *matHeaderCellDef> {{column}} </th>
<td mat-cell *matCellDef="let element">
<div >
{{element[column]}}
<div style="width: 28%"></div>
<div style="width: 28%"></div>
</div></td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
</ng-container>
CSS:
.card-container {
width: 85vw;
height: 90vh;
display: flex;
flex-wrap: wrap;
flex-direction: column;
justify-content: space-evenly;
}
.overview-card {
width: 40%;
height: fit-content;
// height: 46%;
}
.overview-content {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.overview-item {
margin: 10px;
margin-top: 0px;
}
.make-gold {
background-color: gold
}
.progressbar-wrapper {
position: relative;
z-index: 1;
}
.progressbar {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
background-color: #dcf3dd;
z-index: -1;
}
.progressbar2 {
position: absolute;
top: 0;
bottom: 0;
left: 22%;
background-color: #1ccb25;
z-index: -1;
}
.table-card {
width: 44%;
height: 46%;
}
.value-card {
width: 20%;
height: 20%;
}
Typescript:
import { Component, OnInit } from "@angular/core";
import { MatTableDataSource } from "@angular/material/table";
@Component({
selector: "app-dashboard-page",
templateUrl: "./dashboard-page.component.html",
styleUrls: ["./dashboard-page.component.scss"],
})
export class DashboardPageComponent implements OnInit {
displayedColumns: string[] = ["name", "status", "windDirection", "windSpeed", "power"];
dataSource = new MatTableDataSource(ELEMENT_DATA);
constructor() {}
ngOnInit(): void {}
}
export interface PeriodicElement {
name: string;
status: string;
windDirection: number;
windSpeed: number;
power: number;
}
const ELEMENT_DATA: PeriodicElement[] = [
{
name: "Hydrogen",
status: "ok",
windDirection: 180.0,
windSpeed: 8.2,
power: 900,
},
{
name: "Helium",
status: "ok",
windDirection: 180.0,
windSpeed: 8.2,
power: 900,
},
{
name: "Lithium",
status: "ok",
windDirection: 180.0,
windSpeed: 8.2,
power: 900,
},
{
name: "Beryllium",
status: "ok",
windDirection: 180.0,
windSpeed: 8.2,
power: 900,
},
{
name: "Boron",
status: "ok",
windDirection: 180.0,
windSpeed: 8.2,
power: 900,
},
{
name: "Carbon",
status: "ok",
windDirection: 180.0,
windSpeed: 8.2,
power: 900,
},
{
name: "Nitrogen",
status: "ok",
windDirection: 180.0,
windSpeed: 8.2,
power: 900,
},
{
name: "Oxygen",
status: "ok",
windDirection: 180.0,
windSpeed: 8.2,
power: 900,
},
{
name: "Fluorine",
status: "ok",
windDirection: 180.0,
power: 900,
},
{
name: "Neon",
status: "ok",
windDirection: 180.0,
windSpeed: 8.2,
power: 900,
},
];
CodePudding user response:
You can use style binding to set a dynamic width percentage of both your progress bars. Then you just need to calculate this percentage, store in a property of your component and use on your .progressbar and .progressbar2 something like:
<div *ngFor="let element of elements; index as i">
<div [style.width]="percentFilled[i] '%'"></div>
<div [style.width]="percentEmpty[i] '%'"></div>
</div>
Edit: off-topic answer, sorry. I thought we were talking about the width.
CodePudding user response:
I found a way for the divs to fill up the space of the cells.
I added the min-height property to the wrapper:
.progressbar-wrapper {
position: relative;
min-height: inherit;
text-align: center;
width: 100%;
z-index: 1;
}
Then the value sticks to the top of a cell. To vertically center it again I put it in a p tag:
<mat-cell *matCellDef="let element" >
<div >
<p>{{ element[column] }}</p>
<div
*ngIf="element[column] >= 0"
[style.width]="getBarWidth(column, element[column]) '%'"
></div>
<div
*ngIf="element[column] < 0"
[style.width]="getBarWidth(column, element[column]) '%'"
[style.left]="barScale - getBarWidth(column, element[column]) '%'"
></div>
</div>
</mat-cell>
I still wonder if it works without using all those divs, but at least works.