Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ jobs:
run: tree-sitter test

- name: Run Rust tests
run: cargo test --lib --bins
run: cargo test --lib --bins -- --test-threads=1

- name: Install dbc CLI and SQLite ADBC driver
run: |
curl -LsSf https://dbc.columnar.tech/install.sh | sh
"$HOME/.local/bin/dbc" install sqlite

- name: Run ADBC unit tests
run: cargo test --features "adbc sqlite" --lib
run: cargo test --features "adbc sqlite" --lib -- --test-threads=1

- name: Run ADBC SQLite equivalence tests
run: cargo test --features "adbc sqlite" --lib -- --ignored equivalence
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### Added

- The line, path and segment layers now have an `arrow` setting, which
can be used to display arrowheads at the ends of the lines.
- Many layers now support `linecap` and `linejoin` settings for styling lines.
- The Positron extension now registers a ggsql data importer, so dragging a
csv/tsv/parquet/json file into Positron offers to generate the ggsql code
Expand Down
36 changes: 25 additions & 11 deletions doc/syntax/layer/type/line.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ The following aesthetics are recognised by the line layer.
* `aggregate` Aggregation functions to apply per group:
* `null` apply no group aggregation (default).
* A single string or an array of strings. See an overview of aggregation function in [the `DRAW` documentation](../../clause/draw.qmd#aggregate) and more information in the *Data transformation* section below.
* `arrow` Arrow names to display at line ends. Broadly, these come in the following variants:
* Arrow heads: `'open'`, `'closed'`, `'stealth'`, `'latex'`, `'thin'` and `'wedge'`.
* Arrow tails: `'fishtail'`, `'fork'`, and `'feather'`.
* Symmetric: `'bar'`, `'bracket'`, `'cross'`, `'dot'`, `'square'` and `'diamond'`.

Arrow names can optionally be followed by a `:`-separated numeric suffix to set their size in points, e.g. `'open:10'`.
By default, arrows are sized by tripling the `linewidth` value.
Arrows can be declared in the following ways:
* `null` (default) do not display an arrow.
* A single string giving an arrow name to use at the end of the line.
* A `[start, end]` array of names or `null` to specify arrows for the start and end of the line.
To only set an arrow at the start, you could use `['open', null]`.


## Data transformation
This layer supports aggregation through the `aggregate` setting. Aggregation groups are defined by `PARTITION BY`, all discrete mappings, but also the primary axis. Within each group, every numeric mapping is replaced in place by its aggregated value. Use a default like `'mean'` or target individual aesthetics with `'<aes>:<func>'`. See [the `DRAW` documentation](../../clause/draw.qmd#aggregate) for the full setting shape.
Expand Down Expand Up @@ -73,11 +86,10 @@ DRAW line
When `stroke` or `opacity` varies, the properties of the preceding datapoint carry over. In the case below, we don't see the blue of the last datapoint.

```{ggsql}
WITH data(x, y, z) AS (VALUES
(1, 2, 1),
(2, 5, 3),
(3, 3, 5),
)
-- Small example dataset
CREATE TEMP TABLE data AS
SELECT * FROM (VALUES (1,2,1), (2,5,3), (3,3,5)) t(x,y,z)

VISUALISE x, y FROM data
DRAW line
MAPPING z AS stroke
Expand All @@ -87,18 +99,20 @@ SCALE stroke TO ('red', 'green', 'blue')
The `linewidth` aesthetic can vary point to point.

```{ggsql}
WITH data(x, y, z) AS (VALUES
(1, 2, 1),
(2, 5, 3),
(3, 3, 5),
)

VISUALISE x, y FROM data
DRAW line
MAPPING z AS linewidth
SCALE linewidth TO (0, 30)
```

Arrows applied to the start and end of the line.

```{ggsql}
VISUALISE x, y FROM data
DRAW line SETTING
arrow => 'wedge'
```

Use aggregation to draw min and max lines from a set of observations on a single layer. Targeting `y` twice produces one summary row per function within the same group. A synthetic `aggregate` column tags each row with the different function names, that you can remap to colour the lines distinctly:

```{ggsql}
Expand Down
20 changes: 20 additions & 0 deletions doc/syntax/layer/type/path.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ The following aesthetics are recognised by the path layer.
* `linecap`: The style of line endings, including the ends of dashes in dashed lines. One of `'butt'` (default), `'round'`, or `'square'`.
* `linejoin`: The style of corners where line segments meet. One of `'miter'`/`'mitre'` (default), `'round'`, or `'bevel'`.
* `position`: Position adjustment. One of `'identity'` (default), `'stack'`, `'dodge'`, or `'jitter'`
* `arrow` Arrow names to display at line ends. Broadly, these come in the following variants:
* Arrow heads: `'open'`, `'closed'`, `'stealth'`, `'latex'`, `'thin'` and `'wedge'`.
* Arrow tails: `'fishtail'`, `'fork'`, and `'feather'`.
* Symmetric: `'bar'`, `'bracket'`, `'cross'`, `'dot'`, `'square'` and `'diamond'`.

Arrow names can optionally be followed by a `:`-separated numeric suffix to set their size in points, e.g. `'open:10'`.
By default, arrows are sized by tripling the `linewidth` value.
Arrows can be declared in the following ways:
* `null` (default) do not display an arrow.
* A single string giving an arrow name to use at the end of the line.
* A `[start, end]` array of names or `null` to specify arrows for the start and end of the line.
To only set an arrow at the start, you could use `['open', null]`.

## Data transformation
The path layer does not transform its data but passes it through unchanged.
Expand Down Expand Up @@ -92,6 +104,14 @@ DRAW path
MAPPING 'Path' AS stroke
```

Setting an arrow.

```{ggsql}
VISUALISE x, y FROM df
DRAW path SETTING
arrow => 'stealth'
```

Lines have various styling mechanics, inlcuding layer-level settings for joining and capping lines.

```{ggsql}
Expand Down
27 changes: 25 additions & 2 deletions doc/syntax/layer/type/segment.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ For axis-aligned intervals where one coordinate is shared between the start and
* `linetype`: The type of the line, i.e. the dashing pattern.

## Settings
* `arrow` Arrow names to display at line ends. Broadly, these come in the following variants:
* Arrow heads: `'open'`, `'closed'`, `'stealth'`, `'latex'`, `'thin'` and `'wedge'`.
* Arrow tails: `'fishtail'`, `'fork'`, and `'feather'`.
* Symmetric: `'bar'`, `'bracket'`, `'cross'`, `'dot'`, `'square'` and `'diamond'`.

Arrow names can optionally be followed by a `:`-separated numeric suffix to set their size in points, e.g. `'open:10'`.
By default, arrows are sized by tripling the `linewidth` value.
Arrows can be declared in the following ways:
* `null` (default) do not display an arrow.
* A single string giving an arrow name to use at the end of the line.
* A `[start, end]` array of names or `null` to specify arrows for the start and end of the line.
To only set an arrow at the start, you could use `['open', null]`.
* `linecap`: The style of line endings, including the ends of dashes in dashed lines. One of `'butt'` (default), `'round'`, or `'square'`.
* `position`: Position adjustment. One of `'identity'` (default), `'stack'`, `'dodge'`, or `'jitter'`
* `aggregate` Aggregation functions to apply per group:
Expand All @@ -41,7 +53,8 @@ The segment layer has no orientations. The axes are treated symmetrically.
Segments are useful when you have known start and end points of the data. For example in a graph

```{ggsql}
WITH edges(x, y, xend, yend, type) AS (VALUES
CREATE TEMP TABLE edges AS
SELECT * FROM (VALUES
(0, 0, 1, 1, 'A'),
(1, 1, 2, 1, 'A'),
(2, 1, 3, 0, 'A'),
Expand All @@ -50,12 +63,22 @@ WITH edges(x, y, xend, yend, type) AS (VALUES
(2, 2, 3, 3, 'B'),
(1, 1, 1, 2, 'C'),
(2, 2, 2, 1, 'C')
)
) t(x, y, xend, yend, type);

VISUALISE x, y, xend, yend FROM edges
DRAW segment
MAPPING type AS stroke
```

For directional graphs, it makes sense to use arrows to indicate the direction.

```{ggsql}
VISUALISE x, y, xend, yend FROM edges
DRAW segment
MAPPING type AS stroke
SETTING arrow => 'open'
```

Segments can also draw arbitrary diagonal connections between points. For example, marking a delta between two measurements:

```{ggsql}
Expand Down
109 changes: 109 additions & 0 deletions doc/syntax/scale/aesthetic/arrow.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
title: "Arrow"
---

Arrow aesthetics control the shape and size of arrows at the terminal vertices of lines, and apply to layers that draw lines: [line](../../layer/type/line.qmd), [path](../../layer/type/path.qmd) and [segment](../../layer/type/segment.qmd).
These can be useful if lines represent relations and can be mapped if different types of relations need to be reflected.

There are separate aesthetics for arrows at the start and end of lines.
The `arrow` aesthetic is an alias to control `arrowstart` and `arrowend` shapes simultaneously.
The `arrowsize` aesthethic is ditto an alias to control `arrowstartsize` and `arrowendsize` sizes together.
The start and ends of lines are declared directly in segment layers, whereas line and path layers count the first and last observation in a group.

## Literal values
Arrow shapes are specified using named patterns.

| Name | Pattern | Description |
|------|---------|-------------|
| `open` | ![](examples/arrow_open.svg) | V-shape: two strokes converging on the tip |
| `closed` | ![](examples/arrow_closed.svg) | Fatter filled isosceles triangle |
| `stealth` | ![](examples/arrow_stealth.svg) | Dart/chevron as filled concave quadrilateral, thinner in the style of TikZ graphics |
| `latex` | ![](examples/arrow_latex.svg) | Dart/chevron as filled concave quadrilateral, fatter in the style of LaTeX |
| `thin` | ![](examples/arrow_thin.svg) | Thinner filled isosceles triangle |
| `wedge` | ![](examples/arrow_wedge.svg) | Asymmetric triangle |
| `fishtail` | ![](examples/arrow_fishtail.svg) | Inverted V-shape: two strokes diverging as tail |
| `fork` | ![](examples/arrow_fork.svg) | Wider inverted V-shape as tail |
| `feather` | ![](examples/arrow_feather.svg) | Stylised arrow fletching |
| `bar` | ![](examples/arrow_bar.svg) | Orthogonal line at tip |
| `bracket` | ![](examples/arrow_bracket.svg) | Bar with two right-angle protrusions at its ends |
| `cross` | ![](examples/arrow_cross.svg) | Square (Greek) cross angled at 45&deg; from the line |
| `dot` | ![](examples/arrow_dot.svg) | Filled circle |
| `square` | ![](examples/arrow_square.svg) | Filled square |
| `diamond` | ![](examples/arrow_diamond.svg) | Filled diamond |

You can use these names directly when setting the arrow of a line.
Note that the `arrow` setting is an aesthetic alias to set both the `arrowstart` and `arrowend` aesthetics.
You can separate the arrow shapes by using the more specific aesthetics.

```ggsql
DRAW segment
SETTING arrowstart => 'open', arrowend => 'closed'
```

The `arrowsize` and `arrowstartsize`/`arrowendsize` aesthetics are given in bare numbers.
While individual shapes might deviate, the sizes are roughly in points.
Note that the `arrowsize` aesthetics are irrelevant when `arrow` has not been declared.
The following code sets the size of arrows to 20pt.

```ggsql
DRAW segment
SETTING arrow => 'open', arrowsize => 20
```

## Palettes

```{ggsql}
#| code-fold: true
#| code-summary: "Create example data"
CREATE TEMP TABLE edges AS
SELECT * FROM (VALUES
(0, 0, 1, 1, 'Bottom'),
(1, 1, 2, 1, 'Bottom'),
(2, 1, 3, 0, 'Bottom'),
(0, 3, 1, 2, 'Top'),
(1, 2, 2, 2, 'Top'),
(2, 2, 3, 3, 'Top'),
(1, 1, 1, 2, 'Cross'),
(2, 2, 2, 1, 'Cross')
) t(x, y, xend, yend, type);
```

The default palette for arrows picks the 15 arrows listed above.

```{ggsql}
VISUALISE x, y, xend, yend FROM edges
DRAW segment
MAPPING type AS arrowend
SETTING arrowsize => 10
```

You can change the arrows by providing a manual palette with shape names as the `TO` clause in scales.

```{ggsql}
VISUALISE x, y, xend, yend FROM edges
DRAW segment
MAPPING type AS arrowstart
SETTING arrowsize => 10
SCALE arrow TO ['latex', 'cross', 'open']
```

You can use different arrows for the start and end by using the specific `arrowstart` and `arrowend` scales for the aesthetics.

```{ggsql}
VISUALISE x, y, xend, yend FROM edges
DRAW segment
MAPPING type AS arrow
SETTING arrowsize => 10
SCALE arrowstart TO ['latex', 'cross', 'open']
SCALE arrowend TO ['wedge', 'dot', 'feather']
```

The `arrowsize` aesthetic takes numeric values and re-scales these to match the `TO` clause.

```{ggsql}
VISUALISE x, y, xend, yend FROM edges
DRAW segment
MAPPING x AS arrowsize
SETTING arrow => 'closed'
SCALE arrowsize TO (5, 20)
```
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_bar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_bracket.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_closed.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_cross.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_diamond.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_dot.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_feather.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_fishtail.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_fork.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_latex.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_open.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_square.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_stealth.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_thin.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions doc/syntax/scale/aesthetic/examples/arrow_wedge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading