Vega-lite: Mark text overlaps top axis - vega-lite

How can fix text overlap on the top axis in the example?
vega-lite example

This is what I ended up with.
Now, you will probably not like how I got there. In the editor I went to the Compiled Vega tab and edited the low-level Vega spec. The fix was:
Add a signal with the extent transform:
{"type": "extent", "field": "value", "signal": "y_domain"}
Derive two more signals from it:
{"name": "y_domain_min", "update": "y_domain[0]"},
{"name": "y_domain_max", "update": "y_domain[1] * 1.25"}
Note the multiplier.
Use the new signals for the domain definition.
{
"name": "y",
"type": "linear",
"domain": [{"signal": "y_domain_min"}, {"signal": "y_domain_max"}],
...
If a fix is possible directly in Vega-lite, I'd like to know.

Related

Vega-Lite Calculated Scale domainMax

I'm trying to calculate a value for domainMax on the Y-axis scale. I tried the following example where I want the Y-axis domainMax to be one greater than the maximum value in the dataset field named "value". The example produces the error 'Unrecognized signal name: "domMax"'. How can I get it to work?
{
"data": {
"values": [
{"date": "2021-03-01T00:00:00", "value": 1},
{"date": "2021-04-01T00:00:00", "value": 3},
{"date": "2021-05-01T00:00:00", "value": 2}
]
},
"transform": [
{ "calculate": "max(datum.value)+1","as": "domMax"}
],
"mark": "line",
"encoding": {
"x": {
"field": "date",
"type": "temporal"
},
"y": {"field": "value", "type": "quantitative",
"scale": {"domainMax": {"expr": "domMax"}}
}
}
}
This transform
"transform": [
{ "calculate": "max(datum.value)+1","as": "domMax"}
]
adds a new column to your data set - it does not create a new signal. You can check that in the editor. Go to the DataViewer tab and select data_0 from the drop down. Can you see the new domMax column?
Signals are a different thing entirely - have a look here in the documentation. Note that the link points to Vega, not Vega-Lite. (Vega-Lite specifications are compiled to Vega.)
Vega-Lite does not let you declare signals; you declare parameters instead. Here is another example using the domMax parameter. Vega-Lite parameters are translated to Vega signals.
It looks like you are trying to derive the value of your parameter/signal from the data. I am not sure you can do that in Vega-Lite.
On the other hand it's very easy in Vega. For example you could use the extent transform:
https://vega.github.io/vega/docs/transforms/extent/
Side comment - while Vega specifications are more verbose you can sometimes find their primitives simpler and a good way to understand how the visualisation works. (You can see compiled Vega in the editor.)
I tried to get a custom domain based on the data but hit the same limitations as you did.
In my case, I update the data from the outside a bit like the streaming example. I compute the domain from the outside and modify them in the visualization with params. This is quite easy as vega-lite params are exposed as vega signals.
This is the gist of the layout:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"params": [
{
"name": "lowBound",
"value": -10
},
{
"name": "highBound",
"value": 100
}
],
../..
"vconcat": [
{
"name": "detailed",
../..
"layer": [
{
../..
"mark": "line",
"encoding": {
"y": {
"field": "value",
"title": "Temperature",
"type": "quantitative",
"scale": {
"domainMin": {
"expr": "lowBound"
},
"domainMax": {
"expr": "highBound"
}
}
},
...
The lowBound and highBound are dynamically changed through vega signals. I change them with the regular JS API.
You can add a param to pan and zoom in case your hard coded values are less than ideal.
"params": [{"name": "grid", "select": "interval", "bind": "scales"}],
Open the Chart in the Vega Editor

Vega lite: How to change value labels

I could not found out way how to change labels of X axis.
I have this data and I need to show bars which have title taken from field label. Currently bars are aggregated by id and goals is to label bars with label even if the texts are same. I'm confused by examples what to do. Whether I should create layer or some signals. Could someone help me? IMHO this should be trivial, but I did not found anything useful.
{
"id": 15971,
"label": "Click Next to continue",
"result": "Success",
"value": 2
},
{
"id": 15972,
"label": "Click Next to continue",
"result": "No data",
"value": 0
},
There's not really any way to do this in the Vega-Lite grammar, because what you want to do is semantically inconsistent: if you group values by one column, there is no guarantee that the values in another column will match within that grouping.
One option you have is to use labelExpr to define the desired label manually, e.g.
"x": {
"field": "id",
"type": "nominal",
"axis": {"title": "x", "labelExpr": "'Click Next to continue'"},
"scale": {"type": "point"}
},

Vega-lite - Change position of binding inputs

I was looking for a way to change the position of binding inputs. In the attached vega-lite chart, am having 2 select dropdown which are one below another and they are displayed at the bottom of the view. Is there any configuration available which allows to show the 2 dropdowns side by side when they are displayed below or can they be displayed on the right or left side of chart view just like legends.
Refer the below configurations or editor:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "A bar chart of flight statistics, aggregated by the selected time unit.",
"height": "container",
"width": "container",
"params": [
{
"name": "timeunit",
"value": ["day"],
"bind": {
"input": "select",
"options": [["year"], ["month"], ["date"], ["day"], ["hours"]]
}
},
{
"name": "measure",
"value": "delay",
"bind": {"input": "select", "options": ["count", "delay"]}
}
],
"data": {"url": "data/flights-20k.json"},
"transform": [
{
"calculate": "timeFormat(datetime(datum.date), timeUnitSpecifier([timeunit]))",
"as": "formattedDate"
}
],
"mark": "bar",
"encoding": {
"x": {"field": "formattedDate"},
"y": {"field": "delay", "type": "quantitative", "stack": false}
},
"config": {}
}
AFAIK there is no way to specify the position of binding inputs using the vega-lite spec. However you could always use CSS.
The HTML generated by vega-lite lends itself to a variety of styling options. There is a parent <div> element which contains the graph element (<svg> or <canvas>), and, if binding inputs are present, a sibling element <form class="vega-bindings">.
To position the two inputs side by side, the bare minimum CSS could be:
.vega-bindings {
display: flex;
}
To achieve something more aesthetically pleasing, you would need to do some additional styling. But this should be relatively simple depending on your skill with CSS.
Or, if you wanted to place the inputs on the right side similar to a legend, you might start with this:
div#my-parent-element {
display: flex;
}
Again, further styling would be needed depending on the level of polish desired, and the particulars of your design.

Embed Vega-Lite Diagrams in Antora

I'm trying to embed this vega-lite diagram in my antora docs: https://vega.github.io/vega-lite/examples/line_overlay.html
My Asciidoc file looks like this:
... some text ...
== Attachments
[vegalite, rendered-vega-image, svg]
----
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Stock prices of 5 Tech Companies over Time.",
"data": {"url": "data/stocks.csv"},
"mark": {
"type": "line",
"point": true
},
"encoding": {
"x": {"timeUnit": "year", "field": "date"},
"y": {"aggregate":"mean", "field": "price", "type": "quantitative"},
"color": {"field": "symbol", "type": "nominal"}
}
}
----
... some more text ...
The problem is the CSV file containing my data is not found. I tried every path I imagined ... relative and absolute filesystem paths and relativ and absolute http urls. Still I always get this message:
[DONE] build ui bundle
Skipping vegalite block. No such file: http://localhost:8080/vegalite/svg/eNpVkEFywyAMRfc5BcN0mdibdpNtj9D0AAQrWA0gArKnnozvXoHbpl0Zv9F_X3DfKaWfih0hGH1UemRO5dj3MzjTOeRxOndI_TbQ6MEjQz8_dx-Fot7X_ADFZkyMAsTxxmSvKmW0UBRd1Is6gR3VK4VkIlY2Q1YnDNB95w3X8ruesq-Cu2E2dgwQuQyY1z5QRKaM0R08OVe_GRJlllNfal3pbJn12nTB5GvVyVn-eElQpR4jtDphiTCyQM4TCNliEC0NInxEP9tSLIu-S3-VLGCy3it9QfBDBbI6bLUyv7R541yWdxJ-1AFM_DffXqWSn7Vuk4mMbBjnh8iSp9xkv8GyhDP5v8lIAaPxeq032K1fIi6OZQ==
[DONE] build docs
The Skipping vegalite block should not appear.
I tried vega-lite with data which is defined directly in the json block. This snippet works. So Vega-Lite in general works (I'm using a Kroki Server for diagram generation).
[vegalite, rendered-vega-image, svg]
----
{
"description": "A simple bar chart with embedded data.",
"data": {
"values": [
{"a": "A","b": 28}, {"a": "B","b": 55}, {"a": "C","b": 43},
{"a": "D","b": 91}, {"a": "E","b": 81}, {"a": "F","b": 53},
{"a": "G","b": 19}, {"a": "H","b": 87}, {"a": "I","b": 52}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "a", "type": "ordinal"},
"y": {"field": "b", "type": "quantitative"}
}
}
----
Defining my data directly inside the diagram definition is not a solution for me. Right now I'm just trying to make it work using the demo-CSV file. But afterwards I will switch to my own autogenerated, large CSV file. Both my real CSV and the Demo File are located in docs/modules/technical-docs/assets/attachments/monitoring-logging-reporting/stocks.csv.
My general setup consists of several projects.
Project containing the antora playbook und shell-script to generate my docs on my localhost
Project containing Asciidoc, the CSV files and a bunch of other docs and source code
Several other projects containing asciidoc docs which are not relevant for the problem at hand.
Anyone got any thougts? Thanks for yout help.
Kroki provides security levels that restrict access to files on the file system and on the network. Each level includes the restrictions enabled in the prior security level:
UNSAFE: disables any security features.
SAFE: Assume the diagram libraries secure mode request sanitization is sufficient.
SECURE: prevents attempts to read files from the file system or from the network.
By default, Kroki is running in SECURE mode.
As a result, "data": {"url": "data/stocks.csv"} will be removed/ignored.
If you are using Asciidoctor Kroki, the preprocessor should resolve the path, read the content and replace data.url with the actual values. See: https://github.com/Mogztter/asciidoctor-kroki
Alternatively, and since you are running a local instance of Kroki, you can use KROKI_SAFE_MODE=unsafe environment variable to configure the safe mode to unsafe.

Vega-lite default bar width strange

I'm seeing the following oddly styled chart. I understand I can explicitly change the padding etc., but the default vega-lite layout is usually pretty good. I'm confused what I'm doing that's leading to this sub-normal behavior. Thanks! Here is the code in the vega-lite editor
I understand that I can also change x's type to ordinal to make the styling better, though I'm not sure I understand still why it is the difference I see. I need the type to be quantitative so I get the min/max brush bound, as opposed to the set.
Also I actually do not even know how to manually set the bar width after reading the documentation here https://vega.github.io/vega-lite/docs/scale.html. If anyone might have a working example that would be great.
Thanks.
As #marcprux mentioned, there is pre-binned support so you don't have to repeat the bin transform here. However, currently the prebinned support requires both bin_start and bin_end.
For now you could modify the spec to derive a new bin_end field and use it with x2.
{
"data": ...
"transform": [{
"calculate": "datum.ShareWomen_bin+0.1",
"as": "ShareWomen_bin_end"
}],
"mark": "bar",
"encoding": {
"x": {"bin": {"binned": true, "step": 0.1}, "field": "ShareWomen_bin", "type": "quantitative", "title": "ShareWomen_bin"},
"x2": {"field": "ShareWomen_bin_end"},
"y": {"field": "count", "type": "quantitative"}
}
}
like this spec.
I can see that we shouldn't require deriving bin_end and thus have created an issue to track this feature request: https://github.com/vega/vega-lite/issues/6086.
Btw, the quantitative scale only affects the bar position.
To set the bar size directly, you can use size property in a mark definition:
mark: {type: "bar", size: 5}
Since you declare "x" as a quantitative field, there's no assumption that the points along the axis are evenly distributed. E.g., you could add in some data points in between the others:
{"ShareWomen_bin": 0.83, "count": 40, "is_overview": true},
{"ShareWomen_bin": 0.87, "count": 70, "is_overview": true},
and you would see them rendered in between the other bars:
As you mention, you can specify that the bars should be encoded as ordinal values. Another solution is to leave it as quantitative, but specify that it is binned, in which case the bars will also be rendered as if they were ordinal:
"x": {"field": "ShareWomen_bin", "type": "quantitative", "bin": true},
Since it appears that your data is already binned, you should read about how vega-lite supports pre-binned data: https://vega.github.io/vega-lite/docs/bin.html#binned