Calculation in vega - vega

I use vega in Kibana.
I select two values from two different index in section "data". But now I need to summarize this values and visualize it in the section "marks". Is anybody know, how can I do this? Now in the section "marks" I use only one value from first "data".
My code is the following:
{
"$schema": "https://vega.github.io/schema/vega/v3.0.json",
"title": {
"text": "Lead time, hr.",
"orient": "bottom"
},
"data": [
{
"name": "source_1",
"url": {
"index": "metrics-bitbucket-*",
"%context_query%": "#timestamp",
"body": {
"size": 0,
"aggs": {
"etb": {
"avg": {
"field": "elapsed_time",
"script": {"source": "_value/3600*10"}
}
}
}
}
},
"format": {"type": "json", "property": "aggregations.etb"}
},
{
"name": "source_2",
"url": {
"index": "metrics-jenkins-*",
"%context_query%": "#timestamp",
"body": {
"size": 0,
"aggs": {
"etj": {
"avg": {
"field": "elapsed_time",
"script": {"source": "_value/3600*10"}
}
}
}
}
},
"format": {"type": "json", "property": "aggregations.etj"}
}
],
"marks": {
"type": "text",
"from": {"data": "source_1"},
"encode": {
"update": {
"text": {"signal": "round(datum.value)/10"},
"fontSize": {"value": 60},
"fontStyle": {"value": "bold"},
"x": {"signal": "width/2-50"},
"y": {"signal": "height/2"}
}
}
}
}

You essentially have two lists of data objects: source1: [{}, {}, ...] and source2: [{}, {}, {}, ...]. When you draw items, you have to specify just one data source. That data source could be the concatenation of the first two, e.g. you create source3 with its source parameter set to ["source1", "source2"], which includes all elements from both, but I suspect this is not what you want here. Rather, you need to merge the data using lookup transform - iterate over the items in one data source, and pull the corresponding values from another data source. Afterwards, add a formula transform to sum the values. The mark would than use the result of the formula for drawing.

Related

How do I format currency in Vega-Lite?

I'm trying to format values as currency in the Vega-Lite editor. I'm attempting to copy the docs but I'm getting a weird error. The Y axis is a numerical value. Passing in a formatting string gives "value expected".
Here's the json:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "Protocol Chart",
"width": 500,
"height": 225,
"data": {
"values": [
{
"asset": "eth",
"time": "2021-06-15T00:00:00Z",
"ReferenceRateUSD": "2577.04473863238"
},
{
"asset": "eth",
"time": "2021-06-16T00:00:00Z",
"ReferenceRateUSD": "2552.74103641146"
},
{
"asset": "eth",
"time": "2021-06-17T00:00:00Z",
"ReferenceRateUSD": "2360.99938690824"
}
]
},
"config": {
"view": {
"stroke": "transparent"
}
},
"mark": "line",
"encoding": {
"x": {
"axis": {
"domainColor": "#DDD",
"grid": false,
"labelColor": "#AEAEAE",
"ticks": false,
"labelPadding": 10
},
"field": "time",
"type": "temporal",
"title": ""
},
"y": {
"axis": {
"labelOffset": 2,
"domainColor": "white",
"labelColor": "#AEAEAE",
"ticks": false,
"labelPadding": 10,
"format": '$.2f'
},
"field": "ReferenceRateUSD",
"type": "quantitative",
"title": "",
"scale": {
"zero": false
}
},
"color": {
"field": "doesntmatter",
"type": "nominal",
"legend": null,
"scale": {
"range": ["#91DB97"]
}
}
}
}
What am I missing here? How do I get it to accept my formatting string?
"$.2f" looks like a the correct d3-format string for currency, but note that this is only valid if the associated formatType is "number" (see axis label docs).
Since you did not include a full reproducible example of the problem you're seeing, I can only venture a guess that your data type is not numeric, and this is why the formatting is failing. If that's not the case, I'd suggest editing your question to provide a complete example of the error you're seeing.
Edit: your full example appears to work correctly with the current version of vega/vega-lite (view in editor):
Perhaps you need to update your vega/vega-lite libraries?

Why column facet in Vega Lite not working properly with layer?

I'm trying to create 3 column plot and it works when there's no layer.
But when I add the layer - 3 columns get merged into one plot (open in editor).
How to make it to be separated into 3 columns by the duration field?
CODE
For the plot with the full data please use editor link above.
{
"encoding": {
"column": { "field": "duration", "type": "nominal" },
"x": { "field": "bin_i", "type": "ordinal" }
},
"layer": [
{
"mark": { "type": "bar", "size": 2 },
"encoding": {
"y": { "field": "min", "type": "quantitative" },
"y2": { "field": "max", "type": "quantitative" }
}
},
{
"mark": { "type": "tick" },
"encoding": {
"y": { "field": "mean", "type": "quantitative" }
}
}
],
"data": {
"values": [
{
"bin_i": 1,
"duration": 1,
"max": 1.9642835793718165,
"mean": 1.0781367168962268,
"min": 0.3111818864927448
},
...
]
}
}
A layered chart does not accept a faceted encoding. If you want to facet a layered chart, you should use the facet operator rather than a facet encoding.
For your example, it would look like this (Vega Editor):
{
"facet": {"column": {"field": "duration", "type": "nominal"}},
"spec": {
"encoding": {
"x": {"field": "bin_i", "type": "ordinal"}
},
"layer": [
{
"mark": {"type": "bar", "size": 2},
"encoding": {
"y": {"field": "min", "type": "quantitative"},
"y2": {"field": "max"}
}
},
{
"mark": {"type": "tick"},
"encoding": {
"y": {"field": "mean", "type": "quantitative"}
}
}
]
},
"data": {
"values": [
{
"bin_i": 1,
"duration": 1,
"max": 1.9642835793718165,
"mean": 1.0781367168962268,
"min": 0.3111818864927448
},
...
]
}
}

