Vega-lite: Signals in Vega-Lite

Created on 1 Feb 2018  Â·  32Comments  Â·  Source: vega/vega-lite

It would be great to have basic support for signals in Vega-Lite. This could be used to implement a rotating earth as in https://beta.observablehq.com/@domoritz/rotating-earth. Another example would be to define the colors of marks via a signal.

To implement this, we need to add signal support to the types and fix resulting bugs. Also, as we parse the spec, we need to collect signals and create definitions at the top.

While this is exciting, we want to be very careful about the design. We don't want to break abstractions or introduce multiple ways to do the same thing. @arvind suggest that we look into how we can extend single selections to support this use case.

Area - Interaction

Most helpful comment

To build off of the two use-cases, I see @domoritz' rotating-globe as being part of (a); there is some parameter that we want to make reactive - I would like to be able to do this more easily and robustly.

For case (b), I would like to be able to provide my own html inputs (such as the ones provided by Shiny) and bind them to selections, instead of Vega providing the input-element. I would like to be able to provide default values in the spec for such selections, so that I can design the chart without the input present.

Could it be possible to define a selection with a "bring your own input"? To push the question further, could we define a range selection where an input provides both the lower and upper end of a range?

In both scenarios, I assume that I would be responsible for accessing the view to update the signals (which is fine by me).

All 32 comments

I think we should definitely have a way to define the underlying signals in Vega for binding, but whether we call it signals – I'm not sure yet.

I'd motion for sticking with the vega precedent on this one, FWIW. The notion of signal in the FRP world is connected, so it resonates with me.

The notion of signal in the FRP world is connected, so it resonates with me.

Could you elaborate? I'm not sure I understand.

I'm not sure if we will have full-blown signal support throughout the language. (like that they can be used via expression like in Vega.)

A simpler and more common use cases to implement is for binding a property to a signal that can be bound. But if only support a subset, it's unclear if we want to name it similarly.

But if only support a subset, it's unclear if we want to name it similarly.

That makes sense. In general I support vega-lite encapsulating as much of the power of vega as it reasonably can without sacrificing simplicity, but I also recognize it's a challenging optimization problem, and commend you on your success. On that, I'd like to share that I've been a long time ggplot user, and had never found anything that matched it at its sweet spot, but vega-lite 2 now blows it out of the water as far as I'm concerned, so thank you for all your great work!

Could you elaborate? I'm not sure I understand.

In the Reactive Functional Programming world writ large, there is a pattern emerging around the notion of reactive signals. In Elm they're literally called signals, and I think Redux calls them signals as well. In Reagent (ClojureScript) they're called reactions, but we sometimes talk about them as signals abstractly. To the best of my understanding (as someone who is really just starting to dig in deeply) Vega's notion of a signal at least somewhat corresponds to that of FRP.

Vega's notion of a signal at least somewhat corresponds to that of FRP.

Absolutely! In fact, we wrote a paper about the reactive architecture behind Vega: https://idl.cs.washington.edu/files/2015-ReactiveVega-InfoVis.pdf.

Thanks @metasoarous! And yes, the use of signals in Vega (both the name and the semantics) was directly influenced by FRP!

+1 on signal support in vega-lite. that would be awesome.

Forgive the noob question, but in the meanwhile, couldn't I do my own poor man's implementation and just render my own signal controls, catch their events, and manually tweak the spec appropriately and then just re-parse? Could get ugly, I realize, but for simple stuff like hide/show a line on a multiline chart, this should be doable, right?

Yes, you could probably hack this. If you only want to switch between a few states, it probably makes sense to cache them.

Another option is to post-process the generated Vega with some code that changes the JSON spec.

This issue also counts for setting another field for coloring?
Like here: https://vega.github.io/vega-lite/docs/bind.html#input-element-binding
I can select the type within a field, but how to change the field (for example from Cylinder to Year) using a bind input select?

