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?