Change --f7-list-item-after-text-color based on value from json in oh-repeater

Hi,

I display a json based item in a simpleList using oh-repeater:

                    - component: oh-list-card
                      config:
                        simpleList: false
                        style:
                          --f7-list-item-after-font-size: 16px
                          --f7-list-item-after-font-weight: bold
                          --f7-list-item-after-text-color: var(--f7-text-color)
                          min-width: 250px
                          simpleList: true
                        title: Today
                      slots:
                        default:
                          - component: oh-repeater
                            config:
                              for: day
                              fragment: true
                              in: =JSON.parse(items.pricesfortoday.state)
                            slots:
                              default:
                                - component: oh-list-item
                                  config:
                                    after: =loop.day.total
                                    title: =dayjs(loop.day.startsAt).format('dd HH:mm')

This displays the “total” cost-price value of my power for every hour of a certain day (at "startAt). How can I change the --f7-list-item-after-text-color for the top 5 items in this list? Or use some gradient green to red colour to show expensive (red) and cheap (green) times during the day? Prices currently vary from 0.15 to 0.30 € / kWh, but that might change off course, so for the gradient it would need to have the lowest and highest value during the day…

Regards,

Nika.

Specific answers would have to depend on what the actual content of your JSON is. But the general answer is that when you have a repeater, in addition to the loop variable (e.g., loop.day in your case) you have access to the full array the repeater is using in the expressions as well by appending _source (in your case, loop.day_source).

The expression parser recognizes many of the standard javascript array methods (using arrow function syntax for the methods that require function input parameters). So, with the full array you can sort or map or anything else.

Here’s an example of what is in the JSON:

[{"startsAt":"2024-04-24T00:00:00.000+02:00","total":0.2503},{"startsAt":"2024-04-24T01:00:00.000+02:00","total":0.2451},{"startsAt":"2024-04-24T02:00:00.000+02:00","total":0.2446}]

Prettified:

[{
        "startsAt": "2024-04-24T00:00:00.000+02:00",
        "total": 0.2503
    }, {
        "startsAt": "2024-04-24T01:00:00.000+02:00",
        "total": 0.2451
    }, {
        "startsAt": "2024-04-24T02:00:00.000+02:00",
        "total": 0.2446
    }
]

In that case, I’d do something like the following. I would modify the repeater array itself using the map property to add a rank key to each of the array elements. This collects the total values, sorts them and then reorders that sorting from highest (index 0) to lowest (index last):

map: '{"startsAt":loop.day.startsAt,"total":loop.day.total,"rank":loop.day_source.map( d => d.total).sort().reverse().indexOf(loop.day.total)}'

And then the gradient option of red → green would be very easy just using the css hsl function where hue is the ratio of the rank of that element to the overall array length times 120. So, highest total or rank 0 = 0 hue (red) and lowest total or rank max = 120 hue (green).

--f7-list-item-after-text-color: =`hsl(${loop.day.rank/(loop.day_source.length -1)*120},100%,50%)`

That is absolutely marvelous and created exactly what I had hoped for:

I’ll call you JustinGPT as of now! Thanks @JustinG !

Regards,

Nika.