Skip to content

Instantly share code, notes, and snippets.

@Giammaria
Created February 28, 2025 21:44
Show Gist options
  • Save Giammaria/86df0bf46a5d4735dce503c71564cc8d to your computer and use it in GitHub Desktop.
Save Giammaria/86df0bf46a5d4735dce503c71564cc8d to your computer and use it in GitHub Desktop.
20250228_lasso_example_v1_v
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"padding": 0,
"signals": [
{"name": "width", "update": "windowSize()[0]*0.5"},
{"name": "height", "update": "windowSize()[1]*0.5"},
{
"name": "lassoCoordinates",
"init": "null",
"on": [
{
"events": "[mousedown, mouseup] > mousemove{25, 5}",
"update": "{x: x(group()), y: y(group()), timestamp: now(), start: isValid(lassoCoordinates) ? lassoCoordinates.start : now(), end: now(), mousedown: true}"
},
{
"events": "mouseup",
"update": "!isValid(lassoCoordinates) ? null : {x: lassoCoordinates.x, y: lassoCoordinates.y, timestamp: lassoCoordinates.timestamp, start: lassoCoordinates.start, end: lassoCoordinates.end, mousedown: false}"
},
{"events": "mousedown", "update": "null"}
]
},
{
"name": "selectionBounds",
"init": "null",
"on": [
{
"events": {"signal": "data('lasso')"},
"update": "isValid(data('lasso')) && length(data('lasso')) === 1 ? {x: [data('lasso')[0].x, data('lasso')[0].x2], y: [data('lasso')[0].y, data('lasso')[0].y2]} : null"
}
]
},
{
"name": "lassoStrokeDashOffset",
"value": 0,
"on": [
{
"events": {"type": "timer", "throttle": 50},
"update": "lassoStrokeDashOffset-1"
}
]
}
],
"marks": [
{
"name": "text-dummy",
"type": "text",
"encode": {
"update": {
"text": {"value": "Lasso"},
"x": {"signal": "width/2"},
"y": {"signal": "height/2"},
"font": {"value": "consolas"},
"fontSize": {"value": 100},
"align": {"value": "center"},
"baseline": {"value": "middle"},
"fill": {"value": "red"},
"fillOpacity": {"signal": "0"}
}
}
},
{
"name": "text",
"type": "text",
"from": {"data": "text-dummy"},
"encode": {
"update": {
"text": {"field": "text"},
"x": {"field": "x"},
"y": {"field": "y"},
"font": {"field": "font"},
"fontSize": {"field": "fontSize"},
"align": {"field": "align"},
"baseline": {"field": "baseline"},
"fillOpacity": {
"signal": "isValid(selectionBounds) && inrange(datum.bounds.x1, selectionBounds.x) && inrange(datum.bounds.x2, selectionBounds.x) && inrange(datum.bounds.y1, selectionBounds.y) && inrange(datum.bounds.y2, selectionBounds.y) ? 1 : 0.25"
}
}
}
},
{
"name": "rect-lasso",
"type": "rect",
"from": {"data": "lasso"},
"encode": {
"update": {
"x": {"field": "x"},
"x2": {"field": "x2"},
"y": {"field": "y"},
"y2": {"field": "y2"},
"stroke": {"value": "#777"},
"strokeDash": {"value": [8, 2]},
"strokeDashOffset": {"signal": "lassoStrokeDashOffset"},
"strokeWidth": {"value": 0.25},
"fill": {"value": "steelblue"},
"cornerRadius": {"value": 2.5},
"fillOpacity": {
"signal": "isValid(lassoCoordinates) && lassoCoordinates.mousedown ? 0.05 : 0"
}
}
}
}
],
"data": [
{
"name": "lasso",
"on": [
{
"trigger": "lassoCoordinates",
"remove": false,
"insert": "lassoCoordinates"
}
],
"transform": [
{
"type": "joinaggregate",
"ops": ["max", "max"],
"fields": ["end", "start"],
"as": ["end", "mostRecentStart"]
},
{
"type": "window",
"ops": ["row_number"],
"sort": {"field": "timestamp", "order": "descending"},
"as": ["index"]
},
{"type": "filter", "expr": "isValid(lassoCoordinates)"},
{"type": "filter", "expr": "datum.start === datum.mostRecentStart"},
{
"type": "filter",
"expr": "datum.timestamp === datum.start || datum.index==1"
},
{
"type": "aggregate",
"groupby": ["start", "end"],
"fields": ["x", "x", "y", "y"],
"ops": ["min", "max", "min", "max"],
"as": ["x", "x2", "y", "y2"]
},
{"type": "project", "fields": ["x", "x2", "y", "y2"]}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment