Skip to content

Commit 025e94e

Browse files
committed
arc diagram example
1 parent d0b420d commit 025e94e

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

docs/data/miserables.data.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import fs from "node:fs";
2+
3+
export default {
4+
watch: ["../public/data/miserables.json"],
5+
load([file]) {
6+
return JSON.parse(fs.readFileSync(file, "utf-8"));
7+
}
8+
};

docs/data/miserables.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import {data} from "./miserables.data";
2+
3+
export default Object.assign(data, {groups: new Map(data.nodes.map((d) => [d.id, d.group]))});

docs/marks/arrow.md

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,20 @@
33
import * as Plot from "@observablehq/plot";
44
import * as d3 from "d3";
55
import metros from "../data/metros.ts";
6+
import miserables from "../data/miserables.ts";
67

7-
const matrix = [[3, 2, 5], [1, 7, 2], [1, 1, 8]];
8-
const nodes = matrix.map((m, i) => d3.pointRadial(((2 - i) * 2 * Math.PI) / matrix.length, 100));
9-
const edges = matrix.flatMap((m, i) => m.map((value, j) => ([nodes[i], nodes[j], value])));
8+
const markov = (() => {
9+
const matrix = [[3, 2, 5], [1, 7, 2], [1, 1, 8]];
10+
const nodes = matrix.map((m, i) => d3.pointRadial(((2 - i) * 2 * Math.PI) / matrix.length, 100));
11+
const edges = matrix.flatMap((m, i) => m.map((value, j) => ([nodes[i], nodes[j], value])));
12+
return {nodes, edges};
13+
})();
14+
15+
function samegroup({source, target}) {
16+
source = miserables.groups.get(source);
17+
target = miserables.groups.get(target);
18+
return source === target ? source : null;
19+
}
1020

1121
</script>
1222

@@ -67,8 +77,8 @@ Plot.plot({
6777
aspectRatio: 1,
6878
axis: null,
6979
marks: [
70-
Plot.dot(nodes, {r: 40}),
71-
Plot.arrow(edges, {
80+
Plot.dot(markov.nodes, {r: 40}),
81+
Plot.arrow(markov.edges, {
7282
x1: ([[x1]]) => x1,
7383
y1: ([[, y1]]) => y1,
7484
x2: ([, [x2]]) => x2,
@@ -79,8 +89,8 @@ Plot.plot({
7989
headLength: 24,
8090
inset: 48
8191
}),
82-
Plot.text(nodes, {text: ["A", "B", "C"], dy: 12}),
83-
Plot.text(edges, {
92+
Plot.text(markov.nodes, {text: ["A", "B", "C"], dy: 12}),
93+
Plot.text(markov.edges, {
8494
x: ([[x1, y1], [x2, y2]]) => (x1 + x2) / 2 + (y1 - y2) * 0.15,
8595
y: ([[x1, y1], [x2, y2]]) => (y1 + y2) / 2 - (x1 - x2) * 0.15,
8696
text: ([,, value]) => value
@@ -115,7 +125,24 @@ The arrow mark supports the [standard mark options](../features/marks.md#mark-op
115125

116126
The **bend** option sets the angle between the straight line connecting the two points and the outgoing direction of the arrow from the start point. It must be within ±90°. A positive angle will produce a clockwise curve; a negative angle will produce a counterclockwise curve; zero will produce a straight line. The **headAngle** determines how pointy the arrowhead is; it is typically between 0° and 180°. The **headLength** determines the scale of the arrowhead relative to the stroke width. Assuming the default of stroke width 1.5px, the **headLength** is the length of the arrowhead’s side in pixels.
117127

118-
The **sweep** option <VersionBadge pr="1740" /> can be used to make arrows bend in the same direction, independently of the relative positions of the starting and ending points. It defaults to 1 indicating a positive (clockwise) bend angle; -1 indicates a negative (anticlockwise) bend angle. 0 effectively clears the bend angle. If set to *-x*, the bend angle is flipped when the ending point is to the left of the starting point — ensuring all arrows bulge up (down if bend is negative); if set to *-y*, the bend angle is flipped when the ending point is above the starting point — ensuring all arrows bulge right (left if bend is negative); the sign is negated for *+x* and *+y*.
128+
The **sweep** option <VersionBadge pr="1740" /> controls the bend orientation. It defaults to 1 indicating a positive (clockwise) bend angle; -1 indicates a negative (anticlockwise) bend angle; 0 effectively clears the bend angle. If *-x*, the bend angle is flipped when the ending point is to the left of the starting point — ensuring all arrows bulge up (down if bend is negative); if *-y*, the bend angle is flipped when the ending point is above the starting point — ensuring all arrows bulge right (left if bend is negative); the sign is negated for *+x* and *+y*. Below, *-y* is used to render undirected edges in an arc diagram.
129+
130+
:::plot https://observablehq.com/@observablehq/plot-arc-diagram
131+
```js
132+
Plot.plot({
133+
height: 1080,
134+
marginLeft: 100,
135+
axis: null,
136+
x: {domain: [0, 1]}, // see https://github.com/observablehq/plot/issues/1541
137+
color: {domain: d3.range(10), unknown: "#ccc"},
138+
marks: [
139+
Plot.dot(miserables.nodes, {x: 0, y: "id", fill: "group", sort: {y: "fill"}}),
140+
Plot.text(miserables.nodes, {x: 0, y: "id", text: "id", textAnchor: "end", dx: -6, fill: "group"}),
141+
Plot.arrow(miserables.links, {x: 0, y1: "source", y2: "target", sweep: "-y", bend: 90, headLength: 0, stroke: samegroup, sort: samegroup, reverse: true})
142+
]
143+
})
144+
```
145+
:::
119146

120147
## arrow(*data*, *options*) {#arrow}
121148

docs/public/data/miserables.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../test/data/miserables.json

0 commit comments

Comments
 (0)