Related
To get to know how events work in VEGA, I gave myself the simple exercice to render a dot and a text positioned on the cursors coordinates in a given view.
I managed to make a symbol follow the mouse coordinates, yet when I try to make two types of marks ( text and symbol) follow the mouse , it doesn't render them both but the first one appearing in the marks [ ] array.
Any ideas ?
Following specification is used in the exercice :
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 600,
"height": 600,
"signals": [
{
"name": "position",
"on": [
{
"events": {
"type": "mousemove"
},
"update": "xy()"
}
]
},
{
"name": "positionDot",
"on": [
{
"events": {
"type": "mousemove"
},
"update": "xy()"
}
]
}
],
"marks": [
{
"type": "text",
"encode": {
"enter": {
"fill": {
"value": "#000"
},
"text": {
"value": "Text Label"
}
},
"update": {
"opacity": {
"value": 1
},
"x": {
"signal": "position[0]+20"
},
"y": {
"signal": "position[1]+20"
},
"fontSize": {
"value": 50
}
}
}
},
{
"name": "dot",
"type": "symbol",
"encode": {
"enter": {
"fill": {
"value": "#939597"
},
"stroke": {
"value": "#652c90"
},
"x": {
"value": 0
},
"y": {
"value": 0
}
},
"update": {
"x": {
"signal": "positionDot[0]"
},
"y": {
"signal": "position[1]"
},
"size": {
"value": 550
},
"opacity": {
"value": 1
}
},
"hover": {
"opacity": {
"value": 0.5
}
}
}
}
]
}
https://vega.github.io/editor/#/gist/1dcd1034a1d8139b3de49f041ed1ed4b/spec.json
Your example works as expected if an initial value (using "init" or "value") is included in signal position:
"signals": [
{
"name": "position",
"init": [0, 0],
"on": [
{
"events": {
"type": "mousemove"
},
"update": "xy()"
}
]
},
View in Vega online editor
When add the strips as a new layer (in the 2-layers chart), stops to work: there are no visualization and a "WARN Cannot project a selection on encoding channel "y", which has no field".
The first two layer-definitions bellow was working fine when only two lines.
vglSpec.push(['#vis2a',{
$schema: vglVers,
data: {"url":"MyDataset1"},
// old "encoding": { x: {"field": "instant", "type": "temporal"} }
width:680,
layer: [
{
"mark": {"stroke": "#68C", "type": "line", "point": true},
"encoding": { x: {"field": "instant", "type": "temporal"}, "y": {
"field": "n_count",
"type": "quantitative"
}},
"selection": {"grid": {"type":"interval", "bind":"scales"}} //zoom
},
{
"mark": {"stroke": "red", "type": "line", "strokeOpacity": 0.4},
"encoding": { x: {"field": "instant", "type": "temporal"}, "y": {
"field": "instant_totmin",
"type": "quantitative"
}}
},
{
"mark": "rule",
"data": {"url":"MyDataset2"}, // little subset of instant of Dataset1
"encoding": {
"x": { "field": "instant", "type": "temporal"},
"color": {"value": "yellow"},
"size": {"value": 5}
},
//resolve:? x is same axis and the only visualization field
}
],
resolve: {"scale": {"y": "independent"}}
}]);
PS: only removed names and titles, all real script.
Emulating with dummy data: working fine!
Please click on the 3rd example of rule guide... And replace or adapt it for this VEGA-lite script:
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"data": {"url": "data/movies.json"},
"layer": [
{
"mark": "bar",
"encoding": {
"x": {"bin": true, "field": "IMDB_Rating", "type": "quantitative"},
"y": {"aggregate": "count", "type": "quantitative"}
}
},
{
"mark": "rule",
"data": {"values": [{"IMDB_Rating":3.5},{"IMDB_Rating":7.8}]},
"encoding": {
"x": { "field": "IMDB_Rating","type": "quantitative" },
"color": {"value": "yellow"},
"size": {"value": 4}
}
}
]
}
You're using an independent y-scale, and the y-scale of a rule mark with no y encoding is not well defined. The best way to address this is probably to combine the rule mark with one of the other layers, so it can use that y scale:
vglSpec.push(['#vis2a',{
$schema: vglVers,
data: {"url":"MyDataset1"},
// old "encoding": { x: {"field": "instant", "type": "temporal"} }
width:680,
layer: [
{
"mark": {"stroke": "#68C", "type": "line", "point": true},
"encoding": { x: {"field": "instant", "type": "temporal"}, "y": {
"field": "n_count",
"type": "quantitative"
}},
"selection": {"grid": {"type":"interval", "bind":"scales"}} //zoom
},
{
layer: [
{
"mark": {"stroke": "red", "type": "line", "strokeOpacity": 0.4},
"encoding": { x: {"field": "instant", "type": "temporal"}, "y": {
"field": "instant_totmin",
"type": "quantitative"
}}
},
{
"mark": "rule",
"data": {"url":"MyDataset2"}, // little subset of instant of Dataset1
"encoding": {
"x": { "field": "instant", "type": "temporal"},
"color": {"value": "yellow"},
"size": {"value": 5}
},
//resolve:? x is same axis and the only visualization field
}
]
}
],
resolve: {"scale": {"y": "independent"}}
}]);
(note, I've not actually tried this solution because you didn't include data in your question, but the approach should work).
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
},
...
]
}
}
I'd like to group axes and marks together within a group mark, as I'd like a bar chart to be one of several onto the data. However, when I do so the x axis moved from the bottom to the top of the bar chart. Here's an example:
{
"$schema": "https://vega.github.io/schema/vega/v4.json",
"width": 400,
"height": 200,
"padding": 5,
"data": [
{
"name": "cars",
"format": {
"type": "json",
"parse": {
"year": "date"
}
},
"url": "https://vega.github.io/vega-datasets/data/cars.json",
"transform": [
{
"type": "aggregate",
"groupby": [
"Origin"
],
"as": [
"num_records"
]
}
]
}
],
"scales": [
{
"name": "x",
"type": "band",
"domain": {
"data": "cars",
"field": "Origin"
},
"range": "width",
"padding": 0.05
},
{
"name": "y",
"type": "linear",
"domain": {
"data": "cars",
"field": "num_records"
},
"range": "height",
"nice": true
}
],
"marks": [
{
"type": "group",
"axes": [
{
"orient": "bottom",
"scale": "x"
},
{
"orient": "left",
"scale": "y"
}
],
"marks": [
{
"type": "rect",
"from": {
"data": "cars"
},
"encode": {
"enter": {
"x": {
"scale": "x",
"field": "Origin"
},
"width": {
"scale": "x",
"band": 1
},
"y": {
"scale": "y",
"field": "num_records"
},
"y2": {
"scale": "y",
"value": 0
}
}
}
}
]
}
]
}
The Group Mark documentation suggests that groups support such nested visualisation specifications. What am I doing wrong?
What I was doing wrong was not encoding the width and height of the group mark. Here's my revised example:
{
"$schema": "https://vega.github.io/schema/vega/v4.json",
"width": 400,
"height": 200,
"padding": 5,
"data": [
{
"name": "cars",
"format": {
"type": "json",
"parse": {
"year": "date"
}
},
"url": "https://vega.github.io/vega-datasets/data/cars.json",
"transform": [
{
"type": "aggregate",
"groupby": [
"Origin"
],
"as": [
"num_records"
]
}
]
}
],
"scales": [
{
"name": "x",
"type": "band",
"domain": {
"data": "cars",
"field": "Origin"
},
"range": "width",
"padding": 0.05
},
{
"name": "y",
"type": "linear",
"domain": {
"data": "cars",
"field": "num_records"
},
"range": "height",
"nice": true
}
],
"marks": [
{
"type": "group",
"axes": [
{
"orient": "bottom",
"scale": "x"
},
{
"orient": "left",
"scale": "y"
}
],
"encode": {
"enter": {
"width": {
"signal": "width"
},
"height": {
"signal": "height"
}
}
},
"marks": [
{
"type": "rect",
"from": {
"data": "cars"
},
"encode": {
"enter": {
"x": {
"scale": "x",
"field": "Origin"
},
"width": {
"scale": "x",
"band": 1
},
"y": {
"scale": "y",
"field": "num_records"
},
"y2": {
"scale": "y",
"value": 0
}
}
}
}
]
}
]
}
I'm working with vega charts (parallel coordinates). How do I change the color of the lines with respect to scheme colors (w.r.t 'name' field).
Here is my code
I tried changing the stroke property with color scale but there is no effect on line stroke.
Can anyone point out what am I doing wrong.
I'm using Vega Version 4
Thanks
vikky
Because the colors need to be by column "name", transform the input dataset to have repeated name rows. In other words, input dataset must be of 3 columns (name, quarter, value)
Then, change "group" type mark to use facet dataset grouped by column "name"
"name": "marks_group_lines",
"type": "group",
"from": {
"facet": {
"name": "cars_by_name",
"data": "cars",
"groupby": "name"
}
},
Use the cars_by_name as dataset to render "line" type mark.
tip: Instead of defining quarter dataset for 4 axes for each qarter and scales for these axes, "line" type mark which has point scale for "x" property can be used.
Full code for reference:
{
"$schema": "https://vega.github.io/schema/vega/v4.json",
"width": 700,
"height": 400,
"padding": 5,
"config": {
"axisY": {
"titleX": -2,
"titleY": 410,
"titleAngle": 0,
"titleAlign": "right",
"titleBaseline": "top"
}
},
"data": [
{
"name": "cars",
"values": [
{
"name": "A",
"quarter": "Q1",
"value": 51
},
{
"name": "A",
"quarter": "Q2",
"value": 47
},
{
"name": "A",
"quarter": "Q3",
"value": 45
},
{
"name": "A",
"quarter": "Q4",
"value": 30
},
{
"name": "B",
"quarter": "Q1",
"value": 42
},
{
"name": "B",
"quarter": "Q2",
"value": 57
},
{
"name": "B",
"quarter": "Q3",
"value": 72
},
{
"name": "B",
"quarter": "Q4",
"value": 41
},
{
"name": "C",
"quarter": "Q1",
"value": 25
},
{
"name": "C",
"quarter": "Q2",
"value": 37
},
{
"name": "C",
"quarter": "Q3",
"value": 60
},
{
"name": "C",
"quarter": "Q4",
"value": 25
},
{
"name": "D",
"quarter": "Q1",
"value": 22
},
{
"name": "D",
"quarter": "Q2",
"value": 25
},
{
"name": "D",
"quarter": "Q3",
"value": 51
},
{
"name": "D",
"quarter": "Q4",
"value": 42
}
]
},
{
"name": "fields",
"values": [
"Q1",
"Q2",
"Q3",
"Q4"
]
}
],
"scales": [
{
"name": "name_to_xaxis",
"type": "point",
"domain": {
"data": "cars",
"field": "quarter"
},
"range": "width"
},
{
"name": "values_to_height",
"type": "linear",
"domain": {
"data": "cars",
"field": "value"
},
"range": "height"
},
{
"name": "quarter_to_color",
"type": "ordinal",
"domain": {
"data": "cars",
"field": "name"
},
"range": "category"
},
{
"name": "ord",
"type": "point",
"range": "width",
"round": true,
"domain": {
"data": "fields",
"field": "data"
}
},
{
"name": "Q1",
"type": "linear",
"range": "height",
"zero": false,
"nice": true,
"domain": {
"data": "cars",
"field": "Q1"
}
},
{
"name": "Q2",
"type": "linear",
"range": "height",
"zero": false,
"nice": true,
"domain": {
"data": "cars",
"field": "Q2"
}
},
{
"name": "Q3",
"type": "linear",
"range": "height",
"zero": false,
"nice": true,
"domain": {
"data": "cars",
"field": "Q3"
}
},
{
"name": "Q4",
"type": "linear",
"range": "height",
"zero": false,
"nice": true,
"domain": {
"data": "cars",
"field": "Q4"
}
}
],
"axes": [
{
"orient": "left",
"zindex": 1,
"scale": "Q1",
"title": "Q1",
"ticks": false,
"labels": false,
"offset": {
"scale": "ord",
"value": "Q1",
"mult": -1
}
},
{
"orient": "left",
"zindex": 1,
"scale": "Q2",
"title": "Q2",
"ticks": false,
"labels": false,
"offset": {
"scale": "ord",
"value": "Q2",
"mult": -1
}
},
{
"orient": "left",
"zindex": 1,
"scale": "Q3",
"title": "Q3",
"ticks": false,
"labels": false,
"offset": {
"scale": "ord",
"value": "Q3",
"mult": -1
}
},
{
"orient": "left",
"zindex": 1,
"scale": "Q4",
"title": "Q4",
"ticks": false,
"labels": false,
"offset": {
"scale": "ord",
"value": "Q4",
"mult": -1
}
}
],
"marks": [
{
"name": "marks_group_lines",
"type": "group",
"from": {
"facet": {
"name": "cars_by_name",
"data": "cars",
"groupby": "name"
}
},
"marks": [
{
"name": "marks_lines",
"type": "line",
"from": {
"data": "cars_by_name"
},
"encode": {
"update": {
"x": {
"scale": "name_to_xaxis",
"field": "quarter"
},
"y": {
"scale": "values_to_height",
"field": "value"
},
"stroke": {
"scale": "quarter_to_color",
"field": "name"
},
"strokeOpacity": {
"value": 1
}
},
"hover": {
"stroke": {
"value": "#7c7c7c"
},
"strokeOpacity": {
"value": 1
},
"zindex": 99
}
}
},
{
"name": "marks_symbols",
"type": "symbol",
"from": {
"data": "cars_by_name"
},
"encode": {
"enter": {
"stroke": {
"value": "#6D6D6D"
},
"strokeWidth": {
"value": 1
},
"shape": {
"value": "circle"
}
},
"update": {
"x": {
"scale": "name_to_xaxis",
"field": "quarter"
},
"y": {
"scale": "values_to_height",
"field": "value"
},
"fill": {
"scale": "quarter_to_color",
"field": "name"
},
"size": {
"value": 50
},
"stroke": {
"value": "#77AE80"
}
},
"hover": {
"fill": {
"value": "#AFD098"
}
}
}
}
]
}
]
}