Vega Pie doesn't show slices with scripted_metric, only the values in the middle of the chart without a Pie

I'm using Vega to create a Pie visualization that gets its data from an Elasticsearch index. I used the code for the Radial Plot pie example: Radial Plot Example | Vega, but I changed it to use an index and scripted_metric.

The scripted metric returns an array with 2 correct values, but they are shown only as text on the chart, and there are no slices.

The code for Vega is in the first block, and the code for the scripted_metric is in the second block, and it's multiple lines for clarity. When using it in Vega, I add it as one line.

With VEGA_DEBUG.vega_spec in the Dev Tools Console the values are returned in data[0].values.aggregations.item_matching.buckets.all.item_array.value and they can be seen in the screenshot.

But, using aggregations.item_matching.buckets.all.doc_count displays a pie.

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "A basic radial plot that encodes two values as the angle and radius of an arc.",

  "data": [

    {
        name: "table",
        url: {
          %context%: true
          %timefield%: @timestamp
          index: item_index
          body: {
            "aggs": {
                "item_matching": {
                  "filters": {
                    "filters": {
                      "all": {
                        "match_all": {}
                      }
                    }
                  },
                  "aggs": {
                    
                    "item_array": {
                      "scripted_metric": {

                      }
                    }
                  }
                }
              }
          }
        },
        format: {property: "aggregations.item_matching.buckets.all"},
        "transform": [{"type": "pie", "field": "item_array.value"}]
      }
  ],

  "scales": [
    {
      "name": "r",
      "type": "sqrt",
      "domain": {"data": "table", "field": "item_array.value"},
      "zero": true,
      "range": [20, 100]
    }
  ],

  "marks": [
    {
      "type": "arc",
      "from": {"data": "table"},
      "encode": {
        "enter": {
          "x": {"field": {"group": "width"}, "mult": 0.5},
          "y": {"field": {"group": "height"}, "mult": 0.5},
          "startAngle": {"field": "startAngle"},
          "endAngle": {"field": "endAngle"},
          "innerRadius": {"value": 20},
          "outerRadius": {"scale": "r", "field": "item_array.value"},
          "stroke": {"value": "#fff"}
        },
        "update": {
          "fill": {"value": "#ccc"}
        },
        "hover": {
          "fill": {"value": "pink"}
        }
      }
    },

    {
      "type": "text",
      "from": {"data": "table"},
      "encode": {
        "enter": {
          "x": {"field": {"group": "width"}, "mult": 0.5},
          "y": {"field": {"group": "height"}, "mult": 0.5},
          "radius": {"scale": "r", "field": "item_array.value", "offset": 8},
          "theta": {"signal": "(datum.startAngle + datum.endAngle)/2"},
          "fill": {"value": "#000"},
          "align": {"value": "center"},
          "baseline": {"value": "middle"},
          "text": {"field": "item_array.value"}
        }
      }
    }
  ]
}

The code for the scripted_metric:

"scripted_metric": {

    "init_script": "state.max_bytes = 0L; state.documents_count = 0L;",

    "map_script": """
        if (doc['item.15.result.keyword'].size() == 1) {
            if (doc['item.15.result.keyword'] != null && doc['item.15.result.keyword'].value == '100%') {
                state.max_bytes += 100;
                state.documents_count += 1;
                }
        }
        if (doc['item.15.result.keyword'].size() == 1) {
            if (doc['item.15.result.keyword'] != null && doc['item.15.result.keyword'].value == '30%') {
                    state.max_bytes += 30;
                    state.documents_count += 1;
                }
        }
                """,

    "combine_script": "return state;",

    "reduce_script": """
        def response_bytes = 0L;
        def counter = 0L;
            for (s in states) {if (Objects.isNull(s)){response_bytes=0} else if (s.max_bytes > 0)
            {response_bytes = s.max_bytes; counter = s.documents_count;}}
            
            return [response_bytes / counter, 100 - (response_bytes / counter)]
                    """
              
          }

The values appear as numbers in the middle of the chart, instead of showing slices. The example uses an array too, "values": [12, 23, 47, 6, 52, 19], and with it the pie is visible. Does the rendering gets delayed because the data is from an URL?

Adding the full path to the field with the array values with

format: {property: "aggregations.item_matching.buckets.all.item_array.value"}

and replacing everywhere "field": "item_array.value" with "field": "data" shows the pie and its slices.

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.