@mattijn I don't think we will implement this any time soon as we cannot dynamically change the scale (or scale type). You can achieve what you want by pivoting your data so that you have only two fields: "column" and "value".

Following the thread on Slack, here are some more thoughts about this:

Signals are simply reactive variables. They are commonly used to (a) declare parameters and calculate dependent parameters and (b) capture input events to trigger selections.

For the latter case, the selection abstraction serves the purpose quite well without requiring users to declare so many underlying signals.

However, selection is more than just reactive variables as it's dealing with an underlying data query (rather than just a simple scalar value that a parameter typically needs). Thus, selection is beyond what signal is for in the use case (a).

As discussed above, I didn't know if we want full-blown signals support and wondered if we need a higher-level primitives. However, introducing new primitives would also require a different wrapper APIs (like we need with selection). If we were to support this at all, I think we should just keep the name consistent.

Note that I'm not sure if (a) and (b) are exclusively the only two common use cases of signals.
Please feel free to comment on this thread if you have other use cases.

To build off of the two use-cases, I see @domoritz' rotating-globe as being part of (a); there is some parameter that we want to make reactive - I would like to be able to do this more easily and robustly.

For case (b), I would like to be able to provide my own html inputs (such as the ones provided by Shiny) and bind them to selections, instead of Vega providing the input-element. I would like to be able to provide default values in the spec for such selections, so that I can design the chart without the input present.

Could it be possible to define a selection with a "bring your own input"? To push the question further, could we define a range selection where an input provides both the lower and upper end of a range?

In both scenarios, I assume that I would be responsible for accessing the view to update the signals (which is fine by me).

This is similar to a feature I've been requesting where a selection signal
could simply be declared with a default starting value. That would seem to
be a fairly easy lift and require no more manual manipulation of the signal
by the spec.

My use case is simply this: on the timeline overview-detail pattern, where
a timeline at the bottom has a brush selection interaction that allows the
detail chart at the top to be zoomed and panned, there is no way to set a
starting range for the brush selection.

John K.

On Tue, Dec 18, 2018 at 10:04 PM Ian Lyttle notifications@github.com
wrote:

To build off of the two use-cases, I see @domoritz
https://github.com/domoritz' rotating-globe as being part of (a); there
is some parameter that we want to make reactive - I would like to be able
to do this more easily and robustly.

