From 8f49870113b34fb75281df6d7450a3f4594edc1f Mon Sep 17 00:00:00 2001 From: Roman Galochkin Date: Wed, 26 Feb 2020 13:31:34 +0300 Subject: [PATCH 1/7] Adds a route --- src/App.re | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/App.re b/src/App.re index 8b6ef967..08c337fb 100644 --- a/src/App.re +++ b/src/App.re @@ -1,11 +1,13 @@ type route = | Model(string) + | FormBuilder | Home | NotFound; let routeToPath = route => switch (route) { - | Model(i) => "/m/" ++ i + | Model(modelId) => "/m/" ++ modelId + | FormBuilder => "/form-builder" | Home => "/" | _ => "/" }; @@ -66,11 +68,14 @@ module Menu = { {"Home" |> E.ste} {Models.all |> E.A.fmap((model: Prop.Model.t) => { - + {model.name |> E.ste} }) |> ReasonReact.array} + + {"Form Builder" |> E.ste} + ; }; }; @@ -82,6 +87,7 @@ let make = () => { let routing = switch (url.path) { | ["m", modelId] => Model(modelId) + | ["form-builder"] => FormBuilder | [] => Home | _ => NotFound }; @@ -89,13 +95,14 @@ let make = () => {
{switch (routing) { - | Model(n) => - switch (Models.getById(n)) { - | Some(model) => + | Model(id) => + switch (Models.getById(id)) { + | Some(model) => | None =>
{"Page is not found" |> E.ste}
} + | FormBuilder =>
{"Form Builder" |> E.ste}
| Home =>
{"Welcome" |> E.ste}
| _ =>
{"Page is not found" |> E.ste}
}}
; -}; \ No newline at end of file +}; From 09e0714ec4e4bde28517e6d752b6a66a561728bc Mon Sep 17 00:00:00 2001 From: Roman Galochkin Date: Wed, 26 Feb 2020 13:38:29 +0300 Subject: [PATCH 2/7] Adds a component --- src/DistBuilder.re | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/DistBuilder.re diff --git a/src/DistBuilder.re b/src/DistBuilder.re new file mode 100644 index 00000000..eccc3cce --- /dev/null +++ b/src/DistBuilder.re @@ -0,0 +1,63 @@ +open BsReform; + +module FormConfig = [%lenses + type state = { + name: string, + description: string, + picture: string, + } +]; + +module Form = ReForm.Make(FormConfig); + +let schema = Form.Validation.Schema([||]); + +module FieldString = { + [@react.component] + let make = (~field, ~label) => { + + E.ste}> + validate()} + /> + + } + />; + }; +}; + +[@react.component] +let make = () => { + let reform = + Form.use( + ~validationStrategy=OnDemand, + ~schema, + ~onSubmit=({state}) => {None}, + ~initialState={name: "", description: "", picture: ""}, + (), + ); + + let onSubmit = e => { + e->ReactEvent.Synthetic.preventDefault; + reform.submit(); + }; + + + + + + + + {reform.state.formState == Submitting + ? "Loading" |> E.ste + : + {"Submit" |> E.ste} + } + + + ; +}; From 4daa45962debf6ca89a9a5530d328c806513b74d Mon Sep 17 00:00:00 2001 From: Roman Galochkin Date: Wed, 26 Feb 2020 15:21:30 +0300 Subject: [PATCH 3/7] Adds a inputs --- src/App.re | 12 ++-- src/DistBuilder.re | 139 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 138 insertions(+), 13 deletions(-) diff --git a/src/App.re b/src/App.re index 08c337fb..95c76f31 100644 --- a/src/App.re +++ b/src/App.re @@ -1,13 +1,13 @@ type route = | Model(string) - | FormBuilder + | DistBuilder | Home | NotFound; let routeToPath = route => switch (route) { | Model(modelId) => "/m/" ++ modelId - | FormBuilder => "/form-builder" + | DistBuilder => "/dist-builder" | Home => "/" | _ => "/" }; @@ -73,8 +73,8 @@ module Menu = {
}) |> ReasonReact.array} - - {"Form Builder" |> E.ste} + + {"Dist Builder" |> E.ste} ; }; @@ -87,7 +87,7 @@ let make = () => { let routing = switch (url.path) { | ["m", modelId] => Model(modelId) - | ["form-builder"] => FormBuilder + | ["dist-builder"] => DistBuilder | [] => Home | _ => NotFound }; @@ -100,7 +100,7 @@ let make = () => { | Some(model) => | None =>
{"Page is not found" |> E.ste}
} - | FormBuilder =>
{"Form Builder" |> E.ste}
+ | DistBuilder => | Home =>
{"Welcome" |> E.ste}
| _ =>
{"Page is not found" |> E.ste}
}} diff --git a/src/DistBuilder.re b/src/DistBuilder.re index eccc3cce..b1984b11 100644 --- a/src/DistBuilder.re +++ b/src/DistBuilder.re @@ -2,9 +2,15 @@ open BsReform; module FormConfig = [%lenses type state = { - name: string, - description: string, - picture: string, + guesstimatorString: string, + // + domainType: string, // Complete, LeftLimited(...), RightLimited(...), LeftAndRightLimited(..., ...) + xPoint: string, + excludingProbabilityMass: string, + // + unitType: string, // UnspecifiedDistribution, TimeDistribution(zero, unit) + zero: MomentRe.Moment.t, + unit: string, } ]; @@ -30,6 +36,24 @@ module FieldString = { }; }; +module FieldFloat = { + [@react.component] + let make = (~field, ~label) => { + + E.ste}> + validate()} + /> + + } + />; + }; +}; + [@react.component] let make = () => { let reform = @@ -37,7 +61,15 @@ let make = () => { ~validationStrategy=OnDemand, ~schema, ~onSubmit=({state}) => {None}, - ~initialState={name: "", description: "", picture: ""}, + ~initialState={ + guesstimatorString: "mm(5 to 20, floor(normal(20,2)), [.5, .5])", + domainType: "Complete", + xPoint: "0.0", + excludingProbabilityMass: "", + unitType: "UnspecifiedDistribution", + zero: MomentRe.momentNow(), + unit: "days", + }, (), ); @@ -48,9 +80,102 @@ let make = () => { - - - + + + E.ste}> + e |> handleChange}> + + {"Complete" |> E.ste} + + + {"LeftLimited" |> E.ste} + + + {"RightLimited" |> E.ste} + + + {"LeftAndRightLimited" |> E.ste} + + + + } + /> + + + + E.ste}> + e |> handleChange}> + + {"UnspecifiedDistribution" |> E.ste} + + + {"TimeDistribution" |> E.ste} + + + + } + /> + + E.ste}> + { + e |> handleChange; + + _ => (); + }} + /> + + } + /> + + E.ste}> + e |> handleChange}> + + {"days" |> E.ste} + + + {"hours" |> E.ste} + + + {"milliseconds" |> E.ste} + + + {"minutes" |> E.ste} + + + {"months" |> E.ste} + + + {"quarters" |> E.ste} + + + {"seconds" |> E.ste} + + + {"weeks" |> E.ste} + + + {"years" |> E.ste} + + + + } + /> {reform.state.formState == Submitting ? "Loading" |> E.ste From b37d052b4f651db9af9437734490366ed53f1153 Mon Sep 17 00:00:00 2001 From: Roman Galochkin Date: Wed, 26 Feb 2020 15:33:30 +0300 Subject: [PATCH 4/7] Adds a flex --- src/DistBuilder.re | 202 +++++++++++++++++++++++++-------------------- 1 file changed, 111 insertions(+), 91 deletions(-) diff --git a/src/DistBuilder.re b/src/DistBuilder.re index b1984b11..d951856a 100644 --- a/src/DistBuilder.re +++ b/src/DistBuilder.re @@ -36,6 +36,12 @@ module FieldString = { }; }; +module Styles = { + open Css; + let row = + style([display(`flex), selector("div > div", [flex(`num(1.))])]); +}; + module FieldFloat = { [@react.component] let make = (~field, ~label) => { @@ -84,98 +90,112 @@ let make = () => { field=FormConfig.GuesstimatorString label="GuesstimatorString" /> - - E.ste}> - e |> handleChange}> - - {"Complete" |> E.ste} - - - {"LeftLimited" |> E.ste} - - - {"RightLimited" |> E.ste} - - - {"LeftAndRightLimited" |> E.ste} - - - - } - /> - - - - E.ste}> - e |> handleChange}> - - {"UnspecifiedDistribution" |> E.ste} - - - {"TimeDistribution" |> E.ste} - - - - } - /> - - E.ste}> - { - e |> handleChange; +
+
+ + E.ste}> + e |> handleChange}> + + {"Complete" |> E.ste} + + + {"LeftLimited" |> E.ste} + + + {"RightLimited" |> E.ste} + + + {"LeftAndRightLimited" |> E.ste} + + + + } + /> +
+
+
+ +
+
+
+
+ + E.ste}> + e |> handleChange}> + + {"UnspecifiedDistribution" |> E.ste} + + + {"TimeDistribution" |> E.ste} + + + + } + /> +
+
+ + E.ste}> + { + e |> handleChange; - _ => (); - }} - /> - - } - /> - - E.ste}> - e |> handleChange}> - - {"days" |> E.ste} - - - {"hours" |> E.ste} - - - {"milliseconds" |> E.ste} - - - {"minutes" |> E.ste} - - - {"months" |> E.ste} - - - {"quarters" |> E.ste} - - - {"seconds" |> E.ste} - - - {"weeks" |> E.ste} - - - {"years" |> E.ste} - - - - } - /> + _ => (); + }} + /> + + } + /> +
+
+ + E.ste}> + e |> handleChange}> + + {"days" |> E.ste} + + + {"hours" |> E.ste} + + + {"milliseconds" |> E.ste} + + + {"minutes" |> E.ste} + + + {"months" |> E.ste} + + + {"quarters" |> E.ste} + + + {"seconds" |> E.ste} + + + {"weeks" |> E.ste} + + + {"years" |> E.ste} + + + + } + /> +
+
{reform.state.formState == Submitting ? "Loading" |> E.ste From 746d74da9688f0d1b3e3e0de2b7cd276324ff389 Mon Sep 17 00:00:00 2001 From: Roman Galochkin Date: Wed, 26 Feb 2020 15:55:19 +0300 Subject: [PATCH 5/7] Adds spacer --- src/DistBuilder.re | 298 ++++++++++++++++++++------------- src/distributions/TimeTypes.re | 16 +- 2 files changed, 192 insertions(+), 122 deletions(-) diff --git a/src/DistBuilder.re b/src/DistBuilder.re index d951856a..fd0b0cd2 100644 --- a/src/DistBuilder.re +++ b/src/DistBuilder.re @@ -40,6 +40,8 @@ module Styles = { open Css; let row = style([display(`flex), selector("div > div", [flex(`num(1.))])]); + let form = style([backgroundColor(hex("eee")), padding(em(1.))]); + let spacer = style([marginTop(em(3.))]); }; module FieldFloat = { @@ -70,8 +72,8 @@ let make = () => { ~initialState={ guesstimatorString: "mm(5 to 20, floor(normal(20,2)), [.5, .5])", domainType: "Complete", - xPoint: "0.0", - excludingProbabilityMass: "", + xPoint: "50.0", + excludingProbabilityMass: "0.3", unitType: "UnspecifiedDistribution", zero: MomentRe.momentNow(), unit: "days", @@ -84,125 +86,179 @@ let make = () => { reform.submit(); }; - - - -
-
- - E.ste}> - e |> handleChange}> - - {"Complete" |> E.ste} - - - {"LeftLimited" |> E.ste} - - - {"RightLimited" |> E.ste} - - - {"LeftAndRightLimited" |> E.ste} - - - - } - /> -
-
-
- -
-
-
-
- - E.ste}> - e |> handleChange}> - - {"UnspecifiedDistribution" |> E.ste} - - - {"TimeDistribution" |> E.ste} - - - - } - /> -
-
- - E.ste}> - { - e |> handleChange; + let domain = + switch (reform.state.values.domainType) { + | "Complete" => DistTypes.Complete + | "LeftLimited" => + LeftLimited({ + xPoint: reform.state.values.xPoint |> float_of_string, + excludingProbabilityMass: + reform.state.values.excludingProbabilityMass |> float_of_string, + }) + | "RightLimited" => + RightLimited({ + xPoint: reform.state.values.xPoint |> float_of_string, + excludingProbabilityMass: + reform.state.values.excludingProbabilityMass |> float_of_string, + }) + | "LeftAndRightLimited" => + LeftAndRightLimited( + { + xPoint: reform.state.values.xPoint |> float_of_string, + excludingProbabilityMass: + reform.state.values.excludingProbabilityMass |> float_of_string, + }, + { + xPoint: reform.state.values.xPoint |> float_of_string, + excludingProbabilityMass: + reform.state.values.excludingProbabilityMass |> float_of_string, + }, + ) + | _ => Js.Exn.raiseError("domain is unknown") + }; - _ => (); - }} - /> - - } - /> -
-
- - E.ste}> - e |> handleChange}> - - {"days" |> E.ste} - - - {"hours" |> E.ste} - - - {"milliseconds" |> E.ste} - - - {"minutes" |> E.ste} - - - {"months" |> E.ste} - - - {"quarters" |> E.ste} - - - {"seconds" |> E.ste} - - - {"weeks" |> E.ste} - - - {"years" |> E.ste} - - - - } - /> -
+ let unit = + switch (reform.state.values.unitType) { + | "UnspecifiedDistribution" => DistTypes.UnspecifiedDistribution + | "TimeDistribution" => + TimeDistribution({ + zero: reform.state.values.zero, + unit: reform.state.values.unit |> TimeTypes.TimeUnit.ofString, + }) + | _ => Js.Exn.raiseError("unit is unknown") + }; + + let guesstimatorString = reform.state.values.guesstimatorString; + +
+
+
+
+ {DistPlusIngredients.make(~guesstimatorString, ~domain, ~unit, ()) + |> DistPlusIngredients.toDistPlus( + ~sampleCount=10000, + ~outputXYPoints=2000, + ~truncateTo=Some(1000), + ) + |> E.O.React.fmapOrNull(distPlus => )}
- - {reform.state.formState == Submitting - ? "Loading" |> E.ste - : - {"Submit" |> E.ste} - } - - - ; +
+
+
+ + + +
+
+ + E.ste}> + e |> handleChange}> + + {"Complete" |> E.ste} + + + {"LeftLimited" |> E.ste} + + + {"RightLimited" |> E.ste} + + + {"LeftAndRightLimited" |> E.ste} + + + + } + /> +
+
+
+ +
+
+
+
+ + E.ste}> + e |> handleChange}> + + {"UnspecifiedDistribution" |> E.ste} + + + {"TimeDistribution" |> E.ste} + + + + } + /> +
+
+ + E.ste}> + { + e |> handleChange; + + _ => (); + }} + /> + + } + /> +
+
+ + E.ste}> + e |> handleChange}> + + {"days" |> E.ste} + + + {"hours" |> E.ste} + + + {"milliseconds" |> E.ste} + + + {"minutes" |> E.ste} + + + {"months" |> E.ste} + + + {"quarters" |> E.ste} + + + {"seconds" |> E.ste} + + + {"weeks" |> E.ste} + + + {"years" |> E.ste} + + + + } + /> +
+
+
+
+
+
; }; diff --git a/src/distributions/TimeTypes.re b/src/distributions/TimeTypes.re index 7a8368e0..3340ea32 100644 --- a/src/distributions/TimeTypes.re +++ b/src/distributions/TimeTypes.re @@ -33,6 +33,20 @@ module TimeUnit = { | `weeks => "weeks" | `years => "years" }; + + let ofString = (timeUnit: string) => + switch (timeUnit) { + | "days" => `days + | "hours" => `hours + | "milliseconds" => `milliseconds + | "minutes" => `minutes + | "months" => `months + | "quarters" => `quarters + | "seconds" => `seconds + | "weeks" => `weeks + | "years" => `years + | _ => Js.Exn.raiseError("TimeUnit is unknown") + }; }; module TimePoint = { @@ -72,4 +86,4 @@ module RelativeTimePoint = { | Time(r) => _timeToX(r, timeVector.zero, timeVector.unit) | XValue(r) => r }; -}; \ No newline at end of file +}; From a9730c7480edfba82176cc2966396bfff46e0a7b Mon Sep 17 00:00:00 2001 From: Roman Galochkin Date: Wed, 26 Feb 2020 15:58:56 +0300 Subject: [PATCH 6/7] Adds spacer --- src/DistBuilder.re | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/DistBuilder.re b/src/DistBuilder.re index fd0b0cd2..fc5d891d 100644 --- a/src/DistBuilder.re +++ b/src/DistBuilder.re @@ -6,7 +6,9 @@ module FormConfig = [%lenses // domainType: string, // Complete, LeftLimited(...), RightLimited(...), LeftAndRightLimited(..., ...) xPoint: string, + xPoint2: string, excludingProbabilityMass: string, + excludingProbabilityMass2: string, // unitType: string, // UnspecifiedDistribution, TimeDistribution(zero, unit) zero: MomentRe.Moment.t, @@ -73,6 +75,8 @@ let make = () => { guesstimatorString: "mm(5 to 20, floor(normal(20,2)), [.5, .5])", domainType: "Complete", xPoint: "50.0", + xPoint2: "60.0", + excludingProbabilityMass2: "0.5", excludingProbabilityMass: "0.3", unitType: "UnspecifiedDistribution", zero: MomentRe.momentNow(), @@ -109,9 +113,9 @@ let make = () => { reform.state.values.excludingProbabilityMass |> float_of_string, }, { - xPoint: reform.state.values.xPoint |> float_of_string, + xPoint: reform.state.values.xPoint2 |> float_of_string, excludingProbabilityMass: - reform.state.values.excludingProbabilityMass |> float_of_string, + reform.state.values.excludingProbabilityMass2 |> float_of_string, }, ) | _ => Js.Exn.raiseError("domain is unknown") @@ -162,24 +166,35 @@ let make = () => { {"Complete" |> E.ste} - {"LeftLimited" |> E.ste} + {"Left Limited" |> E.ste} - {"RightLimited" |> E.ste} + {"Right Limited" |> E.ste} - {"LeftAndRightLimited" |> E.ste} + {"Left And Right Limited" |> E.ste} } />
-
+
+ +
+
+
+ +
+
+
@@ -191,10 +206,10 @@ let make = () => { E.ste}> e |> handleChange}> - {"UnspecifiedDistribution" |> E.ste} + {"Unspecified Distribution" |> E.ste} - {"TimeDistribution" |> E.ste} + {"Time Distribution" |> E.ste} @@ -210,7 +225,6 @@ let make = () => { value onChange={e => { e |> handleChange; - _ => (); }} /> From 5c204f7244e7fe239fe2f6b6c8ee3fa74587dc3b Mon Sep 17 00:00:00 2001 From: Roman Galochkin Date: Wed, 26 Feb 2020 15:59:31 +0300 Subject: [PATCH 7/7] Adds spacer --- src/{ => components}/DistBuilder.re | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{ => components}/DistBuilder.re (100%) diff --git a/src/DistBuilder.re b/src/components/DistBuilder.re similarity index 100% rename from src/DistBuilder.re rename to src/components/DistBuilder.re