-module(sparklinekit@unicode). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/sparklinekit/unicode.gleam"). -export([render/1, render_ints/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Unicode-block sparklines for terminal output.\n" "\n" " ```gleam\n" " import sparklinekit/unicode\n" "\n" " pub fn shape() -> String {\n" " unicode.render([1.0, 5.0, 22.0, 13.0, 5.0, 2.0, 7.0])\n" " // -> \"▁▂█▅▂▁▃\"\n" " }\n" " ```\n" "\n" " The eight block characters `▁▂▃▄▅▆▇█` partition the value range\n" " into eight equal levels. Empty input returns `\"\"`. A single value,\n" " or a series where every value is the same, renders as a flat line\n" " at the middle level (`▄`).\n" ). -file("src/sparklinekit/unicode.gleam", 68). -spec block_for(float(), float(), float()) -> binary(). block_for(Value, Lo, Hi) -> Normalized = sparklinekit@internal@scale:unit(Value, Lo, Hi), Raw = begin _pipe = Normalized * erlang:float(8 - 1), erlang:round(_pipe) end, Index = sparklinekit@internal@scale:clamp_int(Raw, 0, 8 - 1), gleam@string:slice(<<"▁▂▃▄▅▆▇█"/utf8>>, Index, 1). -file("src/sparklinekit/unicode.gleam", 64). -spec middle_block() -> binary(). middle_block() -> gleam@string:slice(<<"▁▂▃▄▅▆▇█"/utf8>>, 3, 1). -file("src/sparklinekit/unicode.gleam", 38). ?DOC( " Render `values` as a string of Unicode block characters.\n" "\n" " - `[]` produces `\"\"`.\n" " - `[v]` produces a single middle-level block (`▄`).\n" " - All-equal inputs produce a string of middle-level blocks.\n" " - Otherwise each value is mapped into one of eight levels by\n" " normalising against the observed minimum and maximum.\n" "\n" " Use [`render_ints`](#render_ints) if your data series is `List(Int)`.\n" ). -spec render(list(float())) -> binary(). render(Values) -> case Values of [] -> <<""/utf8>>; [_] -> middle_block(); _ -> {Lo, Hi} = sparklinekit@internal@scale:min_max(Values), case Lo =:= Hi of true -> _pipe = Values, _pipe@1 = gleam@list:map( _pipe, fun(_) -> middle_block() end ), erlang:list_to_binary(_pipe@1); false -> _pipe@2 = Values, _pipe@3 = gleam@list:map( _pipe@2, fun(Value) -> block_for(Value, Lo, Hi) end ), erlang:list_to_binary(_pipe@3) end end. -file("src/sparklinekit/unicode.gleam", 60). ?DOC( " Convenience wrapper around [`render/1`](#render) for `List(Int)`\n" " inputs. Equivalent to `render(list.map(values, int.to_float))`.\n" ). -spec render_ints(list(integer())) -> binary(). render_ints(Values) -> render(gleam@list:map(Values, fun erlang:float/1)).