Skip to content

Commit

Permalink
Support threshold aggregation example (#436)
Browse files Browse the repository at this point in the history
* Support threshold aggregation example

* Update expected comm plans
  • Loading branch information
jonmmease authored Dec 16, 2023
1 parent 7403f02 commit ddc14af
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 11 deletions.
3 changes: 2 additions & 1 deletion vegafusion-core/src/planning/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ impl<'a> MutChartVisitor for ExtractServerDependenciesVisitor<'a> {
let scoped_signal_var = (Variable::new_signal(&signal.name), Vec::from(scope));
if self.supported_vars.contains_key(&scoped_signal_var) {
// Move signal to server
let server_signal = signal.clone();
let mut server_signal = signal.clone();
server_signal.bind = None;
if scope.is_empty() {
self.server_spec.signals.push(server_signal)
} else {
Expand Down
1 change: 1 addition & 0 deletions vegafusion-core/src/planning/stitch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ fn make_stub(
update: None,
value: MissingNullOrValue::from(stub_value),
on: vec![],
bind: None,
extra: Default::default(),
};

Expand Down
3 changes: 3 additions & 0 deletions vegafusion-core/src/spec/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ pub struct SignalSpec {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub on: Vec<SignalOnSpec>,

#[serde(skip_serializing_if = "Option::is_none")]
pub bind: Option<Value>,

#[serde(flatten)]
pub extra: HashMap<String, Value>,
}
Expand Down
4 changes: 2 additions & 2 deletions vegafusion-core/src/spec/visitors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,9 @@ impl<'a> ChartVisitor for UpdateVarsChartVisitor<'a> {

fn visit_signal(&mut self, signal: &SignalSpec, scope: &[u32]) -> Result<()> {
// Signal is an update variable if it's not an empty stub
if signal.value.as_option().is_some()
|| signal.init.is_some()
if signal.init.is_some()
|| signal.update.is_some()
|| signal.bind.is_some()
|| !signal.on.is_empty()
{
self.update_vars
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"server_to_client": [
{
"namespace": "signal",
"name": "layer_1_bin_maxbins_10_IMDB_Rating_bins",
"scope": []
},
{
"namespace": "signal",
"name": "layer_1_bin_maxbins_10_Rotten_Tomatoes_Rating_bins",
"scope": []
},
{
"namespace": "data",
"name": "data_0",
"scope": []
},
{
"namespace": "data",
"name": "data_1",
"scope": []
},
{
"namespace": "data",
"name": "empty",
"scope": []
}
],
"client_to_server": [
{
"namespace": "signal",
"name": "param_5",
"scope": []
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[
[
{
"namespace": "signal",
"name": "param_5",
"scope": [],
"value": 3.5
}
],
[
{
"namespace": "signal",
"name": "param_5",
"scope": [],
"value": 6.3
}
]
]
267 changes: 267 additions & 0 deletions vegafusion-runtime/tests/specs/custom/aggregate_with_threshold.vg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"background": "white",
"padding": 5,
"width": 300,
"height": 300,
"style": "cell",
"data": [
{
"name": "source_0",
"url": "https://cdn.jsdelivr.net/npm/vega-datasets@v1.29.0/data/movies.json",
"format": {"type": "json"}
},
{"name": "empty", "values": [{}]},
{
"name": "data_0",
"source": "source_0",
"transform": [
{"type": "filter", "expr": "(datum['IMDB_Rating'] >= param_5)"},
{
"type": "filter",
"expr": "isValid(datum[\"IMDB_Rating\"]) && isFinite(+datum[\"IMDB_Rating\"]) && isValid(datum[\"Rotten_Tomatoes_Rating\"]) && isFinite(+datum[\"Rotten_Tomatoes_Rating\"])"
}
]
},
{
"name": "data_1",
"source": "source_0",
"transform": [
{
"type": "extent",
"field": "IMDB_Rating",
"signal": "layer_1_bin_maxbins_10_IMDB_Rating_extent"
},
{
"type": "bin",
"field": "IMDB_Rating",
"as": [
"bin_maxbins_10_IMDB_Rating",
"bin_maxbins_10_IMDB_Rating_end"
],
"signal": "layer_1_bin_maxbins_10_IMDB_Rating_bins",
"extent": {"signal": "layer_1_bin_maxbins_10_IMDB_Rating_extent"},
"maxbins": 10
},
{
"type": "extent",
"field": "Rotten_Tomatoes_Rating",
"signal": "layer_1_bin_maxbins_10_Rotten_Tomatoes_Rating_extent"
},
{
"type": "bin",
"field": "Rotten_Tomatoes_Rating",
"as": [
"bin_maxbins_10_Rotten_Tomatoes_Rating",
"bin_maxbins_10_Rotten_Tomatoes_Rating_end"
],
"signal": "layer_1_bin_maxbins_10_Rotten_Tomatoes_Rating_bins",
"extent": {
"signal": "layer_1_bin_maxbins_10_Rotten_Tomatoes_Rating_extent"
},
"maxbins": 10
},
{"type": "filter", "expr": "(datum['IMDB_Rating'] < param_5)"},
{
"type": "aggregate",
"groupby": [
"bin_maxbins_10_IMDB_Rating",
"bin_maxbins_10_IMDB_Rating_end",
"bin_maxbins_10_Rotten_Tomatoes_Rating",
"bin_maxbins_10_Rotten_Tomatoes_Rating_end"
],
"ops": ["count"],
"fields": [null],
"as": ["__count"]
},
{
"type": "filter",
"expr": "isValid(datum[\"bin_maxbins_10_IMDB_Rating\"]) && isFinite(+datum[\"bin_maxbins_10_IMDB_Rating\"]) && isValid(datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"]) && isFinite(+datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"])"
}
]
}
],
"signals": [
{
"name": "param_5",
"value": 5,
"bind": {
"input": "range",
"max": 10,
"min": 0,
"name": "threshold",
"step": 0.1
}
}
],
"marks": [
{
"name": "layer_0_marks",
"type": "symbol",
"style": ["circle"],
"from": {"data": "data_0"},
"encode": {
"update": {
"opacity": {"value": 0.7},
"fill": {"value": "#4c78a8"},
"ariaRoleDescription": {"value": "circle"},
"description": {
"signal": "\"IMDB Rating: \" + (format(datum[\"IMDB_Rating\"], \"\")) + \"; Rotten Tomatoes Rating: \" + (format(datum[\"Rotten_Tomatoes_Rating\"], \"\"))"
},
"x": {"scale": "x", "field": "IMDB_Rating"},
"y": {"scale": "y", "field": "Rotten_Tomatoes_Rating"},
"shape": {"value": "circle"}
}
}
},
{
"name": "layer_1_marks",
"type": "symbol",
"style": ["circle"],
"from": {"data": "data_1"},
"encode": {
"update": {
"fill": {"value": "#4c78a8"},
"ariaRoleDescription": {"value": "circle"},
"description": {
"signal": "\"IMDB_Rating (binned): \" + (!isValid(datum[\"bin_maxbins_10_IMDB_Rating\"]) || !isFinite(+datum[\"bin_maxbins_10_IMDB_Rating\"]) ? \"null\" : format(datum[\"bin_maxbins_10_IMDB_Rating\"], \"\") + \"\" + format(datum[\"bin_maxbins_10_IMDB_Rating_end\"], \"\")) + \"; Rotten_Tomatoes_Rating (binned): \" + (!isValid(datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"]) || !isFinite(+datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"]) ? \"null\" : format(datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"], \"\") + \"\" + format(datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating_end\"], \"\")) + \"; Count of Records: \" + (format(datum[\"__count\"], \"\"))"
},
"x": {
"signal": "scale(\"x\", 0.5 * datum[\"bin_maxbins_10_IMDB_Rating\"] + 0.5 * datum[\"bin_maxbins_10_IMDB_Rating_end\"])"
},
"y": {
"signal": "scale(\"y\", 0.5 * datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating\"] + 0.5 * datum[\"bin_maxbins_10_Rotten_Tomatoes_Rating_end\"])"
},
"size": {"scale": "size", "field": "__count"},
"shape": {"value": "circle"}
}
}
},
{
"name": "layer_2_marks",
"type": "rule",
"style": ["rule"],
"from": {"data": "empty"},
"encode": {
"update": {
"stroke": {"value": "gray"},
"strokeWidth": {"value": 6},
"x": {"scale": "x", "signal": "param_5"},
"y": {"value": 0},
"y2": {"field": {"group": "height"}}
}
}
}
],
"scales": [
{
"name": "x",
"type": "linear",
"domain": {
"fields": [
{"data": "data_0", "field": "IMDB_Rating"},
{
"signal": "[layer_1_bin_maxbins_10_IMDB_Rating_bins.start, layer_1_bin_maxbins_10_IMDB_Rating_bins.stop]"
},
[{"expr": "param_5"}]
]
},
"range": [0, {"signal": "width"}],
"bins": {"signal": "layer_1_bin_maxbins_10_IMDB_Rating_bins"},
"nice": true,
"zero": true
},
{
"name": "y",
"type": "linear",
"domain": {
"fields": [
{"data": "data_0", "field": "Rotten_Tomatoes_Rating"},
{
"signal": "[layer_1_bin_maxbins_10_Rotten_Tomatoes_Rating_bins.start, layer_1_bin_maxbins_10_Rotten_Tomatoes_Rating_bins.stop]"
}
]
},
"range": [{"signal": "height"}, 0],
"bins": {"signal": "layer_1_bin_maxbins_10_Rotten_Tomatoes_Rating_bins"},
"nice": true,
"zero": true
},
{
"name": "size",
"type": "linear",
"domain": [0, 160],
"range": [
0,
{
"signal": "pow(0.95 * min(width / ((layer_1_bin_maxbins_10_IMDB_Rating_bins.stop - layer_1_bin_maxbins_10_IMDB_Rating_bins.start) / layer_1_bin_maxbins_10_IMDB_Rating_bins.step), height / ((layer_1_bin_maxbins_10_Rotten_Tomatoes_Rating_bins.stop - layer_1_bin_maxbins_10_Rotten_Tomatoes_Rating_bins.start) / layer_1_bin_maxbins_10_Rotten_Tomatoes_Rating_bins.step)), 2)"
}
],
"zero": true
}
],
"axes": [
{
"scale": "x",
"orient": "bottom",
"gridScale": "y",
"grid": true,
"tickCount": {"signal": "ceil(width/40)"},
"domain": false,
"labels": false,
"aria": false,
"maxExtent": 0,
"minExtent": 0,
"ticks": false,
"zindex": 0
},
{
"scale": "y",
"orient": "left",
"gridScale": "x",
"grid": true,
"tickCount": {"signal": "ceil(height/40)"},
"domain": false,
"labels": false,
"aria": false,
"maxExtent": 0,
"minExtent": 0,
"ticks": false,
"zindex": 0
},
{
"scale": "x",
"orient": "bottom",
"grid": false,
"title": "IMDB Rating",
"labelFlush": true,
"labelOverlap": true,
"tickCount": {"signal": "ceil(width/40)"},
"zindex": 0
},
{
"scale": "y",
"orient": "left",
"grid": false,
"title": "Rotten Tomatoes Rating",
"labelOverlap": true,
"tickCount": {"signal": "ceil(height/40)"},
"zindex": 0
}
],
"legends": [
{
"size": "size",
"symbolType": "circle",
"title": "Count of Records",
"encode": {
"symbols": {
"update": {
"fill": {"value": "#4c78a8"},
"stroke": {"value": "transparent"}
}
}
}
}
]
}
5 changes: 0 additions & 5 deletions vegafusion-runtime/tests/specs/vega/jobs.comm_plan.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@
"name": "query",
"scope": []
},
{
"namespace": "signal",
"name": "sex",
"scope": []
},
{
"namespace": "data",
"name": "_server_jobs",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,11 @@
"scope": []
}
],
"client_to_server": []
"client_to_server": [
{
"namespace": "signal",
"name": "columns",
"scope": []
}
]
}
Loading

0 comments on commit ddc14af

Please sign in to comment.