Added ace code editor

This commit is contained in:
Ozzie Gooen 2020-08-10 14:40:40 +01:00
parent c298c42d3f
commit 5d7ffdf2bc
9 changed files with 361 additions and 246 deletions

View File

@ -28,6 +28,7 @@
"dependencies": { "dependencies": {
"@foretold/components": "0.0.6", "@foretold/components": "0.0.6",
"@glennsl/bs-json": "^5.0.2", "@glennsl/bs-json": "^5.0.2",
"ace-builds": "^1.4.12",
"antd": "3.17.0", "antd": "3.17.0",
"autoprefixer": "9.7.4", "autoprefixer": "9.7.4",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
@ -51,6 +52,7 @@
"postcss-cli": "7.1.0", "postcss-cli": "7.1.0",
"rationale": "0.2.0", "rationale": "0.2.0",
"react": "^16.8.0", "react": "^16.8.0",
"react-ace": "^9.1.2",
"react-dom": "^16.8.0", "react-dom": "^16.8.0",
"react-use": "^13.27.0", "react-use": "^13.27.0",
"react-vega": "^7.4.1", "react-vega": "^7.4.1",

View File

@ -73,6 +73,9 @@ module Menu = {
}; };
}; };
let fixedLength = r =>
<div className="w-full max-w-screen-xl mx-auto px-6"> r </div>;
[@react.component] [@react.component]
let make = () => { let make = () => {
let url = ReasonReactRouter.useUrl(); let url = ReasonReactRouter.useUrl();
@ -85,17 +88,20 @@ let make = () => {
| _ => NotFound | _ => NotFound
}; };
<div className="w-full max-w-screen-xl mx-auto px-6"> <>
<Menu /> <Menu />
{switch (routing) { {switch (routing) {
| Model(id) => | Model(id) =>
switch (Models.getById(id)) { (
| Some(model) => <FormBuilder.ModelForm model key=id /> switch (Models.getById(id)) {
| None => <div> {"Page is not found" |> R.ste} </div> | Some(model) => <FormBuilder.ModelForm model key=id />
} | None => <div> {"Page is not found" |> R.ste} </div>
}
)
|> fixedLength
| DistBuilder => <DistBuilder /> | DistBuilder => <DistBuilder />
| Home => <Home /> | Home => <Home />
| _ => <div> {"Page is not found" |> R.ste} </div> | _ => fixedLength({"Page is not found" |> R.ste})
}} }}
</div>; </>;
}; };

View File

@ -0,0 +1,40 @@
import React from "react";
import AceEditor from "react-ace";
import "ace-builds/src-noconflict/mode-golang";
import "ace-builds/src-noconflict/theme-github";
import "ace-builds/src-noconflict/ext-language_tools";
function onChange(newValue) {
console.log("change", newValue);
}
export class CodeEditor extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<AceEditor
value={this.props.value}
mode="golang"
height="400px"
width="100%"
theme="github"
showGutter={false}
highlightActiveLine={false}
showPrintMargin={false}
onChange={this.props.onChange}
name="UNIQUE_ID_OF_DIV"
editorProps={{
$blockScrolling: true,
}}
setOptions={{
enableBasicAutocompletion: false,
enableLiveAutocompletion: false,
enableSnippets: true,
}}
/>
);
}
}

View File

@ -0,0 +1,10 @@
[@bs.module "./CodeEditor.js"]
external codeEditor: ReasonReact.reactClass = "CodeEditor";
[@react.component]
let make = (~value="", ~onChange=(_:string) => (), ~children=ReasonReact.null) =>
ReasonReact.wrapJsForReason(~reactClass=codeEditor, ~props={
"value": value,
"onChange": onChange
}, children)
|> ReasonReact.element;

View File

