JSONATA for chart

I’m working with charts. The acquired data return three measures for each reading.
This is a sample of some of these.

[
  {
    "m_devID": 1,
    "m_time": "2022-04-04T13:48:11.000Z",
    "temperature": "17.65",
    "cond": "2900",
    "hum": "4.36"
  },
  {
    "m_devID": 1,
    "m_time": "2022-04-04T14:08:11.000Z",
    "temperature": "17.59",
    "cond": "2900",
    "hum": "4.36"
  },
  {
    "m_devID": 1,
    "m_time": "2022-04-04T14:28:11.000Z",
    "temperature": "17.54",
    "cond": "2900",
    "hum": "4.36"
  }
]

I transform the data in order to be used with chart, to di so I’ve implemented one for cycle and I build what I need.
These data are the transformed ones.

[
  {
    "series": [
      "Temp °c",
      "Hum. %",
      "Cond mS/cm"
    ],
    "data": [
      [
        {
          "x": 1649080091000,
          "y": 17.65
        },
        {
          "x": 1649081291000,
          "y": 17.59
        },
        {
          "x": 1649082491000,
          "y": 17.54
        }
      ],
      [
        {
          "x": 1649080091000,
          "y": 4.36
        },
        {
          "x": 1649081291000,
          "y": 4.36
        },
        {
          "x": 1649082491000,
          "y": 4.36
        }
      ],
      [
        {
          "x": 1649080091000,
          "y": 2.9
        },
        {
          "x": 1649081291000,
          "y": 2.9
        },
        {
          "x": 1649082491000,
          "y": 2.9
        }
      ]
    ],
    "labels": [
      "ltemp",
      "lhum",
      "lcond"
    ]
  }
]

I’m convinced that is possible to do the same whit a simpler JSONATA operation, but I wasn’t able to find one. I’m wrong, does exist a simple JSONATA transform?

F.

Is there a particular reason for wanting to use jsonata?

Jsonata often looks as though it's more efficient because it uses less code, but as mentioned a number of times in the forum, it can take considerably more time to execute the code, than plain old JavaScript.

Just something to consider.

No, I solved the problem in the traditional way, but I've spent a lot of time trying (without a solution) with jsonata, and now I'm curious. :roll_eyes:

2 Likes

When I stopped to look for solutions I found, at least one.

Here it is:

[
   {
       "labels":["Humidity", "Conductivity", "Temperature"],
       "series":["%", "mS/cm", "°C" ],
       "data": [
           [
               /* 
               Signature: $map(array, function)
               function(value [, index [, array]])

               $v is the value of m_time, $i is the array index, $a is the array (not needed here) 
               */
               
               $map(
                   payload.$toMillis(m_time),
                   function($v, $i, $a) {   
                       {
                           'x': $v,
                           'y':payload[$i].$number(hum) 
                }  
            }
            )    
        ],[
               $map(
                   payload.$toMillis(m_time),
                   function($v, $i) {
                       {
                           'x': $v,
                           'y':payload[$i].$number(cond) /1000
                }  
            }
            )    
        ],[
               $map(
                   payload.$toMillis(m_time),
                   function($v, $i) {
                       {
                           'x': $v,
                           'y':payload[$i].$number(temperature)
                }  
            }
            )    
        ]
       ]
   }
]

It needs three runs over payload so, as suggested by @Paul-Reed, I think is not so efficient. Maybe I make some performance tests.

Applied to this data

{
  "payload": [
    {
      "m_devID": 1,
      "m_time": "2022-04-04T13:48:11.000Z",
      "temperature": "17.65",
      "cond": "2900",
      "hum": "4.36"
    },
    {
      "m_devID": 1,
      "m_time": "2022-04-04T14:08:11.000Z",
      "temperature": "17.59",
      "cond": "2900",
      "hum": "4.36"
    },
    {
      "m_devID": 1,
      "m_time": "2022-04-04T14:28:11.000Z",
      "temperature": "17.54",
      "cond": "2900",
      "hum": "4.36"
    }
  ]
}

Look here:
https://try.jsonata.org/J26OuQ1JW

Which could be reduced to

[
   {
       "labels":["Humidity", "Conductivity", "Temperature"],
       "series":["%", "mS/cm", "°C" ],
       "data": [
           $map(["hum","cond","temperature"], function($v){
           [$$.payload.{
                'x': $toMillis($.m_time),
                'y': $number($lookup($,$v)) 
            }  
        ]})
       ]
   }
]

This node is ideal for checking performance times - GitHub - bartbutenaers/node-red-contrib-msg-profiler: A Node-RED node to execute time profiling (and tracing) of a message through a flow

Thanks. Very concise query. If I understand it cycles three times, one for every parameter inside the array ["hum","cond","temperature"].
I've to better understand JSONATA and the use of parameters, and the documentation isn't very easy. Too much $ :slightly_smiling_face:.

@Paul-Reed very useful node.