Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source pure

Package sparkline renders a numeric series as one line of Unicode block characters — ▁▂▃▄▅▆▇█ — so a realm's Render c...

Readme View source

gno.land/p/moul/x/daily/sparkline/v0

Sparklines: a numeric series as one line of block charactersInts, Scaled, Level, Bounds, Levels, Steps.

1import "gno.land/p/moul/x/daily/sparkline/v0"
2
3sparkline.Ints([]int{3, 5, 9, 14, 12, 18, 25, 21, 16, 11, 7, 4})
4// ▁▁▂▄▃▅█▆▅▃▂▁   scaled between the series' own min and max
5
6sparkline.Scaled(pct, 0, 100)   // fixed window; outliers clamp to the ends

A realm's Render returns markdown, so a trend normally means an image, a chart library, or client-side code — none of which a realm has. Eight block runes and one line of text do the job, and gnoweb needs nothing to display them.

Everything is integer math, deliberately. Render output has to be byte-identical on every validating node, and floating point is the usual way that quietly stops being true. Scaling is integer division with floor rounding.

Three behaviours worth knowing before you use it:

  • A flat series renders mid-ramp (▅▅▅▅), not along the floor. A series sitting unchanged at 1000 has no shape, but drawing it at the bottom would claim it was zero — a different thing, and a wrong one.
  • Scaled clamps instead of failing. A window is chosen for readability (0..100 for a percentage), and one outlier should not be able to flatten the rest of the picture or break the Render that drew it.
  • Rounding is floor, so only a value at the maximum itself reaches . The peak of a series is always visually distinct.

Level is total: every input maps into [0, Steps), including the extremes where the scaling arithmetic would otherwise wrap. That matters because Scaled indexes the ramp with it — an out-of-range result would panic the calling realm, so it is tested against minInt/maxInt windows directly.

Rendering is O(len(values)). A realm should slice its series to a window rather than sparking an unbounded, user-grown slice.

Live demo: r/moul/x/daily/sparklinedemo · render it at /r/moul/x/daily/sparklinedemo/v0.


Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.

Overview

Package sparkline renders a numeric series as one line of Unicode block characters — ▁▂▃▄▅▆▇█ — so a realm's Render can show a trend inline, with no image, no chart library and no client-side code.

Everything is integer math, deliberately. A realm's Render must produce byte-identical output on every validating node, and floating point is the usual way that quietly stops being true. Scaling here is integer division with the rounding rule stated below, so a given series always yields exactly the same runes.

Rendering is O(len(values)) and allocates one builder; a realm should bound what it feeds in (slice to a window) rather than sparking an unbounded, user-grown slice.

A live demo of this package is at r/moul/x/daily/sparklinedemo(/r/moul/x/daily/sparklinedemo/v0).

Constants 2

const Levels

1const Levels = "▁▂▃▄▅▆▇█"
source

Levels is the ramp, lowest to highest. A string constant rather than a []rune so callers cannot mutate the ramp out from under other realms.

const Steps

1const Steps = 8
source

Steps is how many levels the ramp has.

Functions 4

func Bounds

1func Bounds(values []int) (lo, hi int, ok bool)
source

Bounds returns the smallest and largest value in values. ok is false when values is empty, in which case lo and hi are zero.

func Ints

1func Ints(values []int) string
source

Ints renders values scaled between their own smallest and largest element. An empty series renders as the empty string.

func Level

1func Level(v, lo, hi int) int
source

Level maps v within [lo, hi] to a ramp index in [0, Steps-1].

Rounding is floor, so only a value at hi itself reaches the top of the ramp; everything below it rounds down. That makes the maximum visually distinct, which is what a reader is looking for in a sparkline.

A flat window (hi <= lo) maps everything to the MIDDLE of the ramp, not the bottom: a series that sits unchanged at 1000 carries no shape, but drawing it along the floor would read as "zero", which is a different and wrong claim.

func Scaled

1func Scaled(values []int, lo, hi int) string
source

Scaled renders values against an explicit [lo, hi] window. Values outside it clamp to the ends rather than erroring: a window is chosen for readability (0..100 for a percentage, say), and one outlier should not be able to break a realm's Render.

A window with hi <= lo is treated as flat; see Level.

Imports 1

  • strings stdlib

Source Files 3