Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.6.7 #1557

Merged
merged 18 commits into from
May 23, 2023
419 changes: 419 additions & 0 deletions CHANGELOG-2021.md

Large diffs are not rendered by default.

666 changes: 666 additions & 0 deletions CHANGELOG-2022.md

Large diffs are not rendered by default.

1,215 changes: 142 additions & 1,073 deletions CHANGELOG.md

Large diffs are not rendered by default.

20 changes: 15 additions & 5 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {defineConfig} from "vitepress";
import plot from "./markdown-it-plot.js";

// https://vitepress.dev/reference/site-config
// prettier-ignore
export default defineConfig({
title: "Observable Plot",
description: "The JavaScript library for exploratory data visualization",
Expand Down Expand Up @@ -57,18 +58,19 @@ export default defineConfig({
{text: "Scales", link: "/features/scales"},
{text: "Projections", link: "/features/projections"},
{text: "Transforms", link: "/features/transforms"},
{text: "Interactions", link: "/features/interactions"},
{text: "Facets", link: "/features/facets"},
{text: "Legends", link: "/features/legends"},
{text: "Curves", link: "/features/curves"},
{text: "Formats", link: "/features/formats"},
{text: "Markers", link: "/features/markers"},
{text: "Shorthand", link: "/features/shorthand"},
{text: "Accessibility", link: "/features/accessibility"},
{text: "Accessibility", link: "/features/accessibility"}
]
},
{
text: "Marks",
collapsed: false,
collapsed: true,
items: [
{text: "Area", link: "/marks/area"},
{text: "Arrow", link: "/marks/arrow"},
Expand All @@ -78,6 +80,7 @@ export default defineConfig({
{text: "Box", link: "/marks/box"},
{text: "Cell", link: "/marks/cell"},
{text: "Contour", link: "/marks/contour"},
{text: "Crosshair", link: "/marks/crosshair"},
{text: "Delaunay", link: "/marks/delaunay"},
{text: "Density", link: "/marks/density"},
{text: "Dot", link: "/marks/dot"},
Expand All @@ -94,13 +97,14 @@ export default defineConfig({
{text: "Rule", link: "/marks/rule"},
{text: "Text", link: "/marks/text"},
{text: "Tick", link: "/marks/tick"},
{text: "Tip", link: "/marks/tip"},
{text: "Tree", link: "/marks/tree"},
{text: "Vector", link: "/marks/vector"}
]
},
{
text: "Transforms",
collapsed: false,
collapsed: true,
items: [
{text: "Bin", link: "/transforms/bin"},
{text: "Centroid", link: "/transforms/centroid"},
Expand All @@ -117,6 +121,13 @@ export default defineConfig({
{text: "Tree", link: "/transforms/tree"},
{text: "Window", link: "/transforms/window"}
]
},
{
text: "Interactions",
collapsed: true,
items: [
{text: "Pointer", link: "/interactions/pointer"}
]
}
],
search: {
Expand All @@ -131,8 +142,7 @@ export default defineConfig({
{icon: "youtube", link: "https://www.youtube.com/c/Observablehq"}
],
footer: {
message:
"Library released under <a style='text-decoration:underline;' href='https://github.com/observablehq/plot/blob/main/LICENSE'>ISC License</a>.",
message: "Library released under <a style='text-decoration:underline;' href='https://github.com/observablehq/plot/blob/main/LICENSE'>ISC License</a>.",
copyright: `Copyright 2020–${new Date().getUTCFullYear()} Observable, Inc.`
}
}
Expand Down
3 changes: 2 additions & 1 deletion docs/.vitepress/theme/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
fill: var(--vp-c-bg-alt);
}

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

Expand Down
75 changes: 75 additions & 0 deletions docs/features/interactions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<script setup>

import * as Plot from "@observablehq/plot";
import * as d3 from "d3";
import {shallowRef, onMounted} from "vue";

const olympians = shallowRef([
{weight: 31, height: 1.21, sex: "female"},
{weight: 170, height: 2.21, sex: "male"}
]);

onMounted(() => {
d3.csv("../data/athletes.csv", d3.autoType).then((data) => (olympians.value = data));
});

</script>

# Interactions

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.

## Pointing

When looking at a scatterplot, the reader may wonder, *what abstract values does this dot represent?*

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.

:::plot defer
```js
Plot.dot(olympians, {
x: "weight",
y: "height",
stroke: "sex",
channels: {name: "name", sport: "sport"},
tip: true
}).plot()
```
:::

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.

:::plot defer
```js
Plot.plot({
marks: [
Plot.dot(olympians, {x: "weight", y: "height", stroke: "sex"}),
Plot.crosshair(olympians, {x: "weight", y: "height"})
]
})
```
:::

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.

## Selecting

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.

## Zooming

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).

## Animation

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.

## Custom reactivity

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.

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.

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).

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).
3 changes: 3 additions & 0 deletions docs/features/marks.md
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,12 @@ All marks support the following style options:
* **ariaHidden** - if true, hide this content from the accessibility tree
* **pointerEvents** - the [pointer events](https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events) (*e.g.*, *none*)
* **clip** - whether and how to clip the mark
* **tip** - whether to generate an implicit [pointer](../interactions/pointer.md) [tip](../marks/tip.md)

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).

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.)

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.

All marks support the following optional channels:
Expand Down
Loading