Skip to content

Commit c5040d8

Browse files
authored
move inputs overview (#1722)
* move inputs overview * fix links; self-host olympians
1 parent 0f2018a commit c5040d8

File tree

3 files changed

+133
-130
lines changed

3 files changed

+133
-130
lines changed

docs/inputs/index.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Observable Inputs
2+
3+
[Observable Inputs](https://github.com/observablehq/inputs) provides “lightweight interface components — buttons, sliders, dropdowns, tables, and the like — to help you explore data and build interactive displays.” Observable Inputs is available by default as `Inputs` in Markdown, but you can import it explicitly like so:
4+
5+
```js echo
6+
import * as Inputs from "npm:@observablehq/inputs";
7+
```
8+
9+
Or, just import the specific inputs you want:
10+
11+
```js echo
12+
import {button, color} from "npm:@observablehq/inputs";
13+
```
14+
15+
Inputs are typically passed to the [`view` function](<../reactivity#inputs>) for display, while exposing the input’s [value generator](../reactivity#generators) as a [reactive variable](../reactivity). Options differ between inputs. For example, the checkbox input accepts options to disable all or certain values, sort displayed values, and only display repeated values _once_ (among others):
16+
17+
```js echo
18+
const checkout = view(
19+
Inputs.checkbox(["B", "A", "Z", "Z", "⚠️F", "D", "G", "G", "G", "⚠️Q"], {
20+
disabled: ["⚠️F", "⚠️Q"],
21+
sort: true,
22+
unique: true,
23+
value: "B",
24+
label: "Choose categories:"
25+
})
26+
);
27+
```
28+
29+
```js echo
30+
checkout
31+
```
32+
33+
To demonstrate Observable Inputs, let’s look at a sample dataset of athletes from the 2016 Rio olympics via [Matt Riggott](https://flother.is/2017/olympic-games-data/). Here’s a [table input](./table) — always a good starting point for an agnostic view of the data:
34+
35+
```js
36+
const olympians = await d3.csv(import.meta.resolve("npm:@observablehq/sample-datasets/olympians.csv"), (d) => (delete d.id, delete d.info, d3.autoType(d)));
37+
```
38+
39+
```js echo
40+
Inputs.table(olympians)
41+
```
42+
43+
<div class="tip">Tables can be inputs, too! The value of the table is the subset of rows that you select using the checkboxes in the first column.</div>
44+
45+
Now let’s wire up the table to a [search input](./search). Type anything into the box and the search input will find the matching rows in the data. The value of the search input is the subset of rows that match the query.
46+
47+
A few examples to try: **[mal]** will match _sex_ = male, but also names that start with “mal”, such as Anna Malova; **[1986]** will match anyone born in 1986 (and a few other results); **[USA gym]** will match USA’s gymnastics team. Each space-separated term in your query is prefix-matched against all columns in the data.
48+
49+
```js echo
50+
const searchResults = view(Inputs.search(olympians, {
51+
datalist: ["mal", "1986", "USA gym"],
52+
placeholder: "Search athletes"
53+
}))
54+
```
55+
56+
```js echo
57+
Inputs.table(searchResults)
58+
```
59+
60+
You can sort columns by clicking on the column name: click once to sort ascending, and click again to sort descending. Note that the sort order is temporary: it’ll go away if you reload the page. Specify the column name as the _sort_ option above if you want this order to persist.
61+
62+
For a more structured approach, we can use a select input to choose a sport, then _array_.filter to determine which rows are shown in the table. The _sort_ and _unique_ options tell the input to show only distinct values and to sort them alphabetically. Try comparing the **[gymnastics]** and **[basketball]** sports.
63+
64+
```js echo
65+
const sport = view(
66+
Inputs.select(
67+
olympians.filter((d) => d.weight && d.height).map((d) => d.sport),
68+
{sort: true, unique: true, label: "sport"}
69+
)
70+
);
71+
```
72+
73+
```js echo
74+
Plot.plot({
75+
title: `How ${sport} athletes compare`,
76+
marks: [
77+
Plot.dot(olympians, {x: "weight", y: "height"}),
78+
Plot.dot(olympians.filter((d) => d.sport === sport), {x: "weight", y: "height", stroke: "red"})
79+
]
80+
})
81+
```
82+
83+
You can pass grouped data to a [select input](./select) as a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) from key to array of values, say using [d3.group](https://d3js.org/d3-array/group). The value of the select input in this mode is the data in the selected group. Note that _unique_ is no longer required, and that _sort_ works here, too, sorting the keys of the map returned by d3.group.
84+
85+
```js echo
86+
const sportAthletes = view(
87+
Inputs.select(
88+
d3.group(olympians, (d) => d.sport),
89+
{sort: true, label: "sport"}
90+
)
91+
);
92+
```
93+
94+
```js echo
95+
Inputs.table(sportAthletes)
96+
```
97+
98+
The select input works well for categorical data, such as sports or nationalities, but how about quantitative dimensions such as height or weight? Here’s a [range input](./range) that lets you pick a target weight; we then filter the table rows for any athlete within 10% of the target weight. Notice that some columns, such as sport, are strongly correlated with weight.
99+
100+
```js echo
101+
const weight = view(
102+
Inputs.range(
103+
d3.extent(olympians, (d) => d.weight),
104+
{step: 1, label: "weight (kg)"}
105+
)
106+
);
107+
```
108+
109+
```js echo
110+
Inputs.table(
111+
olympians.filter((d) => d.weight < weight * 1.1 && weight * 0.9 < d.weight),
112+
{sort: "weight"}
113+
)
114+
```
115+
116+
For more, see the individual input pages:
117+
118+
- [Button](./button) - do something when a button is clicked
119+
- [Toggle](./toggle) - toggle between two values (on or off)
120+
- [Checkbox](./checkbox) - choose any from a set
121+
- [Radio](./radio) - choose one from a set
122+
- [Range](./range) or [Number](./range) - choose a number in a range (slider)
123+
- [Select](./select) - choose one or any from a set (drop-down menu)
124+
- [Text](./text) - enter freeform single-line text
125+
- [Textarea](./textarea) - enter freeform multi-line text
126+
- [Date](./date) or [Datetime](./date) - choose a date
127+
- [Color](./color) - choose a color
128+
- [File](./file) - choose a local file
129+
- [Search](./search) - query a tabular dataset
130+
- [Table](./table) - browse a tabular dataset

docs/lib/inputs.md

Lines changed: 2 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,3 @@
1-
# Observable Inputs
1+
<meta http-equiv="refresh" content="0; url=../inputs/">
22

3-
[Observable Inputs](https://github.com/observablehq/inputs) provides “lightweight interface components — buttons, sliders, dropdowns, tables, and the like — to help you explore data and build interactive displays.” Observable Inputs is available by default as `Inputs` in Markdown, but you can import it explicitly like so:
4-
5-
```js echo
6-
import * as Inputs from "npm:@observablehq/inputs";
7-
```
8-
9-
Or, just import the specific inputs you want:
10-
11-
```js echo
12-
import {button, color} from "npm:@observablehq/inputs";
13-
```
14-
15-
Inputs are typically passed to the [`view` function](<../reactivity#inputs>) for display, while exposing the input’s [value generator](../reactivity#generators) as a [reactive variable](../reactivity). Options differ between inputs. For example, the checkbox input accepts options to disable all or certain values, sort displayed values, and only display repeated values _once_ (among others):
16-
17-
```js echo
18-
const checkout = view(
19-
Inputs.checkbox(["B", "A", "Z", "Z", "⚠️F", "D", "G", "G", "G", "⚠️Q"], {
20-
disabled: ["⚠️F", "⚠️Q"],
21-
sort: true,
22-
unique: true,
23-
value: "B",
24-
label: "Choose categories:"
25-
})
26-
);
27-
```
28-
29-
```js echo
30-
checkout
31-
```
32-
33-
To demonstrate Observable Inputs, let’s look at a sample dataset of athletes from the 2016 Rio olympics via [Matt Riggott](https://flother.is/2017/olympic-games-data/). Here’s a [table input](../inputs/table) — always a good starting point for an agnostic view of the data:
34-
35-
```js
36-
const olympians = await d3.csv("https://static.observableusercontent.com/files/31ca24545a0603dce099d10ee89ee5ae72d29fa55e8fc7c9ffb5ded87ac83060d80f1d9e21f4ae8eb04c1e8940b7287d179fe8060d887fb1f055f430e210007c", (d) => (delete d.id, delete d.info, d3.autoType(d)));
37-
```
38-
39-
```js echo
40-
Inputs.table(olympians)
41-
```
42-
43-
<div class="tip">Tables can be inputs, too! The value of the table is the subset of rows that you select using the checkboxes in the first column.</div>
44-
45-
Now let’s wire up the table to a [search input](../inputs/search). Type anything into the box and the search input will find the matching rows in the data. The value of the search input is the subset of rows that match the query.
46-
47-
A few examples to try: **[mal]** will match _sex_ = male, but also names that start with “mal”, such as Anna Malova; **[1986]** will match anyone born in 1986 (and a few other results); **[USA gym]** will match USA’s gymnastics team. Each space-separated term in your query is prefix-matched against all columns in the data.
48-
49-
```js echo
50-
const searchResults = view(Inputs.search(olympians, {
51-
datalist: ["mal", "1986", "USA gym"],
52-
placeholder: "Search athletes"
53-
}))
54-
```
55-
56-
```js echo
57-
Inputs.table(searchResults)
58-
```
59-
60-
You can sort columns by clicking on the column name: click once to sort ascending, and click again to sort descending. Note that the sort order is temporary: it’ll go away if you reload the page. Specify the column name as the _sort_ option above if you want this order to persist.
61-
62-
For a more structured approach, we can use a select input to choose a sport, then _array_.filter to determine which rows are shown in the table. The _sort_ and _unique_ options tell the input to show only distinct values and to sort them alphabetically. Try comparing the **[gymnastics]** and **[basketball]** sports.
63-
64-
```js echo
65-
const sport = view(
66-
Inputs.select(
67-
olympians.filter((d) => d.weight && d.height).map((d) => d.sport),
68-
{sort: true, unique: true, label: "sport"}
69-
)
70-
);
71-
```
72-
73-
```js echo
74-
Plot.plot({
75-
title: `How ${sport} athletes compare`,
76-
marks: [
77-
Plot.dot(olympians, {x: "weight", y: "height"}),
78-
Plot.dot(olympians.filter((d) => d.sport === sport), {x: "weight", y: "height", stroke: "red"})
79-
]
80-
})
81-
```
82-
83-
You can pass grouped data to a [select input](../inputs/select) as a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) from key to array of values, say using [d3.group](https://d3js.org/d3-array/group). The value of the select input in this mode is the data in the selected group. Note that _unique_ is no longer required, and that _sort_ works here, too, sorting the keys of the map returned by d3.group.
84-
85-
```js echo
86-
const sportAthletes = view(
87-
Inputs.select(
88-
d3.group(olympians, (d) => d.sport),
89-
{sort: true, label: "sport"}
90-
)
91-
);
92-
```
93-
94-
```js echo
95-
Inputs.table(sportAthletes)
96-
```
97-
98-
The select input works well for categorical data, such as sports or nationalities, but how about quantitative dimensions such as height or weight? Here’s a [range input](../inputs/range) that lets you pick a target weight; we then filter the table rows for any athlete within 10% of the target weight. Notice that some columns, such as sport, are strongly correlated with weight.
99-
100-
```js echo
101-
const weight = view(
102-
Inputs.range(
103-
d3.extent(olympians, (d) => d.weight),
104-
{step: 1, label: "weight (kg)"}
105-
)
106-
);
107-
```
108-
109-
```js echo
110-
Inputs.table(
111-
olympians.filter((d) => d.weight < weight * 1.1 && weight * 0.9 < d.weight),
112-
{sort: "weight"}
113-
)
114-
```
115-
116-
For more, see the individual input pages:
117-
118-
- [Button](../inputs/button) - do something when a button is clicked
119-
- [Toggle](../inputs/toggle) - toggle between two values (on or off)
120-
- [Checkbox](../inputs/checkbox) - choose any from a set
121-
- [Radio](../inputs/radio) - choose one from a set
122-
- [Range](../inputs/range) or [Number](../inputs/range) - choose a number in a range (slider)
123-
- [Select](../inputs/select) - choose one or any from a set (drop-down menu)
124-
- [Text](../inputs/text) - enter freeform single-line text
125-
- [Textarea](../inputs/textarea) - enter freeform multi-line text
126-
- [Date](../inputs/date) or [Datetime](../inputs/date) - choose a date
127-
- [Color](../inputs/color) - choose a color
128-
- [File](../inputs/file) - choose a local file
129-
- [Search](../inputs/search) - query a tabular dataset
130-
- [Table](../inputs/table) - browse a tabular dataset
3+
Moved to [Inputs](../inputs/).

observablehq.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export default {
4444
name: "Inputs",
4545
open: false,
4646
pager: "inputs",
47+
path: "/inputs/",
4748
pages: [
4849
{name: "Button", path: "/inputs/button"},
4950
{name: "Checkbox", path: "/inputs/checkbox"},
@@ -81,7 +82,6 @@ export default {
8182
{name: "Microsoft Excel (XLSX)", path: "/lib/xlsx"},
8283
{name: "Mosaic vgplot", path: "/lib/mosaic"},
8384
{name: "Observable Generators", path: "/lib/generators"},
84-
{name: "Observable Inputs", path: "/lib/inputs"},
8585
{name: "Observable Plot", path: "/lib/plot"},
8686
{name: "Shapefile", path: "/lib/shapefile"},
8787
{name: "SQLite", path: "/lib/sqlite"},

0 commit comments

Comments
 (0)