-module(etui@widgets@sparkline).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/etui/widgets/sparkline.gleam").
-export([sparkline_new/1, with_fill/2, with_max/2, with_bg/2, with_period/2, with_modifier/2, with_style/2, render/4]).
-export_type([spark_fill/0, sparkline/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type spark_fill() :: {spark_gradient, list(etui@style:color())} |
{spark_animated, list(etui@style:color())} |
spark_rainbow |
spark_animated_rainbow |
{spark_solid, etui@style:color()}.
-type sparkline() :: {sparkline,
list(integer()),
integer(),
spark_fill(),
etui@style:color(),
etui@style:modifier(),
integer()}.
-file("src/etui/widgets/sparkline.gleam", 43).
-spec sparkline_new(list(integer())) -> sparkline().
sparkline_new(Data) ->
{sparkline,
Data,
0,
{spark_gradient, [{rgb, 0, 180, 255}, {rgb, 0, 255, 180}]},
default,
etui@style:none(),
60}.
-file("src/etui/widgets/sparkline.gleam", 54).
-spec with_fill(sparkline(), spark_fill()) -> sparkline().
with_fill(S, Fill) ->
{sparkline,
erlang:element(2, S),
erlang:element(3, S),
Fill,
erlang:element(5, S),
erlang:element(6, S),
erlang:element(7, S)}.
-file("src/etui/widgets/sparkline.gleam", 58).
-spec with_max(sparkline(), integer()) -> sparkline().
with_max(S, Max) ->
{sparkline,
erlang:element(2, S),
Max,
erlang:element(4, S),
erlang:element(5, S),
erlang:element(6, S),
erlang:element(7, S)}.
-file("src/etui/widgets/sparkline.gleam", 62).
-spec with_bg(sparkline(), etui@style:color()) -> sparkline().
with_bg(S, Bg) ->
{sparkline,
erlang:element(2, S),
erlang:element(3, S),
erlang:element(4, S),
Bg,
erlang:element(6, S),
erlang:element(7, S)}.
-file("src/etui/widgets/sparkline.gleam", 66).
-spec with_period(sparkline(), integer()) -> sparkline().
with_period(S, Period) ->
{sparkline,
erlang:element(2, S),
erlang:element(3, S),
erlang:element(4, S),
erlang:element(5, S),
erlang:element(6, S),
gleam@int:max(1, Period)}.
-file("src/etui/widgets/sparkline.gleam", 70).
-spec with_modifier(sparkline(), etui@style:modifier()) -> sparkline().
with_modifier(S, M) ->
{sparkline,
erlang:element(2, S),
erlang:element(3, S),
erlang:element(4, S),
erlang:element(5, S),
M,
erlang:element(7, S)}.
-file("src/etui/widgets/sparkline.gleam", 74).
-spec with_style(sparkline(), etui@style:style()) -> sparkline().
with_style(S, St) ->
{sparkline,
erlang:element(2, S),
erlang:element(3, S),
erlang:element(4, S),
erlang:element(3, St),
erlang:element(4, St),
erlang:element(7, S)}.
-file("src/etui/widgets/sparkline.gleam", 148).
-spec cell_color(spark_fill(), integer(), integer(), integer(), integer()) -> etui@style:color().
cell_color(Fill, X, Width, Frame, Period) ->
P = gleam@int:max(1, Period),
W = gleam@int:max(1, Width),
case Fill of
{spark_solid, C} ->
C;
{spark_gradient, Stops} ->
etui@color:gradient(Stops, X, W - 1);
{spark_animated, Stops@1} ->
Offset = case P of
0 -> 0;
Gleam@denominator -> Frame * W div Gleam@denominator
end,
etui@color:gradient(Stops@1, case W of
0 -> 0;
Gleam@denominator@1 -> (X + Offset) rem Gleam@denominator@1
end, W - 1);
spark_rainbow ->
etui@color:hue_to_rgb(case W of
0 -> 0;
Gleam@denominator@2 -> X * 360 div Gleam@denominator@2
end);
spark_animated_rainbow ->
etui@color:hue_to_rgb(((case W of
0 -> 0;
Gleam@denominator@3 -> X * 360 div Gleam@denominator@3
end) + (case P of
0 -> 0;
Gleam@denominator@4 -> Frame * 360 div Gleam@denominator@4
end)) rem 360)
end.
-file("src/etui/widgets/sparkline.gleam", 134).
-spec bar_char(integer()) -> binary().
bar_char(Level) ->
case Level of
0 ->
<<" "/utf8>>;
1 ->
<<"▁"/utf8>>;
2 ->
<<"▂"/utf8>>;
3 ->
<<"▃"/utf8>>;
4 ->
<<"▄"/utf8>>;
5 ->
<<"▅"/utf8>>;
6 ->
<<"▆"/utf8>>;
7 ->
<<"▇"/utf8>>;
_ ->
<<"█"/utf8>>
end.
-file("src/etui/widgets/sparkline.gleam", 100).
-spec render_cols(
etui@buffer:buffer(),
etui@geometry:rect(),
sparkline(),
list(integer()),
integer(),
integer(),
integer(),
integer()
) -> etui@buffer:buffer().
render_cols(Buf, Area, S, Data, X, Width, Max, Frame) ->
case X >= Width of
true ->
Buf;
false ->
Val = case Data of
[V | _] ->
V;
[] ->
0
end,
Rest = case Data of
[_ | R] ->
R;
[] ->
[]
end,
Level = gleam@int:min(8, case gleam@int:max(1, Max) of
0 -> 0;
Gleam@denominator -> Val * 8 div Gleam@denominator
end),
Ch = bar_char(Level),
Fg = cell_color(
erlang:element(4, S),
X,
Width,
Frame,
erlang:element(7, S)
),
Pos = {position,
erlang:element(2, erlang:element(2, Area)) + X,
erlang:element(3, erlang:element(2, Area))},
Buf2 = etui@buffer:set_string(
Buf,
Pos,
Ch,
Fg,
erlang:element(5, S),
erlang:element(6, S)
),
render_cols(Buf2, Area, S, Rest, X + 1, Width, Max, Frame)
end.
-file("src/etui/widgets/sparkline.gleam", 82).
?DOC(" Render the sparkline. `frame` drives animated fills.\n").
-spec render(etui@buffer:buffer(), etui@geometry:rect(), sparkline(), integer()) -> etui@buffer:buffer().
render(Buf, Area, S, Frame) ->
case (erlang:element(2, erlang:element(3, Area)) =< 0) orelse (erlang:element(
3,
erlang:element(3, Area)
)
=< 0) of
true ->
Buf;
false ->
Max = case erlang:element(3, S) of
0 ->
gleam@list:fold(
erlang:element(2, S),
1,
fun gleam@int:max/2
);
M ->
gleam@int:max(1, M)
end,
render_cols(
Buf,
Area,
S,
erlang:element(2, S),
0,
erlang:element(2, erlang:element(3, Area)),
Max,
Frame
)
end.