From 5a3e70506cdead41f25d11396b6ad3407e62fe56 Mon Sep 17 00:00:00 2001 From: Johannes Wolf Date: Thu, 5 Dec 2024 01:10:56 +0100 Subject: [PATCH] spine: School-Book add grid lines --- src/axis.typ | 18 ++++++++++++++++-- src/spine/schoolbook.typ | 11 +++++++---- src/spine/scientific.typ | 17 +++++++++-------- src/ticks.typ | 27 +++------------------------ 4 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/axis.typ b/src/axis.typ index 378b507..65b8323 100644 --- a/src/axis.typ +++ b/src/axis.typ @@ -1,6 +1,19 @@ #import "/src/ticks.typ" #import "/src/plot/util.typ" +// Grid modes +#let _get-grid-mode(mode) = { + return if mode == true or mode == "major" { + 1 + } else if mode == "minor" { + 2 + } else if mode == "both" { + 3 + } else { + 0 + } +} + /// Transform linear axis value to linear space (low, high) #let _transform-lin(ax, value, low, high) = { let range = high - low @@ -25,7 +38,7 @@ name: name, min: min, max: max, base: 10, transform: _transform-lin, auto-domain: (none, none), ticks: (step: auto, minor-step: none, format: auto, list: none), - grid: none, + grid: 0, compute-ticks: ticks.compute-ticks.with("lin"), ) + options.named() @@ -35,12 +48,13 @@ name: name, min: min, max: max, base: base, transform: _transform-log, auto-domain: (none, none), ticks: (step: auto, minor-step: none, format: auto, list: none), - grid: none, + grid: 0, compute-ticks: ticks.compute-ticks.with("log"), ) + options.named() // Prepare axis #let prepare(ptx, ax) = { + ax.grid = _get-grid-mode(ax.grid) if ax.min == none { ax.min = ax.auto-domain.at(0) } if ax.max == none { ax.max = ax.auto-domain.at(1) } if ax.min == none or ax.max == none { ax.min = -1e-6; ax.max = +1e-6 } diff --git a/src/spine/schoolbook.typ b/src/spine/schoolbook.typ index 9af43e0..9e6c24b 100644 --- a/src/spine/schoolbook.typ +++ b/src/spine/schoolbook.typ @@ -3,6 +3,7 @@ #import "/src/ticks.typ" #import "/src/style.typ": prepare-style, get-axis-style, default-style #import "/src/spine/util.typ": cartesian-axis-projection +#import "/src/spine/grid.typ" #import cetz: vector, draw @@ -19,7 +20,6 @@ ), )) - /// #let schoolbook(projections: none, name: none, zero: (0, 0), ..style) = { return ( @@ -68,7 +68,6 @@ let outset-min-y = vector.scale(outset-lo-y, -1) let outset-max-y = vector.scale(outset-hi-y, +1) - draw.on-layer(x-style.axis-layer, { draw.line((rel: outset-min-x, to: min-x), (rel: outset-max-x, to: max-x), @@ -76,8 +75,10 @@ stroke: x-style.stroke) }) if "computed-ticks" in x { - //ticks.draw-cartesian-grid(grid-proj, grid-dir, ax, ax.computed-ticks, style) + let grid-offset = min-x.at(1) - min-y.at(1) + let grid-length = max-y.at(1) - min-y.at(1) let tick-proj = cartesian-axis-projection(x, min-x, max-x) + grid.draw-cartesian(tick-proj, grid-offset, grid-length, (0,1), x.computed-ticks, style.grid, x.grid) ticks.draw-cartesian(tick-proj, (0,+1), x.computed-ticks, x-style) } @@ -88,8 +89,10 @@ stroke: y-style.stroke) }) if "computed-ticks" in y { - //ticks.draw-cartesian-grid(min-y, max-y, 1, y, y.computed-ticks, min-x, max-x, y-style) + let grid-offset = min-y.at(0) - min-x.at(0) + let grid-length = max-x.at(0) - min-x.at(0) let tick-proj = cartesian-axis-projection(y, min-y, max-y) + grid.draw-cartesian(tick-proj, grid-offset, grid-length, (1,0), y.computed-ticks, style.grid, y.grid) ticks.draw-cartesian(tick-proj, (+1,0), y.computed-ticks, y-style) } } diff --git a/src/spine/scientific.typ b/src/spine/scientific.typ index 6d95797..c17595a 100644 --- a/src/spine/scientific.typ +++ b/src/spine/scientific.typ @@ -3,6 +3,7 @@ #import "/src/ticks.typ" #import "/src/style.typ": prepare-style, get-axis-style, default-style #import "/src/spine/util.typ": cartesian-axis-projection +#import "/src/spine/grid.typ" #import cetz: vector, draw @@ -56,24 +57,24 @@ // Grid lengths let x-grid-length = u-low.at(1) - x-low.at(1) let y-grid-length = v-low.at(0) - y-low.at(0) - let u-grid-length = x-low.at(1) - u-low.at(1) - let v-grid-length = y-low.at(0) - v-low.at(0) + let u-grid-length = u-low.at(1) - x-low.at(1) + let v-grid-length = v-low.at(0) - y-low.at(0) let axes = ( - (x, (0,+1), (0,x-grid-length), cartesian-axis-projection(x, x-low, x-high), x-style, false), - (y, (+1,0), (y-grid-length,0), cartesian-axis-projection(y, y-low, y-high), y-style, false), - (u, (0,-1), (0,u-grid-length), cartesian-axis-projection(u, u-low, u-high), u-style, not has-uv), - (v, (-1,0), (v-grid-length,0), cartesian-axis-projection(v, v-low, v-high), v-style, not has-uv), + (x, (0,+1), x-grid-length, cartesian-axis-projection(x, x-low, x-high), x-style, false), + (y, (+1,0), y-grid-length, cartesian-axis-projection(y, y-low, y-high), y-style, false), + (u, (0,-1), u-grid-length, cartesian-axis-projection(u, u-low, u-high), u-style, not has-uv), + (v, (-1,0), v-grid-length, cartesian-axis-projection(v, v-low, v-high), v-style, not has-uv), ) draw.group(name: "spine", { - for (ax, dir, grid-dir, proj, style, mirror) in axes { + for (ax, dir, grid-length, proj, style, mirror) in axes { draw.on-layer(style.axis-layer, { draw.line(proj(ax.min), proj(ax.max), stroke: style.stroke, mark: style.mark) }) if "computed-ticks" in ax { if not mirror { - ticks.draw-cartesian-grid(proj, grid-dir, ax, ax.computed-ticks, style) + grid.draw-cartesian(proj, 0, grid-length, dir, ax.computed-ticks, style.grid, ax.grid) } ticks.draw-cartesian(proj, dir, ax.computed-ticks, style, is-mirror: mirror) } diff --git a/src/ticks.typ b/src/ticks.typ index e71a489..88ee9be 100644 --- a/src/ticks.typ +++ b/src/ticks.typ @@ -3,6 +3,7 @@ #import "/src/plot/formats.typ" +// TODO: Remove #let _get-grid-mode(mode) = { return if mode in (true, "major") { 1 @@ -15,8 +16,9 @@ } } +// TODO: Remove #let _draw-grid(mode, is-major) = { - return mode >= 3 or (is-major and mode == 1) or mode == 2 + return (2 + int(is-major)).bit-and(mode) } // Format a tick value @@ -312,29 +314,6 @@ }) } -// Draw grid lines for the ticks of an axis -// -#let draw-cartesian-grid(proj, offset, axis, ticks, style) = { - let kind = _get-grid-mode(axis.grid) - if kind > 0 { - draw.on-layer(style.grid-layer, { - for (value, _, major) in ticks { - let start = proj(value) - let end = vector.add(start, offset) - - // Draw a minor line - if not major and kind >= 2 { - draw.line(start, end, stroke: style.grid.minor-stroke) - } - // Draw a major line - if major and (kind == 1 or kind == 3) { - draw.line(start, end, stroke: style.grid.stroke) - } - } - }) - } -} - /// Draw angular polar grid #let draw-angular-grid(projection, ticks, style) = { let (angular, distal, ..) = projection.axes