open DistPlusPlotReducer let plotBlue = #hex("1860ad") let showAsForm = (distPlus: SquiggleLang.PointSetTypes.distPlus) =>
E.O.default("")} />
let showFloat = (~precision=3, number) => let table = (distPlus, x) =>
{"X Point" |> React.string} {"Discrete Value" |> React.string} {"Continuous Value" |> React.string} {"Y Integral to Point" |> React.string} {"Y Integral Total" |> React.string}
{x |> E.Float.toString |> React.string} {distPlus |> SquiggleLang.DistPlus.T.xToY(x) |> SquiggleLang.PointSetTypes.MixedPoint.toDiscreteValue |> Js.Float.toPrecisionWithPrecision(_, ~digits=7) |> React.string} {distPlus |> SquiggleLang.DistPlus.T.xToY(x) |> SquiggleLang.PointSetTypes.MixedPoint.toContinuousValue |> Js.Float.toPrecisionWithPrecision(_, ~digits=7) |> React.string} {distPlus |> SquiggleLang.DistPlus.T.Integral.xToY(x) |> E.Float.with2DigitsPrecision |> React.string} {distPlus |> SquiggleLang.DistPlus.T.Integral.sum |> E.Float.with2DigitsPrecision |> React.string}
{"Continuous Total" |> React.string} {"Discrete Total" |> React.string}
{distPlus |> SquiggleLang.DistPlus.T.toContinuous |> E.O.fmap(SquiggleLang.Continuous.T.Integral.sum) |> E.O.fmap(E.Float.with2DigitsPrecision) |> E.O.default("") |> React.string} {distPlus |> SquiggleLang.DistPlus.T.toDiscrete |> E.O.fmap(SquiggleLang.Discrete.T.Integral.sum) |> E.O.fmap(E.Float.with2DigitsPrecision) |> E.O.default("") |> React.string}
let percentiles = distPlus =>
{"1" |> React.string} {"5" |> React.string} {"25" |> React.string} {"50" |> React.string} {"75" |> React.string} {"95" |> React.string} {"99" |> React.string} {"99.999" |> React.string}
{distPlus |> SquiggleLang.DistPlus.T.Integral.yToX(0.01) |> showFloat} {distPlus |> SquiggleLang.DistPlus.T.Integral.yToX(0.05) |> showFloat} {distPlus |> SquiggleLang.DistPlus.T.Integral.yToX(0.25) |> showFloat} {distPlus |> SquiggleLang.DistPlus.T.Integral.yToX(0.5) |> showFloat} {distPlus |> SquiggleLang.DistPlus.T.Integral.yToX(0.75) |> showFloat} {distPlus |> SquiggleLang.DistPlus.T.Integral.yToX(0.95) |> showFloat} {distPlus |> SquiggleLang.DistPlus.T.Integral.yToX(0.99) |> showFloat} {distPlus |> SquiggleLang.DistPlus.T.Integral.yToX(0.99999) |> showFloat}
{"mean" |> React.string} {"standard deviation" |> React.string} {"variance" |> React.string}
{distPlus |> SquiggleLang.DistPlus.T.mean |> showFloat} {distPlus |> SquiggleLang.DistPlus.T.variance |> (r => r ** 0.5) |> showFloat} {distPlus |> SquiggleLang.DistPlus.T.variance |> showFloat}
let adjustBoth = discreteProbabilityMassFraction => { let yMaxDiscreteDomainFactor = discreteProbabilityMassFraction let yMaxContinuousDomainFactor = 1.0 -. discreteProbabilityMassFraction // use the bigger proportion, such that whichever is the bigger proportion, the yMax is 1. let yMax = yMaxDiscreteDomainFactor > 0.5 ? yMaxDiscreteDomainFactor : yMaxContinuousDomainFactor (yMax /. yMaxDiscreteDomainFactor, yMax /. yMaxContinuousDomainFactor) } module DistPlusChart = { @react.component let make = (~distPlus: SquiggleLang.PointSetTypes.distPlus, ~config: chartConfig, ~onHover) => { open SquiggleLang.DistPlus let discrete = distPlus |> T.toDiscrete |> E.O.fmap(SquiggleLang.Discrete.getShape) let continuous = distPlus |> T.toContinuous |> E.O.fmap(SquiggleLang.Continuous.getShape) // // We subtract a bit from the range to make sure that it fits. Maybe this should be done in d3 instead. // let minX = // switch ( // distPlus // |> DistPlus.T.Integral.yToX(0.0001), // range, // ) { // | (min, Some(range)) => Some(min -. range *. 0.001) // | _ => None // }; let minX = distPlus |> T.Integral.yToX(0.00001) let maxX = distPlus |> T.Integral.yToX(0.99999) let timeScale = distPlus.unit |> SquiggleLang.PointSetTypes.DistributionUnit.toJson let discreteProbabilityMassFraction = distPlus |> T.toDiscreteProbabilityMassFraction let (yMaxDiscreteDomainFactor, yMaxContinuousDomainFactor) = adjustBoth( discreteProbabilityMassFraction, ) } } module IntegralChart = { @react.component let make = (~distPlus: SquiggleLang.PointSetTypes.distPlus, ~config: chartConfig, ~onHover) => { let integral = distPlus.integralCache let continuous = integral |> SquiggleLang.Continuous.toLinear |> E.O.fmap(SquiggleLang.Continuous.getShape) let minX = distPlus |> SquiggleLang.DistPlus.T.Integral.yToX(0.00001) let maxX = distPlus |> SquiggleLang.DistPlus.T.Integral.yToX(0.99999) let timeScale = distPlus.unit |> SquiggleLang.PointSetTypes.DistributionUnit.toJson } } module Chart = { @react.component let make = (~distPlus: SquiggleLang.PointSetTypes.distPlus, ~config: chartConfig, ~onHover) => { let chart = React.useMemo2( () => config.isCumulative ? : , (distPlus, config), )
chart
} } let button = "bg-gray-300 hover:bg-gray-500 text-grey-darkest text-xs px-4 py-1" @react.component let make = (~distPlus: SquiggleLang.PointSetTypes.distPlus) => { let (x, setX) = React.useState(() => 0.) let (state, dispatch) = React.useReducer(DistPlusPlotReducer.reducer, DistPlusPlotReducer.init)
{state.distributions |> E.L.fmapi((index, config) =>
setX(_ => r)} />
{index != 0 ? : React.null}
) |> E.L.toArray |> React.array}
{state.showParams ? showAsForm(distPlus) : React.null} {state.showStats ? table(distPlus, x) : React.null} {state.showPercentiles ? percentiles(distPlus) : React.null}
}