For case (b), I would like to be able to provide my own html inputs (such
as the ones provided by Shiny
http://shiny.rstudio.com/gallery/widget-gallery.html) and bind them to
selections, instead of Vega providing the input-element. I would like to be
able to provide default values in the spec for such selections, so that I
can design the chart without the input present.

Could it be possible to define a selection with a "bring your own input"?
To push the question further, could we define a range selection where an
input provides both the lower and upper end of a range?

In both scenarios, I assume that I would be responsible for accessing the
view to update the signals (which is fine by me).

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/vega/vega-lite/issues/3338#issuecomment-448453019,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFYx0IluFTq3GoTLq7A2JUA58ZdDl9Ysks5u6ayngaJpZM4R1AFh
.

@king612 - your use case will be supported once #4139 is merged and released.

Expanding the conversation above:

Signals are simply reactive variables. They are commonly used to (a) declare parameters and calculate dependent parameters and (b) capture input events to trigger selections.

From #4423, another use case (c) is to use signal to define custom expression.
We may not really care about reactive signals in this case, but in Vega we use signal to define arbitrary expression as well.

Thank you!

On Sat, Dec 29, 2018 at 10:07 PM Kanit Wongsuphasawat <
[email protected]> wrote:

@king612 https://github.com/king612 - your use case will be supported
once #4139 https://github.com/vega/vega-lite/pull/4139 is merged and
released.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/vega/vega-lite/issues/3338#issuecomment-450536057,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFYx0N_m1B3IV4tV7BvSoCGMMSRH0rrnks5u-C3fgaJpZM4R1AFh
.

I need to bind an event handler to an interaction in Vega Lite. Is there another way besides signals that I can do this? Or do I need to throw out Vega Lite and just use Vega?

@volkanunsal You can always connect to the signals that are created in the generated Vega. You can still use Vega-Lite!

Am I understanding correctly that this is the necessary feature to toggle dynamically between the three different stack options? All that is needed to change between the three different stacked area charts is to modify the stack attribute to either zero, normalize or center but it doesn't appear possible to easily implement this given the current API.

Yes, but you can use the patch property of Vega-Embed to add a signal for your specific purpose. We hope to have a cleaner API in the future.

@domoritz, I tried using this patch method in veg-embed and setting signals into vega-lite compiled vega for transform and init options, but I can't get (n?)either of them to work.

See observable notebook https://observablehq.com/@mattijn/vega-lite-experiment-signal-patch-and-external-inputs for some use-cases that hopefully one day will be supported. Or even better, my approach is wrong and it already works.

(btw vega-embed@4 doesn't work in observable?)

In the end, you just have Vega so if it works in Vega, you can achieve it with patching.

The patching part works as expected, but the part before where you put the signal in the Vega-Lite spec, which compiles to Vega doesn't always.

In some places in the Vega-Lite spec the definitions will be escaped during compiling and so does the injected signal.

This Vega-Lite specification with injected signal in a transform:

"transform": [
  {"filter": {"field": "Origin", "oneOf": ["signal_origin_value"]}}
]

compiles to this Vega definition:

"transform": [
  {
    "type": "filter",
    "expr": "indexof([\"signal_origin_value\"], datum[\"Origin\"]) !== -1"
  }
]

So a patch like

{patch: {signals: [{
  "name": "signal_origin_value",
  "value": "Japan"
}]}}

Can't be resolved.

So now we compile the Vega-Lite to Vega manually in the editor and fix the signals in Vega to make it dynamic, but every change in the Vega-Lite spec needs manual compiling and manually defining the signals again.

If Vega-Lite does not pass signals through (we make no guarantees), you have to patch the generated Vega manually.

Fair enough. If there is a certain character that force not escaping, while removing that character during compiling it could be possible. Thanks for the prompt responses!

Not that I know.

I would like to use signals in vega-lite to change the parameters of the formula, and to update the parameters with the rule marks.

For example, such an example can be realized with vega, but I hope it can also be realized with vega-lite.

https://gist.github.com/tmori3y2/6606686d9087a4b10d61d5e20d5a86b4

Of course, with vega-lite, you can add a constant value field to every data item with a calculate transform and use it in a formula, but it's a less clever implementation than a signal.

And selection cannot be bound to rule mark.

The rule marks bound to signals can be used for filters, so I think they are particularly useful.

[EDIT] Even if you can bind a selection to a rule mark before implementing a signal and refer to it instead of a field or value, or use it in a calculate transform, it will be a big improvement.

In the meantime, you can use the patch method in Eega-Embed as I've done in https://observablehq.com/@domoritz/rotating-earth.

What I want to do is achieved with the vega spec (pure json).

What I wanted to say is not about patching compiled vega, but about the vega-lite spec extension.

I want the following functions as a spec of vega-lite.

  • Use symbol and rule marks placed on the chart layer as a data picker

  • Allow that value to be used instead of 'field' or 'value'

For symbol mark, there are the following vega examples.

https://vega.github.io/vega/examples/budget-forecasts/

See my vega example for rule marks.

Open Link

The rule mark image is close to the binding of the slider of selection , but it does not match my request..

Also, the slider is not cool and cannot be operated intuitively.

Better if signal can be used with vega-lite, but extension of selection is also acceptable

We mostly have signals as experimental features in VL.
I'm opening https://github.com/vega/vega-lite/issues/6189 to discuss whether we want this to be an official feature, so we no longer need this issue.

Was this page helpful?
0 / 5 - 0 ratings