@ -36,20 +36,14 @@ let schema = Form.Validation.Schema([||]);
module FieldText = { module FieldText = {
[@react.component] [@react.component]
let make = (~field, ~label) => { let make = (~field, ~label) => {
<Form.Field <>
field <Form.Field
render={({handleChange, error, value, validate}) => field
<Antd.Form.Item label={label |> R.ste}> render={({handleChange, error, value, validate}) =>
<Antd.Input.TextArea <CodeEditor value onChange={r => handleChange(r)} />
value }
spellcheck=false />
autosize=true </>;
onChange={BsReform.Helpers.handleChange(handleChange)}
onBlur={_ => validate()}
/>
</Antd.Form.Item>
}
/>;
}; };
}; };
module FieldString = { module FieldString = {
@ -134,7 +128,6 @@ module DemoDist = {
[@react.component] [@react.component]
let make = (~guesstimatorString, ~domain, ~unit, ~options) => { let make = (~guesstimatorString, ~domain, ~unit, ~options) => {
<Antd.Card title={"Distribution" |> R.ste}> <Antd.Card title={"Distribution" |> R.ste}>
<div className=Styles.spacer />
<div> <div>
{switch (domain, unit, options) { {switch (domain, unit, options) {
| (Some(domain), Some(unit), Some(options)) => | (Some(domain), Some(unit), Some(options)) =>
@ -187,7 +180,7 @@ module DemoDist = {
) )
|> E.R.bind(_, a => |> E.R.bind(_, a =>
switch (a) { switch (a) {
| `DistPlus(d) => Ok((r, d)) | `DistPlus(d) => Ok((r, DistPlus.T.normalize(d)))
| _ => Error("") | _ => Error("")
} }
) )
@ -347,53 +340,57 @@ bar",
setReloader(_ => reloader + 1); setReloader(_ => reloader + 1);
}; };
<div className=Styles.parent> <div className="grid grid-cols-2 gap-4">
<div className=Styles.spacer /> <div>
demoDist <Antd.Card
<div className=Styles.spacer /> title={"Distribution Form" |> R.ste}
<Antd.Card extra={
title={"Distribution Form" |> R.ste}
extra={
<Antd.Button
icon=Antd.IconName.reload
shape=`circle
onClick=onReload
/>
}>
<Form.Provider value=reform>
<Antd.Form onSubmit>
<Row _type=`flex className=Styles.rows>
<Col span=24>
<FieldText field=FormConfig.GuesstimatorString label="Program" />
</Col>
</Row>
<Row _type=`flex className=Styles.rows>
<Col span=4>
<FieldFloat field=FormConfig.SampleCount label="Sample Count" />
</Col>
<Col span=4>
<FieldFloat
field=FormConfig.OutputXYPoints
label="Output XY-points"
/>
</Col>
<Col span=4>
<FieldFloat
field=FormConfig.DownsampleTo
label="Downsample To"
/>
</Col>
<Col span=4>
<FieldFloat field=FormConfig.KernelWidth label="Kernel Width" />
</Col>
</Row>
<Antd.Button <Antd.Button
_type=`primary icon=Antd.IconName.reload onClick=onReload> icon=Antd.IconName.reload
{"Update Distribution" |> R.ste} shape=`circle
</Antd.Button> onClick=onReload
</Antd.Form> />
</Form.Provider> }>
</Antd.Card> <Form.Provider value=reform>
<div className=Styles.spacer /> <Antd.Form onSubmit>
<Row _type=`flex className=Styles.rows>
<Col span=24>
<FieldText
field=FormConfig.GuesstimatorString
label="Program"
/>
</Col>
</Row>
<Row _type=`flex className=Styles.rows>
<Col span=12>
<FieldFloat
field=FormConfig.SampleCount
label="Sample Count"
/>
</Col>
<Col span=12>
<FieldFloat
field=FormConfig.OutputXYPoints
label="Output XY-points"
/>
</Col>
<Col span=12>
<FieldFloat
field=FormConfig.DownsampleTo
label="Downsample To"
/>
</Col>
<Col span=12>
<FieldFloat
field=FormConfig.KernelWidth
label="Kernel Width"
/>
</Col>
</Row>
</Antd.Form>
</Form.Provider>
</Antd.Card>
</div>
<div> demoDist </div>
</div>; </div>;
}; };

View File

@ -106,6 +106,6 @@ let init = {
showParams: false, showParams: false,
showPercentiles: false, showPercentiles: false,
distributions: [ distributions: [
{yLog: false, xLog: false, isCumulative: false, height: 1}, {yLog: false, xLog: false, isCumulative: false, height: 4},
], ],
}; };

View File

@ -1,15 +1,10 @@
import * as _ from 'lodash'; import * as _ from "lodash";
import React from 'react'; import { createClassFromSpec } from "react-vega";
import * as vega from 'vega'; import spec from "./spec-percentiles";
import {
createClassFromSpec
} from "react-vega";
import spec from './spec-percentiles';
const PercentilesChart = createClassFromSpec({ const PercentilesChart = createClassFromSpec({
spec spec,
style: "width: 100%",
}); });
export { export { PercentilesChart };
PercentilesChart
};

View File

@ -1,169 +1,208 @@
{ {
"$schema": "https://vega.github.io/schema/vega/v5.json", "$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 900, "width": 500,
"height": 200, "height": 400,
"padding": 5, "padding": 5,
"data": [ "data": [
{ {
"name": "facet", "name": "facet",
"values": [ "values": [],
], "format": { "type": "json", "parse": { "timestamp": "date" } }
"format": { "type": "json", "parse": { "timestamp": "date" } } },
}, {
{ "name": "table",
"name": "table", "source": "facet",
"source": "facet", "transform": [
"transform": [ {
{ "type": "aggregate",
"type": "aggregate", "groupby": ["x"],
"groupby": ["x"], "ops": [
"ops": ["mean","mean","mean","mean","mean", "mean","mean","mean","mean","mean","mean","mean","mean"], "mean",
"fields": ["p1", "p5", "p10", "p20", "p30", "p40", "p50", "p60", "p70", "p80", "p90", "p95", "p99"], "mean",
"as": ["p1", "p5", "p10", "p20", "p30", "p40", "p50", "p60", "p70", "p80", "p90", "p95", "p99"] "mean",
} "mean",
] "mean",
} "mean",
], "mean",
"scales": [ "mean",
{ "mean",
"name": "xscale", "mean",
"type": "linear", "mean",
"nice": true, "mean",
"domain": { "data": "facet", "field": "x"}, "mean"
"range": "width" ],
}, "fields": [
{ "p1",
"name": "yscale", "p5",
"type": "linear", "p10",
"range": "height", "p20",
"nice": true, "p30",
"zero": true, "p40",
"domain": { "data": "facet", "field": "p95" } "p50",
} "p60",
], "p70",
"axes": [ "p80",
{ "p90",
"orient": "bottom", "p95",
"scale": "xscale", "p99"
"grid": false, ],
"title": "X Value", "as": [
"encode": { "p1",
"grid": { "enter": { "stroke": { "value": "#ccc" } } }, "p5",
"ticks": { "enter": { "stroke": { "value": "#ccc" } } } "p10",
"p20",
"p30",
"p40",
"p50",
"p60",
"p70",
"p80",
"p90",
"p95",
"p99"
]
} }
}, ]
{ }
"orient": "left", ],
"scale": "yscale", "scales": [
"title": "Values and Percentiles", {
"grid": false, "name": "xscale",
"domain": false, "type": "linear",
"tickSize": 2, "nice": true,
"encode": { "domain": { "data": "facet", "field": "x" },
"grid": { "enter": { "stroke": { "value": "#ccc" } } }, "range": "width"
"ticks": { "enter": { "stroke": { "value": "#ccc" } } } },
{
"name": "yscale",
"type": "linear",
"range": "height",
"nice": true,
"zero": false,
"domain": { "data": "facet", "field": "p99" }
}
],
"axes": [
{
"orient": "bottom",
"scale": "xscale",
"grid": false,
"tickSize": 2,
"encode": {
"grid": { "enter": { "stroke": { "value": "#ccc" } } },
"ticks": { "enter": { "stroke": { "value": "#ccc" } } }
}
},
{
"orient": "left",
"scale": "yscale",
"grid": false,
"domain": false,
"tickSize": 2,
"encode": {
"grid": { "enter": { "stroke": { "value": "#ccc" } } },
"ticks": { "enter": { "stroke": { "value": "#ccc" } } }
}
}
],
"marks": [
{
"type": "area",
"from": { "data": "table" },
"encode": {
"enter": { "fill": { "value": "#4C78A8" } },
"update": {
"interpolate": { "value": "monotone" },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p1" },
"y2": { "scale": "yscale", "field": "p99" },
"opacity": { "value": 0.05 }
} }
} }
], },
"marks": [ {
{ "type": "area",
"type": "area", "from": { "data": "table" },
"from": { "data": "table" }, "encode": {
"encode": { "enter": { "fill": { "value": "#4C78A8" } },
"enter": { "fill": { "value": "#4C78A8" } }, "update": {
"update": { "interpolate": { "value": "monotone" },
"interpolate": { "value": "monotone" }, "x": { "scale": "xscale", "field": "x" },
"x": { "scale": "xscale", "field": "x" }, "y": { "scale": "yscale", "field": "p5" },
"y": { "scale": "yscale", "field": "p1" }, "y2": { "scale": "yscale", "field": "p95" },
"y2": { "scale": "yscale", "field": "p99" }, "opacity": { "value": 0.1 }
"opacity": { "value": 0.05 }
}
}
},
{
"type": "area",
"from": { "data": "table" },
"encode": {
"enter": { "fill": { "value": "#4C78A8" } },
"update": {
"interpolate": { "value": "monotone" },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p5" },
"y2": { "scale": "yscale", "field": "p95" },
"opacity": { "value": 0.1 }
}
}
},
{
"type": "area",
"from": { "data": "table" },
"encode": {
"enter": { "fill": { "value": "#4C78A8" } },
"update": {
"interpolate": { "value": "monotone" },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p10" },
"y2": { "scale": "yscale", "field": "p90" },
"opacity": { "value": 0.15 }
}
}
},
{
"type": "area",
"from": { "data": "table" },
"encode": {
"enter": { "fill": { "value": "#4C78A8" } },
"update": {
"interpolate": { "value": "monotone" },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p20" },
"y2": { "scale": "yscale", "field": "p80" },
"opacity": { "value": 0.2 }
}
}
},
{
"type": "area",
"from": { "data": "table" },
"encode": {
"enter": { "fill": { "value": "#4C78A8" } },
"update": {
"interpolate": { "value": "monotone" },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p30" },
"y2": { "scale": "yscale", "field": "p70" },
"opacity": { "value": 0.2 }
}
}
},
{
"type": "area",
"from": { "data": "table" },
"encode": {
"enter": { "fill": { "value": "#4C78A8" } },
"update": {
"interpolate": { "value": "monotone" },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p40" },
"y2": { "scale": "yscale", "field": "p60" },
"opacity": { "value": 0.2 }
}
}
},
{
"type": "line",
"from": { "data": "table" },
"encode": {
"update": {
"interpolate": { "value": "monotone" },
"stroke": { "value": "#4C78A8" },
"strokeWidth": { "value": 2 },
"opacity": { "value": 0.8 },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p50" }
}
} }
} }
] },
} {
"type": "area",
"from": { "data": "table" },
"encode": {
"enter": { "fill": { "value": "#4C78A8" } },
"update": {
"interpolate": { "value": "monotone" },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p10" },
"y2": { "scale": "yscale", "field": "p90" },
"opacity": { "value": 0.15 }
}
}
},
{
"type": "area",
"from": { "data": "table" },
"encode": {
"enter": { "fill": { "value": "#4C78A8" } },
"update": {
"interpolate": { "value": "monotone" },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p20" },
"y2": { "scale": "yscale", "field": "p80" },
"opacity": { "value": 0.2 }
}
}
},
{
"type": "area",
"from": { "data": "table" },
"encode": {
"enter": { "fill": { "value": "#4C78A8" } },
"update": {
"interpolate": { "value": "monotone" },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p30" },
"y2": { "scale": "yscale", "field": "p70" },
"opacity": { "value": 0.2 }
}
}
},
{
"type": "area",
"from": { "data": "table" },
"encode": {
"enter": { "fill": { "value": "#4C78A8" } },
"update": {
"interpolate": { "value": "monotone" },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p40" },
"y2": { "scale": "yscale", "field": "p60" },
"opacity": { "value": 0.2 }
}
}
},
{
"type": "line",
"from": { "data": "table" },
"encode": {
"update": {
"interpolate": { "value": "monotone" },
"stroke": { "value": "#4C78A8" },
"strokeWidth": { "value": 2 },
"opacity": { "value": 0.8 },
"x": { "scale": "xscale", "field": "x" },
"y": { "scale": "yscale", "field": "p50" }
}
}
}
]
}

View File

@ -1620,6 +1620,11 @@ abbrev@1:
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
ace-builds@^1.4.12, ace-builds@^1.4.6:
version "1.4.12"
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.12.tgz#888efa386e36f4345f40b5233fcc4fe4c588fae7"
integrity sha512-G+chJctFPiiLGvs3+/Mly3apXTcfgE45dT5yp12BcWZ1kUs+gm0qd3/fv4gsz6fVag4mM0moHVpjHDIgph6Psg==
acorn-globals@^4.3.0, acorn-globals@^4.3.2: acorn-globals@^4.3.0, acorn-globals@^4.3.2:
version "4.3.4" version "4.3.4"
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7"
@ -3805,6 +3810,11 @@ detective@^5.2.0:
defined "^1.0.0" defined "^1.0.0"
minimist "^1.1.1" minimist "^1.1.1"
diff-match-patch@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37"
integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==
diff-sequences@^25.2.6: diff-sequences@^25.2.6:
version "25.2.6" version "25.2.6"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd"
@ -6123,6 +6133,11 @@ lodash.debounce@^4.0.0, lodash.debounce@^4.0.8:
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
lodash.get@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
lodash.isequal@^4.5.0: lodash.isequal@^4.5.0:
version "4.5.0" version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
@ -8367,6 +8382,17 @@ re-classnames@^4.0.0:
resolved "https://registry.yarnpkg.com/re-classnames/-/re-classnames-4.1.0.tgz#a13e1d66d84518f55e78435579bc303f7dba55e1" resolved "https://registry.yarnpkg.com/re-classnames/-/re-classnames-4.1.0.tgz#a13e1d66d84518f55e78435579bc303f7dba55e1"
integrity sha512-3gWpk6R5AP3H2r+k+6rcEygcrSJ6wRbvEpPcW55USHhSCMNdHMRs9iD02mZ3+urKQygys+AjZMQXrZ6HDBA2IQ== integrity sha512-3gWpk6R5AP3H2r+k+6rcEygcrSJ6wRbvEpPcW55USHhSCMNdHMRs9iD02mZ3+urKQygys+AjZMQXrZ6HDBA2IQ==
react-ace@^9.1.2:
version "9.1.2"
resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-9.1.2.tgz#4a3ad8dbd07f84fd99c26d9ec697ea3b2ef0a963"
integrity sha512-rzsPiGZ2/d4dmlxg0+Zo15igCnagao+TIUJCGV8RGLBr8xpKFpq5sxnTLvsE3pWPoFbMbQAXYJiZTMWEkNpRtg==
dependencies:
ace-builds "^1.4.6"
diff-match-patch "^1.0.4"
lodash.get "^4.4.2"
lodash.isequal "^4.5.0"
prop-types "^15.7.2"
react-apollo@^2.5.8: react-apollo@^2.5.8:
version "2.5.8" version "2.5.8"
resolved "https://registry.yarnpkg.com/react-apollo/-/react-apollo-2.5.8.tgz#c7a593b027efeefdd8399885e0ac6bec3b32623c" resolved "https://registry.yarnpkg.com/react-apollo/-/react-apollo-2.5.8.tgz#c7a593b027efeefdd8399885e0ac6bec3b32623c"