Skip to content

Commit 5c2f198

Browse files
mbostockFil
andauthored
0.6.7 (#1557)
* 0.6.7 * typescript declarations * revert pointer scale changes; CHANGELOG * Update CHANGELOG * edits * typo * document crosshair * add x, y, note that common options are not supported * document pointer * pointer edits * edits * pointer edits * edits * pointer edits * crosshair edits * pRetTIER * fix crosshair link * fix crosshair link, again --------- Co-authored-by: Philippe Rivière <[email protected]>
1 parent 3e9497a commit 5c2f198

31 files changed

+2501
-1175
lines changed

CHANGELOG-2021.md

Lines changed: 419 additions & 0 deletions
Large diffs are not rendered by default.

CHANGELOG-2022.md

Lines changed: 666 additions & 0 deletions
Large diffs are not rendered by default.

CHANGELOG.md

Lines changed: 142 additions & 1073 deletions
Large diffs are not rendered by default.

docs/.vitepress/config.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {defineConfig} from "vitepress";
33
import plot from "./markdown-it-plot.js";
44

55
// https://vitepress.dev/reference/site-config
6+
// prettier-ignore
67
export default defineConfig({
78
title: "Observable Plot",
89
description: "The JavaScript library for exploratory data visualization",
@@ -57,18 +58,19 @@ export default defineConfig({
5758
{text: "Scales", link: "/features/scales"},
5859
{text: "Projections", link: "/features/projections"},
5960
{text: "Transforms", link: "/features/transforms"},
61+
{text: "Interactions", link: "/features/interactions"},
6062
{text: "Facets", link: "/features/facets"},
6163
{text: "Legends", link: "/features/legends"},
6264
{text: "Curves", link: "/features/curves"},
6365
{text: "Formats", link: "/features/formats"},
6466
{text: "Markers", link: "/features/markers"},
6567
{text: "Shorthand", link: "/features/shorthand"},
66-
{text: "Accessibility", link: "/features/accessibility"},
68+
{text: "Accessibility", link: "/features/accessibility"}
6769
]
6870
},
6971
{
7072
text: "Marks",
71-
collapsed: false,
73+
collapsed: true,
7274
items: [
7375
{text: "Area", link: "/marks/area"},
7476
{text: "Arrow", link: "/marks/arrow"},
@@ -78,6 +80,7 @@ export default defineConfig({
7880
{text: "Box", link: "/marks/box"},
7981
{text: "Cell", link: "/marks/cell"},
8082
{text: "Contour", link: "/marks/contour"},
83+
{text: "Crosshair", link: "/marks/crosshair"},
8184
{text: "Delaunay", link: "/marks/delaunay"},
8285
{text: "Density", link: "/marks/density"},
8386
{text: "Dot", link: "/marks/dot"},
@@ -94,13 +97,14 @@ export default defineConfig({
9497
{text: "Rule", link: "/marks/rule"},
9598
{text: "Text", link: "/marks/text"},
9699
{text: "Tick", link: "/marks/tick"},
100+
{text: "Tip", link: "/marks/tip"},
97101
{text: "Tree", link: "/marks/tree"},
98102
{text: "Vector", link: "/marks/vector"}
99103
]
100104
},
101105
{
102106
text: "Transforms",
103-
collapsed: false,
107+
collapsed: true,
104108
items: [
105109
{text: "Bin", link: "/transforms/bin"},
106110
{text: "Centroid", link: "/transforms/centroid"},
@@ -117,6 +121,13 @@ export default defineConfig({
117121
{text: "Tree", link: "/transforms/tree"},
118122
{text: "Window", link: "/transforms/window"}
119123
]
124+
},
125+
{
126+
text: "Interactions",
127+
collapsed: true,
128+
items: [
129+
{text: "Pointer", link: "/interactions/pointer"}
130+
]
120131
}
121132
],
122133
search: {
@@ -131,8 +142,7 @@ export default defineConfig({
131142
{icon: "youtube", link: "https://www.youtube.com/c/Observablehq"}
132143
],
133144
footer: {
134-
message:
135-
"Library released under <a style='text-decoration:underline;' href='https://github.com/observablehq/plot/blob/main/LICENSE'>ISC License</a>.",
145+
message: "Library released under <a style='text-decoration:underline;' href='https://github.com/observablehq/plot/blob/main/LICENSE'>ISC License</a>.",
136146
copyright: `Copyright 2020–${new Date().getUTCFullYear()} Observable, Inc.`
137147
}
138148
}

docs/.vitepress/theme/custom.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
fill: var(--vp-c-bg-alt);
3737
}
3838

39-
:root.dark marker[stroke="white"] {
39+
:root.dark marker[stroke="white"],
40+
:root.dark [aria-label^="crosshair"][stroke="white"] {
4041
stroke: var(--vp-c-bg);
4142
}
4243

docs/features/interactions.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<script setup>
2+
3+
import * as Plot from "@observablehq/plot";
4+
import * as d3 from "d3";
5+
import {shallowRef, onMounted} from "vue";
6+
7+
const olympians = shallowRef([
8+
{weight: 31, height: 1.21, sex: "female"},
9+
{weight: 170, height: 2.21, sex: "male"}
10+
]);
11+
12+
onMounted(() => {
13+
d3.csv("../data/athletes.csv", d3.autoType).then((data) => (olympians.value = data));
14+
});
15+
16+
</script>
17+
18+
# Interactions
19+
20+
Interaction allows reading values out of a plot (details on demand), or fluidly changing a view of data without editing code (zoom and filter). There are a variety of ways to achieve interaction with Plot, including built-in interaction features and development techniques with frameworks such as Observable and React.
21+
22+
## Pointing
23+
24+
When looking at a scatterplot, the reader may wonder, *what abstract values does this dot represent?*
25+
26+
The [pointer transform](../interactions/pointer.md) can provide an answer: it dynamically [filters](../transforms/filter.md) a mark such that only the data closest to the pointer (such as the mouse) is rendered. The pointer transform is often paired with the [tip mark](../marks/tip.md) for interactive tooltips, revealing exact values as the pointer moves over the plot. The tip can show additional fields not otherwise visible, such as the *name* and *sport* of Olympic athletes below.
27+
28+
:::plot defer
29+
```js
30+
Plot.dot(olympians, {
31+
x: "weight",
32+
y: "height",
33+
stroke: "sex",
34+
channels: {name: "name", sport: "sport"},
35+
tip: true
36+
}).plot()
37+
```
38+
:::
39+
40+
The [crosshair mark](../marks/crosshair.md) uses the pointer transform internally to display a [rule](../marks/rule.md) and a [text](../marks/text.md) showing the **x** (horizontal↔︎ position) and **y** (vertical↕︎ position) value of the nearest data.
41+
42+
:::plot defer
43+
```js
44+
Plot.plot({
45+
marks: [
46+
Plot.dot(olympians, {x: "weight", y: "height", stroke: "sex"}),
47+
Plot.crosshair(olympians, {x: "weight", y: "height"})
48+
]
49+
})
50+
```
51+
:::
52+
53+
These values are displayed atop the axes on the edge of the frame; unlike the tip mark, the crosshair mark will not obscure other marks in the plot.
54+
55+
## Selecting
56+
57+
Support for selecting points within a plot through direct manipulation is under development. If you are interested in this feature, please upvote [#5](https://github.com/observablehq/plot/issues/5). See [#721](https://github.com/observablehq/plot/pull/721) for some early work on brushing.
58+
59+
## Zooming
60+
61+
Support for interactive panning and zooming is planned for a future release. If you are interested in this feature, please upvote [#1590](https://github.com/observablehq/plot/issues/1590).
62+
63+
## Animation
64+
65+
Support for declarative animation is planned for a future release. If you are interested in this feature, please upvote [#166](https://github.com/observablehq/plot/issues/166). See [#995](https://github.com/observablehq/plot/pull/995) for some early work on a **time** channel.
66+
67+
## Custom reactivity
68+
69+
With the exception of render transforms (see the [pointer transform](https://github.com/observablehq/plot/blob/main/src/interactions/pointer.js) implementation), Plot does not currently provide incremental re-rendering (partial updates to previously-rendered plots) or animated transitions between views.
70+
71+
That said, you can simply throw away an old plot and replace it with a new one! This allows plotting of dynamic data: data which can change in real-time as it streams in, or because it is derived in response to external inputs such as range sliders and search boxes.
72+
73+
On Observable, you can use [viewof](https://observablehq.com/@observablehq/views) in conjunction with [Observable Inputs](https://observablehq.com/@observablehq/inputs) for interactivity. If your cell references another cell, it will automatically re-run whenever the upstream cell’s value changes. For example, try dragging the slider in this [hexbin example](https://observablehq.com/@observablehq/plot-hexbin-binwidth?intent=fork). In React, use [useEffect](https://react.dev/reference/react/useEffect) and [useRef](https://react.dev/reference/react/useRef) to re-render the plot when data changes. In Vue, use [ref](https://vuejs.org/api/reactivity-core.html#ref). For more, see our [getting started guide](../getting-started.md).
74+
75+
You can also manipulate the SVG that Plot creates, if you are comfortable using lower-level APIs; see examples by [Mike Freeman](https://observablehq.com/@mkfreeman/plot-animation) and [Philippe Rivière](https://observablehq.com/@fil/plot-animate-a-bar-chart).

docs/features/marks.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,12 @@ All marks support the following style options:
486486
* **ariaHidden** - if true, hide this content from the accessibility tree
487487
* **pointerEvents** - the [pointer events](https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events) (*e.g.*, *none*)
488488
* **clip** - whether and how to clip the mark
489+
* **tip** - whether to generate an implicit [pointer](../interactions/pointer.md) [tip](../marks/tip.md)
489490

490491
If the **clip** option is *frame* (or equivalently true), the mark is clipped to the frame’s dimensions; if the **clip** option is null (or equivalently false), the mark is not clipped. If the **clip** option is *sphere*, then a [geographic projection](./projections.md) is required and the mark will be clipped to the projected sphere (_e.g._, the front hemisphere when using the orthographic projection).
491492

493+
If the **tip** option is true, a [tip mark](../marks/tip.md) with the [pointer transform](../interactions/pointer.md) will be derived from this mark and placed atop all other marks, offering details on demand. If the **tip** option is set to *x*, *y*, or *xy*, [pointerX](../interactions/pointer.md#pointerx-options), [pointerY](../interactions/pointer.md#pointery-options), or [pointer](../interactions/pointer.md#pointer-options) will be used, respectively; otherwise the pointing mode will be chosen automatically. (If the **tip** mark option is truthy, the **title** channel is no longer applied using an SVG title element as this would conflict with the tip mark.)
494+
492495
For all marks except [text](../marks/text.md), the **dx** and **dy** options are rendered as a transform property, possibly including a 0.5px offset on low-density screens.
493496

494497
All marks support the following optional channels:

0 commit comments

Comments
 (0)