From cd5680f2dc034d7bfcf4d7e40914778c29a99590 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 29 Mar 2022 16:31:08 -0400 Subject: [PATCH] Refactored Sparklines.res --- .../squiggle-lang/__tests__/Symbolic_test.res | 3 +- .../squiggle-lang/src/rescript/utility/E.res | 6 ++- .../src/rescript/utility/Sparklines.res | 38 +++++++++---------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Symbolic_test.res b/packages/squiggle-lang/__tests__/Symbolic_test.res index bac4d17b..8ec3be22 100644 --- a/packages/squiggle-lang/__tests__/Symbolic_test.res +++ b/packages/squiggle-lang/__tests__/Symbolic_test.res @@ -22,13 +22,12 @@ describe("Normal distribution with sparklines", () => { let normalDistAtMean5: SymbolicDistTypes.normal = {mean: 5.0, stdev: 2.0} let normalDistAtMean10: SymbolicDistTypes.normal = {mean: 10.0, stdev: 2.0} - let range20Float = E.A.rangeFloat(0, 20) // [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,] + let range20Float = E.A.rangeFloat(0, 20) // [0.0,1.0,2.0,3.0,4.0,...19.0,] let pdfNormalDistAtMean5 = x => Normal.pdf(x, normalDistAtMean5) let sparklineMean5 = pdfImage(pdfNormalDistAtMean5, range20Float) makeTest("mean=5", Sparklines.create(sparklineMean5, ()), `▁▂▃▅███▅▃▂▁▁▁▁▁▁▁▁▁▁▁`) let sparklineMean15 = normalDistAtMean5 -> parameterWiseAdditionHelper(normalDistAtMean10) -> pdfImage(range20Float) - // let sparklineMean15 = pdfImage(pdfNormalDistAtMean15, range20Float) makeTest("parameter-wise addition of two normal distributions", Sparklines.create(sparklineMean15, ()), `▁▁▁▁▁▁▁▁▁▁▂▃▅▇███▇▅▃▂`) }) diff --git a/packages/squiggle-lang/src/rescript/utility/E.res b/packages/squiggle-lang/src/rescript/utility/E.res index eb366a6d..6d2a2ce2 100644 --- a/packages/squiggle-lang/src/rescript/utility/E.res +++ b/packages/squiggle-lang/src/rescript/utility/E.res @@ -269,7 +269,8 @@ module A = { )) |> Rationale.Result.return } - let rangeFloat = (start, stop) => start -> Belt.Array.rangeBy(stop, ~step=1) -> (arr => fmap(Belt.Int.toFloat, arr)) + let rangeFloat = (~step=1, start, stop) => + Belt.Array.rangeBy(start, stop, ~step) |> fmap(Belt.Int.toFloat) // This zips while taking the longest elements of each array. let zipMaxLength = (array1, array2) => { @@ -324,7 +325,7 @@ module A = { } ) let filter = (o, e) => Js.Array.filter(o, e) - let joinWith = (fill, arr) => Js.Array.joinWith(fill, arr) + let joinWith = Js.Array.joinWith module O = { let concatSomes = (optionals: array>): array<'a> => @@ -407,6 +408,7 @@ module A = { : { let _ = Js.Array.push(element, continuous) } + () }) diff --git a/packages/squiggle-lang/src/rescript/utility/Sparklines.res b/packages/squiggle-lang/src/rescript/utility/Sparklines.res index 09e17e37..cc07860f 100644 --- a/packages/squiggle-lang/src/rescript/utility/Sparklines.res +++ b/packages/squiggle-lang/src/rescript/utility/Sparklines.res @@ -3,26 +3,24 @@ // Omitting rgb "fire" style, so no `chalk` dependency // Omitting: NaN handling, special consideration for constant data. -let create = ( - numbers: array, - ~minimum=?, - ~maximum=?, - () -) => { - let ticks = [`▁`, `▂`, `▃`, `▄`, `▅`, `▆`, `▇`, `█`] +let ticks = [`▁`, `▂`, `▃`, `▄`, `▅`, `▆`, `▇`, `█`] - let minimum = E.O.default(Js.Math.minMany_float(numbers), minimum) - let maximum = E.O.default(Js.Math.maxMany_float(numbers), maximum) +let _ticksLength = E.A.length(ticks) - let toHeight = (number: float) => { - let tickIndex = Js.Math.ceil_int((number /. maximum) *. (ticks -> Belt.Array.length -> Belt.Int.toFloat)) - 1 - let tickIndex = if maximum == 0.0 || tickIndex < 0 { - 0 - } else { - tickIndex - } - ticks[tickIndex] - } - - toHeight -> E.A.fmap(numbers) -> (arr => E.A.joinWith("", arr)) +let _heightToTickIndex = (maximum: float, v: float) => { + let v = Js.Math.ceil_int(v /. maximum *. Belt.Int.toFloat(_ticksLength)) - 1 + min(v, 0) +} + +let create = (relativeHeights: array, ~maximum=?, ()) => { + if E.A.length(relativeHeights) === 0 { + "" + } else { + let maximum = maximum |> E.O.default(E.A.max(relativeHeights) |> E.O.toExn("")) + + relativeHeights + |> E.A.fmap(_heightToTickIndex(maximum)) + |> E.A.fmap(r => E.A.get(ticks, r) |> E.O.toExn("")) + |> E.A.joinWith("") + } }