I have multiple lengths of array in variables and I need to find which variable is greater and just change the color of that variable font. I have done this but issue is if 2 variable have same values so I need to color both of them right now its just showing one.
My code
calculateconfirm(location1, location2, location3, location4, type) {
var max = Number.NEGATIVE_INFINITY;
var max_key = undefined;
var obj = { 'location1': location1, 'location2': location2, 'location3': location3, 'location4': location4 };
for (var key in obj) {
if (obj[key] > max) {
max_key = key;
max = obj[key];
}
}
return max_key == type ? '#5D3FD3' : '#301934';
}
Html
<tr *ngFor="let x of userdata">
<td><img src="{{x.data.userImage}}" alt="" style="height: 75px; width: 75px;"></td>
<td>{{x.data.fullName}}</td>
<td *ngIf="x.data.location.location1 == 'false'">N/A</td>
<td *ngIf="x.data.location.location1 != 'false'"
[style.color]="calculateconfirm(x.data.location.like.length, x.data.location2.like.length, x.data.location3.like.length, x.data.location4.like.length, 'location1')">
{{x.data.location.location1}}
<td *ngIf="x.data.location2.location2 == 'false'">N/A</td>
<td *ngIf="x.data.location2.location2 != 'false'"
[style.color]="calculateconfirm(x.data.location.like.length, x.data.location2.like.length, x.data.location3.like.length, x.data.location4.like.length, 'location2')">
{{x.data.location2.location2}}
<td *ngIf="x.data.location3.location3 == 'false'">N/A</td>
<td *ngIf="x.data.location3.location3 != 'false'"
[style.color]="calculateconfirm(x.data.location.like.length, x.data.location2.like.length, x.data.location3.like.length, x.data.location4.like.length, 'location3')">
{{x.data.location3.location3}}
<td *ngIf="x.data.location4.location4 == 'false'">N/A</td>
<td *ngIf="x.data.location4.location4 != 'false'"
[style.color]="calculateconfirm(x.data.location.like.length, x.data.location2.like.length, x.data.location3.like.length, x.data.location4.like.length, 'location4')">
{{x.data.location4.location4}}
</td>
</tr>
Lets assume I have Obj like this
var obj = { 'location1': 2, 'location2': 1, 'location3': 5, 'location4': 5 };
So I need to color location 3 and 5 both in html.
CodePudding user response:
You need to keep track of multiple keys in cases where they both have the current max value. If a new max value is found, discard all existing keys. The following tweaked version of your existing function should work for this purpose:
calculateconfirm(location1, location2, location3, location4, type) {
var max = Number.NEGATIVE_INFINITY;
// store keys in an array, so we can have several
var max_keys = [];
var obj = { 'location1': location1, 'location2': location2, 'location3': location3, 'location4': location4 };
for (var key in obj) {
if (obj[key] > max) {
max_keys = [key];
max = obj[key];
} else if (obj[key] === max) {
// add to list of keys if there's a tie
max_keys.push(key)
}
}
// check if type matches any of the keys
return max_keys.includes(type) ? '#5D3FD3' : '#301934';
}
CodePudding user response:
It would be simpler if you calculate the max value only once and then compare against that known value to assign the style. Here is a simplified example:
export class AppComponent {
items = [
{ name: 'Item #1', value: 3 },
{ name: 'Item #2', value: 2 },
{ name: 'Item #3', value: 3 },
{ name: 'Item #4', value: 5 },
{ name: 'Item #5', value: 4 },
{ name: 'Item #6', value: 5 },
];
maxValue = Math.max(...this.items.map(i => i.value));
}
<li *ngFor="let item of items" [style.color]="item.value === maxValue ? 'red' : 'black'">
{{ item.name }} ({{ item.value}})
</li>
Notice we use a ternary operation to assign the value of the style; we simply compare the value
against the previously computed maxValue
.
Notice we don't call a function from the template. Generally, you want to avoid calling functions from the template because they will get executed each time Angular's change detection runs. In your code, you're calling the function 4 times for every item in your collection and within the function you're iterating the array. In small data sets you won't notice, but as you the data gets larger (or the complexity of your function increases) performance could be impacted.
Here's a little StackBlitz sample.
In your case it looks like you have multiple values in each row of data. You can still use the same principle of calculating the max value, but you'd do it for each row. You can append a new maxValue
property to each object in the array, something like this:
export class AppComponent {
private dataItems = [
{ name: 'Item #1', values: [3, 1, 2, 3] },
{ name: 'Item #2', values: [8, 2, 5, 3] },
{ name: 'Item #3', values: [3, 4, 2, 4] },
{ name: 'Item #4', values: [5, 5, 1, 9] },
{ name: 'Item #5', values: [4, 8, 1, 8] },
{ name: 'Item #6', values: [5, 1, 6, 7] },
];
items = this.dataItems.map(item => ({
name : item.name,
values : item.values,
maxValue : Math.max(...item.values)
}));
}
<tr *ngFor="let item of items">
<td> {{ item.name }}
<td *ngFor="let value of item.values"
[style.color]="value === item.maxValue ? 'red' : 'black'"
>
{{ value }}
</td>
</tr>