How to specify Rule Line with a single value in VegaLite?

It's possible to specify Rule as encoding over the data. But sometimes it's too verbose. Is there a shorter way to specify it with just a single number?
In example below I want to draw a horizontal line with y=1 and it requires me to specify a calculate transform. Wonder if it's possible with something more compact, like:
"layer": [
...,
{ "mark": { "type": "rule", "y": 1 }, // Specify ruler with just a single line
...
]
Playground
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"transform":[
{ "calculate": "1", "as": "one" }
],
"layer": [
{
"mark": { "type": "bar" },
"encoding": {
"x": { "field": "diff", "type": "quantitative" },
"y": { "field": "diff", "type": "quantitative" }
}
},
{
"mark": { "type": "rule" },
"encoding": {
"y": { "field": "one", "type": "quantitative" }
}
}
],
"data": {
"values": [
{ "diff": 1 },
{ "diff": 2 },
{ "diff": 3 }
]
}
}
You can specify a single value using the "value" field in the encoding; e.g.
{
"mark": { "type": "rule" },
"encoding": {
"y": { "value": 133 }
}
}
(Playground)
But be aware this value is a value in the axis domain, rather than in the data domain; i.e. it represents pixels from the top-left of the chart.
If you want to specify a value in the data domain, there is no such shorthand. You have to either use a transform (as you did in your question) or define a new dataset for your layer. The most compact way of doing this, I think, is something like this:
{
"mark": { "type": "rule" },
"data": {"values": {"y": 1}},
"encoding": {
"y": { "field": "y" }
}
}

How to add a text field to a symbol mark

I'm trying to add a text mark to the nodes in the force-directed-layout example on the github page of vega.
I converted the symbol mark to a group mark and moved the "encode" part to a child "symbol" mark. In this new group-mark I now also add a text mark which I give the name of the node.
This is the nodes mark, the "on" and "transform" parts are left out because these are unchanged.
{
"name": "nodes",
"type": "group",
"zindex": 1,
"from": {
"data": "node-data"
},
"marks": [
{
"type": "symbol",
"encode": {
"enter": {
"fill": {
"scale": "color",
"field": "group"
},
"stroke": {
"value": "white"
}
},
"update": {
"size": {
"signal": "2 * nodeRadius * nodeRadius"
},
"cursor": {
"value": "pointer"
}
}
}
},
{
"type": "text",
"interactive": false,
"encode": {
"enter": {
"fill": {
"value": "black"
},
"fontSize": {
"value": 12
},
"align": {
"value": "center"
},
"text": {
"field": "name"
},
"y": {
"value": -5
}
}
}
}
],
"on": [...],
"transform": [...]
}
Expected was to see the name of the node above each node, but the text AND the symbol become invisible.
Steps to Reproduce
Make the type "group", add a "marks" array, add a mark object with type "symbol" to this marks array
-> the nodes still show
Move the encode part to the nested symbol group
-> the nodes dissapear
Adding the text mark also does nothing
I have a hunch that its the "field" property that borks when you try to nest it while keeping the data in the parent because the text mark does show in the group when I give it a fixed value, but I can't seem to figured out how to get it working.
(I thought this was the way because the docs say that a child mark gets the parent data automatically when ommiting a data field)
Within a group, you have to use {"parent": <field_name>} to refer to a field. For example, to refer to the field "group" in the parent use:
"field": {"parent": "group"}}
See an example here.
Adding the following mark also works, without breaking dragging (example link):
{
"type": "text",
"from": {"data": "nodes"},
"interactive": false,
"enter": {
"fill": {"value": "black"},
"fontSize": {"value": 10}
},
"encode": {
"update": {
"y": {"field": "y", "offset": {"signal": "nodeRadius * -0.9"}},
"x": {"field": "x"},
"text": {"field": "datum.name"},
"align": {"value": "center"}
}
}
}
This text mark uses the symbol mark (called nodes) as its backing data source. See https://vega.github.io/vega/docs/marks/#reactive-geometry.

How to add legend for single or multi series chart in Vega Lite?

How do I add a legend to a basic chart in Vega?
I'm using Vega in the web app where I want all my charts to include a legend even if its a single series.
i.e in Google Sheets it looks like
Since Datum hasn't been implemented yet I added an extra layer as a workaround (This also works for Multi Series Charts by adding additional values into data.values for the rule.)
{
"mark": {
"type": "rule"
},
"data": {
"values": [
{
"color": "Total Units"
}
]
},
"encoding": {
"color": {
"field": "color",
// If you want to update the color of the legend...
"scale": {"range": ["blue", "#000"]},
"sort": false,
"type": "nominal",
"legend": { "title": "" }
}
}
}
Also for those that want to view an example in VegaLite Editor https://vega.github.io/editor/#/
{
"layer": [
{
"mark": "bar",
"data": {
"values": [
{
"goal": 25,
"project": "a",
"score": 25
},
{
"goal": 47,
"project": "b",
"score": 57
},
{
"goal": 30,
"project": "c",
"score": 23
},
{
"goal": 27,
"project": "d",
"score": 19
}
]
},
"encoding": {
"x": {
"type": "nominal",
"field": "project"
},
"y": {
"type": "quantitative",
"field": "score"
}
},
"height": 300,
"width": 400
},
{
"mark": {
"type": "rule"
},
"data": {
"values": [
{
"color": "Goal"
}
]
},
"encoding": {
"color": {
"field": "color",
"sort": false,
"type": "nominal",
"legend": { "title": "" }
}
}
}
]
}