Doing math with auto_format: true
I’d like column 5 to be column 4 multiplied by 43 (the price of a liter multiplied by the capacity = the price of a full tank).
It works if I don’t use auto_format :
Not with it true:
Just in case, I tried :
I’m sure some of you will tell me it works exactly as expected but I can assure you, as a user (and not a Javascript developer or a computer wizard of some sort), it’s extremely disconcerting. Should I turn auto_format off and then apply a modify: to each column to replace the . with a , and add the unit?
auto_format happens very early - in fact the data is already received formatted from HA. This means inside modify you'll have a string already - doing arithmetic on strings is not liked by JS:
a = "3 hdf"
"3 hdf"
>> a*4
NaN
So under the line this boils down to the order of operations done on the data.
Maybe you should take a look into suffix (which is appended after modify):
https://github.com/custom-cards/flex-table-card/blob/master/docs/example-cfg-simple-cell-formatting.md
It feels like we should document these orders to avoid this confusion...
I'd like to fix this problem by grabbing both unformatted and formatted versions and making the unformatted version available for cross-cell math, sorting, footers, etc. The need for unformatted data keeps popping up in issues.
Haven't looked at it in detail yet but I will.
I'd like to fix this problem by grabbing both unformatted and formatted versions and making the unformatted version available for cross-cell math, sorting, footers, etc. The need for unformatted data keeps popping up in issues.
Haven't looked at it in detail yet but I will.
But then the cell in which you did cross-cell math won't be formatted, right?
Could the card do the formatting itself (grab the locale from HA and format the data once it's been modified, suffixed and everything)?
But then the cell in which you did cross-cell math won't be formatted, right?
The card can grab both formatted and unformatted values from HA and provide one or the other as appropriate.
In the meantime, you can use parseFloat:
let x = "1.682 €";
console.log (((parseFloat(x)) * 43).toFixed(1));
> "72.3"
The reason this works in this case is:
parseFloat() is more lenient than Number() because it ignores trailing invalid characters, which would cause Number() to return NaN.
But then the cell in which you did cross-cell math won't be formatted, right?
The card can grab both formatted and unformatted values from HA and provide one or the other as appropriate.
Some cells will be formatted (the ones without math), the others won't.
In the meantime, you can use
parseFloat:let x = "1.682 €"; console.log (((parseFloat(x)) * 43).toFixed(1)); > "72.3"The reason this works in this case is:
parseFloat() is more lenient than Number() because it ignores trailing invalid characters, which would cause Number() to return NaN.
I tried:
It doesn't work at all:
- It doesn't do the math, I get 55 instead of 55*1,8 (or whatever the price per liter is);
- the second column loses its format anyway.
Apparently parseFloat doesn't support commas as a decimal separator.
The characters accepted by parseFloat() are plus sign (+), minus sign (- U+002D HYPHEN-MINUS), decimal digits (0 – 9), decimal point (.), exponent indicator (e or E), and the "Infinity" literal.
So, you'll have to convert the comma to a period, and then you would have to reformat it:
let x = "1,682 €";
let result = new Intl.NumberFormat('fr',).format((((parseFloat(x.replace(',', '.'))) * 43).toFixed(1))) + ' €';
console.log(result);
> "72,3 €"
It's not pretty, but it works.
Thank you for spending time on my problem!
We're getting somewhere:
It's already really good but I'd like to force the number of decimals to 3 on the first column and 2 on the second one.
I tried modify: (new Intl.NumberFormat('fr',).format(parseFloat(x))).toFixed(3), modify: new Intl.NumberFormat('fr', { minimumFractionDigits: 3 } ).format(parseFloat(x)) to no avail
As I said, you're not going to get anywhere trying to parseFloat a number with a comma as a decimal separator.
BTW, I used "fr" to force the locale to French for the example, since my environment is set to "en-US".
let x = "1,8";
let y = 55;
console.log(new Intl.NumberFormat('fr',{minimumFractionDigits:3}).format(parseFloat(x.replace(',', '.'))) + "€/l");
console.log(new Intl.NumberFormat('fr',{minimumFractionDigits:2}).format((parseFloat(x.replace(',', '.') * y))) + "€");
> "1,800€/l"
> "99,00€"
As I said, you're not going to get anywhere trying to
parseFloata number with a comma as a decimal separator.
I know, so I had not set auto_format: to true. So I didn't need x.replace(',', '.') since x was already using a decimal point. My mistake (and I thank you for allowing me to realize it) was the space in minimumFractionDigits: 3
So, with modify: Intl.NumberFormat('fr',{ minimumFractionDigits:3 }).format(parseFloat(x)), I get:
Thanks again!!