Equivalent of Alias in flux - map works for built in graphs, not all plugins

Hi!

I finally have a CDF plugin available to me. :slight_smile: But it’s a bit finicky when it comes to naming the series. I have a more detailed post on the grafana site:

Apparently map is not a functional equal when it comes to renaming series as what Alias is for influxql. Our site admin strongly encourages us to use flux in stead of influxql. Anybody with a idea for how to properly (re)name dataseries within flux so they are identical to what influxql + alias generates?

The map() function is for transforming your data one record at a time. Reading through the Grafana forums thread it sounds like the CDF plugin is using the column names for the legends, so I suspect something like this would work for you:

from(bucket:"piprobe/autogen")
 |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
 |> filter(fn: (r) => r._measurement == "ping" and r._field == "rtt")
 |> aggregateWindow(every: ${interval}, fn: mean)

// Add this:
 |> keep(columns: ["_time", "probe", "_value"])

This line will drop everything but what you’re interested in (the probe name, value of the “rtt” field, and the timestamp). This is necessary because it looks like the CDF plugin will get confused by all the other columns that Flux returns by default. The plugin appears to look for a column with timestamps, a column with numbers, and a column with strings that get used for the legend, which is all that you’ll have in your results after the keep() function.

Thanks for respondim @mhall119. I agree that your proposal looks sane, and close to what I would do. By close meaning I tend to use map() to be able to rename the output (I really do miss alias from influxql).

But alas - the CDF plugin does not agree with us.

I’ve done multiple variants on CLI and “table view” - but no luck so far. As far as I can tell the output is identical on influxql and flux

From my original ping example, this is how the data json looks like. There is a field called name at the start. That one is picked up by the CDF plugin.

 {
        "name": "mean",
        "refId": "A",
        "meta": {
          "executedQueryString": "from(bucket:\"piprobe/autogen\")\n |> range(start: 2022-03-16T05:44:43.344Z, stop: 2022-03-16T06:44:43.344Z)\n |> filter(fn: (r) => r._measurement == \"ping\" and\n  r._field == \"rtt\" and\n  r.probe == \"probe12\"\n )\n |> aggregateWindow(every: 1m, fn: mean)\n |> map(fn:(r) => ({ _time:r._time,_value:r._value,_measurement:\"mean\"}))\n"
        },
        "fields": [

Here is the same for the one which don’t work. The name field is missing, and no label in the CDF plugin.

 {
        "refId": "C",
        "meta": {
          "executedQueryString": "from(bucket:\"piprobe/autogen\")\n |> range(start: 2022-03-16T05:44:43.344Z, stop: 2022-03-16T06:44:43.344Z)\n |> filter(fn: (r) => r._measurement == \"ping\" and\n  r._field == \"rtt\" \n )\n |> map(fn:(r) => ({ _time:r._time,_value:r._value}))\n |> aggregateWindow(every: 1m, fn: mean)\n |> map(fn:(r) => ({ _time:r._time,\"Group\":r._value,_measurement:\"Group\"}))\n"
        },
        "fields": [

The coresponding querries
A

from(bucket:"piprobe/autogen")
 |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
 |> filter(fn: (r) => r._measurement == "ping" and
  r._field == "rtt" and
  r.probe == "${probe}"
 )
 |> aggregateWindow(every: ${interval}, fn: mean)
 |> map(fn:(r) => ({ _time:r._time,_value:r._value,_measurement:"mean"}))

C

from(bucket:"piprobe/autogen")
 |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
 |> filter(fn: (r) => r._measurement == "ping" and
  r._field == "rtt" 
 )
 |> map(fn:(r) => ({ _time:r._time,_value:r._value}))
 |> aggregateWindow(every: ${interval}, fn: mean)
 |> map(fn:(r) => ({ _time:r._time,"Group":r._value,_measurement:"Group"}))

Is the CDF plugin to blame? Should it read the name nested further in, connected to the data series, not the entire querry?

{
    "refId": "C",
    "meta": {
      "executedQueryString": "from(bucket:\"piprobe/autogen\")\n |> range(start: 2022-03-16T05:44:43.344Z, stop: 2022-03-16T06:44:43.344Z)\n |> filter(fn: (r) => r._measurement == \"ping\" and\n  r._field == \"rtt\" \n )\n |> map(fn:(r) => ({ _time:r._time,_value:r._value}))\n |> aggregateWindow(every: 1m, fn: mean)\n |> map(fn:(r) => ({ _time:r._time,\"Group\":r._value,_measurement:\"Group\"}))\n"
    },
    "fields": [
      {
        "name": "_time",
        "type": "time",
        "typeInfo": {
          "frame": "time.Time",
          "nullable": true
        },
        "config": {
          "unit": "ms",
          "color": {
            "mode": "thresholds"
          },
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          }
        },
        "values": [
            ...
        ],
        "entities": {},
        "state": {
          "scopedVars": {
            "__series": {
              "text": "Series",
              "value": {
                "name": "Series (C)"
              }
            },
            "__field": {
              "text": "Field",
              "value": {}
            }
          },
          "seriesIndex": 3
        }
      },
      {
        "name": "Group",
        "type": "number",  # CDF should use this name?
        "typeInfo": {
          "frame": "float64",
          "nullable": true
        },
        "labels": {},
        "config": {
          "unit": "ms",
          "min": 0,
          "color": {
            "mode": "thresholds"
          },
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          },
          "mappings": []
        },
        "values": [ ... ]

If you just want to change the name of a column, you can use the rename() function for that.

Let me walk through your map() examples and explain what they’re doing:

A

 |> map(fn:(r) => ({ _time:r._time,_value:r._value,_measurement:"mean"}))

This line replaces the values in the column _measurement with the string “mean”. So instead of your _measurement being “ping” it will be “mean” for all your records. This doesn’t change the name of any column in the results.

C

 |> map(fn:(r) => ({ _time:r._time,"Group":r._value,_measurement:"Group"}))

This does two things. Like the one above it changes the values in the _measurement column, this time replacing them with the string “Group”. But it also created a new column, named “Group”, and sets it’s value to the same as the _value column for each record.

If you just want to rename the _value column to be called Group, you can do that with:

 |> rename(columns: {_value: "Group"})

I would whole heatedly agree that my code here is not a fine example of flux coding. :slight_smile: I am just trying everything I can to get the labels to work with this plugin. It seems to be a bit random as to what I need to do in order to be able to rename the labels. I’m in contact with the author of the plugin now so perhaps it’s not to big of an job to get it to behave more like the build in plugins.

Thanks for the walk though of map() vs rename(). It did not solve the labels, but it may improve the speed of other graphs I have made.