Skip to content

Commit

Permalink
more documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Fil committed Sep 6, 2023
1 parent 567b830 commit 2eb8b47
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 42 deletions.
21 changes: 13 additions & 8 deletions docs/features/interactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,21 @@ These values are displayed atop the axes on the edge of the frame; unlike the ti

## Selecting

The [brush transform](../interactions/brush.md) allows the interactive selection of discrete elements, such as dots in a scatterplot, by direct manipulation of the chart. A brush listens to mouse and touch events on the chart, allowing the user to define a rectangular region. All the data points that fall within the region are included in the selection.
The [brush transform](../interactions/brush.md) allows the interactive selection of discrete elements by direct manipulation of the chart.

:::plot defer https://observablehq.com/@observablehq/plot-brush-interaction-dev
:::plot defer https://observablehq.com/@observablehq/brushing-plot--1653
```js
Plot.plot({
marks: [
Plot.dot(penguins, { x: "culmen_length_mm", y: "culmen_depth_mm" }),
Plot.dot(penguins, Plot.brush({ x: "culmen_length_mm", y: "culmen_depth_mm", fill: "species", stroke: "currentColor" }))
]
})
Plot.dot(
penguins,
Plot.brush({
x: "culmen_length_mm",
y: "culmen_depth_mm",
stroke: "currentColor",
fill: "#fff",
unselected: {strokeOpacity: 0.5},
selected: {fill: "species"}
})
).plot()
```
:::

Expand Down
67 changes: 33 additions & 34 deletions docs/interactions/brush.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,57 @@ import * as Plot from "@observablehq/plot";
import * as d3 from "d3";
import {ref, shallowRef, onMounted} from "vue";

// const pointered = ref(true);
// const aapl = shallowRef([]);
// const industries = shallowRef([]);
// const olympians = shallowRef([]);
const penguins = shallowRef([]);
// const linetip = ref("x");
// const recttip = ref("x");

onMounted(() => {
// d3.csv("../data/aapl.csv", d3.autoType).then((data) => (aapl.value = data));
// d3.csv("../data/athletes.csv", d3.autoType).then((data) => (olympians.value = data));
// d3.csv("../data/bls-industry-unemployment.csv", d3.autoType).then((data) => (industries.value = data));
d3.csv("../data/penguins.csv", d3.autoType).then((data) => (penguins.value = data));
});

</script>

# Brush transform

The **brush transform** filters a mark interactively such that only the data that fall within the rectangular region defined by the user are rendered. It is typically used to select discrete elements, such as dots in a scatterplot:
The **brush transform** allows the interactive selection of discrete elements, such as dots in a scatterplot, by direct manipulation of the chart. A brush listens to mouse and touch events on the chart, allowing the user to define a rectangular region. All the data points that fall within the region are included in the selection.

:::plot defer
```js
Plot.plot({
marks: [
Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", fill: "currentColor"}),
Plot.dot(penguins, Plot.brush({x: "culmen_length_mm", y: "culmen_depth_mm", fill: "species", stroke: "currentColor", r: 4}))
]
})
Plot.dot(
penguins,
Plot.brush({
x: "culmen_length_mm",
y: "culmen_depth_mm",
stroke: "currentColor",
fill: "#fff",
unselected: {strokeOpacity: 0.5},
selected: {fill: "species"}
})
).plot()
```
:::

When the chart has a dominant axis, an horizontal or vertical brush is recommended; for example, to select bars in a histogram:

:::plot defer
```js
Plot.plot({
marks: [
Plot.rectY(penguins, Plot.binX({y: "count"}, {x: "body_mass_g", thresholds: 40, fillOpacity: 0.2})),
Plot.rectY(penguins, Plot.brushX(Plot.binX({y: "count"}, {fill:"currentColor", x: "body_mass_g", thresholds: 40}))),
]
})
Plot.rectY(
penguins,
Plot.brushX(
Plot.binX(
{y: "count"},
{
x: "body_mass_g",
thresholds: 40,
unselected: {opacity: 0.1},
}
)
)
).plot()
```
:::

The brush transform is similar to the [pointer](./pointer.md) transform: it interactively filters the mark’s index to show a subset of the data, and re-renders the mark as the selection changes. Since the mark is lazily rendered during interaction, it is fast: only the visible elements are rendered as needed. And, like the filter and select transforms, unfiltered channel values are incorporated into default scale domains.
The brush transform interactively partitions the mark’s index in two: the unselected subset — for points outside the region —, and the selected subset for points inside. As the selection changes, the mark is replaced by two derived marks: below, a mark for the unselected data, with the mark options combined with the **unselected** option; above, a mark for the selected data, with the mark options combined with the **selected** option. All the channel values are incorporated into default scale domains, allowing *e.g.* a color scale to include the fill channel of the selected mark.

