Combining faceting with dynamic queries.
Reading, Recording, Notebook, Rmarkdown
It is often useful to combine multi-view composition with dynamic queries. The basic idea is to (a) show different aspects of a dataset using different views, and then (b) link the views using dynamic queries. This strategy is sometimes called dynamic linking.
To make this concrete, consider cross-filtering. In the visualization below, we can see how different fields of a flights dataset are related to one another.
robservable("@krisrs1128/week-3-4", include = 4, height = 235)
{const brush = vl.selectInterval().encodings('x').resolve('intersect'),
= vl.markBar().encode(
hist .x().fieldQ(vl.repeat('row')).bin({maxbins: 100}), // up to 100 bins, but no smaller than 1 unit
vl.y().count().title(null) // no y-axis title
vl;
)
return vl.layer(
.select(brush).encode(vl.color().value('lightgrey')),
hist.transform(vl.filter(brush))
hist
).width(900).height(100)
.repeat({row: ['delay', 'distance', 'time']})
.data(flights)
.config({view: {stroke: null}}) // no outline
.render();
}
robservable("@krisrs1128/week-3-4", include = 5, height = 430)
The implementation here is subtle.
repeat
strategy. These serve as a reference and are never updated.selectInterval
is bound to each of these grey histograms. This is what lets us select ranges of values, with which we will update the blue histogram.selectInterval
. Every time the brush is moved, the histograms are recomputed and redrawn.Aside: Scented widgets are an other example of how coordinated views and dynamic queries are useful together. There, though, one of the views had a more central role.
Considered abstractly, there are two axes along which we can think of coordinated views. The first is whether we are encoding the data in the same way. Second, are we sharing the same data across the different views? We can recover many of our earlier plots from this point of view, and it is a useful conceptual aid when exploring the space of design possibilities for a dataset.
Why are these all effective?