The brush transform supports both one- and two-dimensional brushing modes. The two-dimensional mode, [brush](#brush), is used above and is suitable for scatterplots and the general case: it allows the user to define a rectangular region by clicking on a corner (_e.g._ the top-left corner) and dragging the pointer to the bottom-right corner. The one-dimensional modes, [brushX](#brushX) and [brushY](#brushY), in contrast only consider one dimension; this is desirable when a chart has a “dominant” dimension, such as time in a time-series chart, the binned quantitative dimension in a histogram, or the categorical dimension of a bar chart.
The brush transform supports both one- and two-dimensional brushing modes. The two-dimensional mode, [brush](#brush), is suitable for scatterplots and the general case: it allows the user to define a rectangular region by clicking on a corner (_e.g._ the top-left corner) and dragging the pointer to the bottom-right corner. The one-dimensional modes, [brushX](#brushX) and [brushY](#brushY), in contrast only consider one dimension; this is desirable when a chart has a “dominant” dimension, such as time in a time-series chart, the binned quantitative dimension in a histogram, or the categorical dimension of a bar chart.

The brush transform emits an [*input* event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event) whenever the selection changes, and sets the value of the plot element to the selected data. This allows you to use a plot as an [Observable view](https://observablehq.com/@observablehq/views) (viewof), or to register an *input* event listener to react to brushing.

Expand All @@ -65,20 +68,16 @@ The following options control the brush transform:
- **y2** - the ending vertical↕︎ target position; bound to the *y* scale
- **x** - the fallback horizontal↔︎ target position; bound to the *x* scale
- **y** - the fallback vertical↕︎ target position; bound to the *y* scale
- **selectionMode** - controls the value exposed to listeners of the *input* events.
- **selected** - additional options for the derived mark representing the selection
- **unselected** - additional options for the derived mark representing non-selected data

The positional options define a sensitive surface for each data point, defined on the horizontal axis as the extent between *x1* and *x2* if specified, between *x* and *x + bandwidth* if *x* is a band scale, or the value *x* otherwise. The sensitive surface’s vertical extent likewise spans from *y1* to *y2* if specified, from *y* to *y + bandwidth* if *y* is a band scale, or is equal to the *y* value otherwise.

When the user interacts with the plot by clicking and dragging the brush to define a rectangular region, all the elements whose sensitive surface intersect with the brushed region are selected, and the mark is re-rendered.
When the user interacts with the plot by clicking and dragging the brush to define a rectangular region, all the elements whose sensitive surface intersect with the brushed region are selected, and the derived marks are re-rendered.

The brush’s selection mode determines the contents of the plot’s value property when the user manipulates the brush. It supports the following options:
The selected data exposed as the value of the plot is an array of the (possibly transformed) data rendered by the *selected* derived mark. For example, in the case of the histogram above, the selected data is an array of bins, each containing the penguins whose body mass is between the bin’s lower and upper bounds.

* **data** - default; the selected data
* **extent** - the selection extent, in data space

The selected data is an array of the possibly transformed data rendered by the mark. For example, in the case of the histogram above, the selected data is an array of bins, each containing the penguins whose body mass is between the bin’s lower and upper bounds.

The selection extent is an object with properties *x*: [x1, x2] for brushX, *y*: [y1, y2] for brushY, and both *x* and *y* for brush. Additionally, when faceting, it contains the facet’s *fx* and *fy* properties.
The value is decorated with the brush’s coordinates (in data space) as its **x1** and **x2** properties for a quantitative scale *x*, and its **x** property if *x* is ordinal — and likewise for *y*. The value is also decorated with a **done** property set to false while brushing, true when the user releases the pointer, and undefined when the brush is canceled. Additionally, when faceting, it exposes the brushed facet’s *fx* and *fy* properties.

For details on the user interface (including touch events, pointer events and modifier keys), see [d3-brush](https://github.com/d3/d3-brush).

Expand All @@ -88,7 +87,7 @@ For details on the user interface (including touch events, pointer events and mo
Plot.dot(penguins, Plot.brush({x: "culmen_length_mm", y: "culmen_depth_mm"}))
```

Applies the brush render transform to the specified *options* to filter the mark index such that the points whose sensitive surface intersect with the brushed region the point closest to the pointer is rendered; the mark will re-render interactively in response to brush events.
Applies the brush render transform to the specified *options* to filter the mark index such that the points whose sensitive surface intersect with the brushed region the point closest to the pointer is rendered.

## brushX(*options*) {#brushX}

Expand Down

0 comments on commit 2eb8b47

Please sign in to comment.