Merge pull request #11 from foretold-app/improvements/1086
Improvements/1086
This commit is contained in:
commit
6a86346b23
|
@ -1,7 +1,10 @@
|
|||
// "mm(floor(uniform(30,35)), normal(50,20), [.25,.5])",
|
||||
// "mm(floor(normal(28,4)), normal(32,2), uniform(20,24), [.5,.2,.1])",
|
||||
// Examples:
|
||||
// mm(floor(uniform(30,35)), normal(50,20), [.25,.5])
|
||||
// mm(floor(normal(28,4)), normal(32,2), uniform(20,24), [.5,.2,.1])
|
||||
// mm(5 to 20, floor(normal(20,2)), [.5, .5])"
|
||||
// floor(3 to 4)
|
||||
// uniform(0,1) > 0.3 ? lognormal(6.652, -0.41): 0
|
||||
|
||||
// "mm(5 to 20, floor(normal(20,2)), [.5, .5])",
|
||||
let timeDist =
|
||||
DistPlusIngredients.make(
|
||||
~guesstimatorString="(floor(10 to 15))",
|
||||
|
@ -36,4 +39,4 @@ let distributions = () =>
|
|||
</div>
|
||||
</div>;
|
||||
|
||||
let entry = EntryTypes.(entry(~title="Pdf", ~render=distributions));
|
||||
let entry = EntryTypes.(entry(~title="Pdf", ~render=distributions));
|
||||
|
|
|
@ -375,60 +375,68 @@ let make = () => {
|
|||
}
|
||||
/>
|
||||
</Col>
|
||||
<Col span=4>
|
||||
<Form.Field
|
||||
field=FormConfig.Zero
|
||||
render={({handleChange, value}) =>
|
||||
<Antd.Form.Item label={"Zero Point" |> E.ste}>
|
||||
<Antd_DatePicker
|
||||
value
|
||||
onChange={e => {
|
||||
e |> handleChange;
|
||||
_ => ();
|
||||
}}
|
||||
/>
|
||||
</Antd.Form.Item>
|
||||
}
|
||||
/>
|
||||
</Col>
|
||||
<Col span=4>
|
||||
<Form.Field
|
||||
field=FormConfig.Unit
|
||||
render={({handleChange, value}) =>
|
||||
<Antd.Form.Item label={"Unit" |> E.ste}>
|
||||
<Antd.Select value onChange={e => e |> handleChange}>
|
||||
<Antd.Select.Option value="days">
|
||||
{"Days" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="hours">
|
||||
{"Hours" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="milliseconds">
|
||||
{"Milliseconds" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="minutes">
|
||||
{"Minutes" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="months">
|
||||
{"Months" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="quarters">
|
||||
{"Quarters" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="seconds">
|
||||
{"Seconds" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="weeks">
|
||||
{"Weeks" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="years">
|
||||
{"Years" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
</Antd.Select>
|
||||
</Antd.Form.Item>
|
||||
}
|
||||
/>
|
||||
</Col>
|
||||
{<>
|
||||
<Col span=4>
|
||||
<Form.Field
|
||||
field=FormConfig.Zero
|
||||
render={({handleChange, value}) =>
|
||||
<Antd.Form.Item label={"Zero Point" |> E.ste}>
|
||||
<Antd_DatePicker
|
||||
value
|
||||
onChange={e => {
|
||||
e |> handleChange;
|
||||
_ => ();
|
||||
}}
|
||||
/>
|
||||
</Antd.Form.Item>
|
||||
}
|
||||
/>
|
||||
</Col>
|
||||
<Col span=4>
|
||||
<Form.Field
|
||||
field=FormConfig.Unit
|
||||
render={({handleChange, value}) =>
|
||||
<Antd.Form.Item label={"Unit" |> E.ste}>
|
||||
<Antd.Select value onChange={e => e |> handleChange}>
|
||||
<Antd.Select.Option value="days">
|
||||
{"Days" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="hours">
|
||||
{"Hours" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="milliseconds">
|
||||
{"Milliseconds" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="minutes">
|
||||
{"Minutes" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="months">
|
||||
{"Months" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="quarters">
|
||||
{"Quarters" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="seconds">
|
||||
{"Seconds" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="weeks">
|
||||
{"Weeks" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
<Antd.Select.Option value="years">
|
||||
{"Years" |> E.ste}
|
||||
</Antd.Select.Option>
|
||||
</Antd.Select>
|
||||
</Antd.Form.Item>
|
||||
}
|
||||
/>
|
||||
</Col>
|
||||
</>
|
||||
|> E.showIf(
|
||||
E.L.contains(
|
||||
reform.state.values.unitType,
|
||||
["TimeDistribution"],
|
||||
),
|
||||
)}
|
||||
</Row>
|
||||
<Row _type=`flex className=Styles.rows>
|
||||
<Col span=4>
|
||||
|
@ -453,4 +461,4 @@ let make = () => {
|
|||
</Antd.Card>
|
||||
<div className=Styles.spacer />
|
||||
</div>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -34,8 +34,7 @@ module Styles = {
|
|||
module DemoDist = {
|
||||
[@react.component]
|
||||
let make = (~guesstimatorString: string) => {
|
||||
let (ys, xs) =
|
||||
DistEditor.getPdfFromUserInput("normal(1, 1) / normal(10, 1)");
|
||||
let (ys, xs) = DistEditor.getPdfFromUserInput(guesstimatorString);
|
||||
let continuous: DistTypes.xyShape = {xs, ys};
|
||||
<Antd.Card title={"Distribution" |> E.ste}>
|
||||
<div className=Styles.spacer />
|
||||
|
|
|
@ -109,22 +109,28 @@ export class CdfChartD3 {
|
|||
`translate(${this.calc.chartLeftMargin}, ${this.calc.chartTopMargin})`,
|
||||
);
|
||||
|
||||
const common = this.getCommonThings();
|
||||
if (this.hasDate('continuous')) {
|
||||
const distributionChart = this.addDistributionChart();
|
||||
if (this.hasDate('discrete')) {
|
||||
this.addLollipopsChart(distributionChart);
|
||||
}
|
||||
this.addDistributionChart(common);
|
||||
}
|
||||
if (this.hasDate('discrete')) {
|
||||
this.addLollipopsChart(common);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
addDistributionChart() {
|
||||
const areaColorRange = d3.scaleOrdinal().range(this.attrs.areaColors);
|
||||
const dataPoints = [this.getDataPoints('continuous')];
|
||||
|
||||
/**
|
||||
* @returns {*}
|
||||
*/
|
||||
getCommonThings() {
|
||||
// Boundaries.
|
||||
const xMin = this.attrs.minX || d3.min(this.attrs.data.continuous.xs) || d3.min(this.attrs.data.discrete.xs);
|
||||
const xMax = this.attrs.maxX || d3.max(this.attrs.data.continuous.xs) || d3.max(this.attrs.data.discrete.xs);
|
||||
const xMin = this.attrs.minX
|
||||
|| d3.min(this.attrs.data.continuous.xs)
|
||||
|| d3.min(this.attrs.data.discrete.xs);
|
||||
const xMax = this.attrs.maxX
|
||||
|| d3.max(this.attrs.data.continuous.xs)
|
||||
|| d3.max(this.attrs.data.discrete.xs);
|
||||
|
||||
const yMin = d3.min(this.attrs.data.continuous.ys);
|
||||
const yMax = d3.max(this.attrs.data.continuous.ys);
|
||||
|
||||
|
@ -150,6 +156,21 @@ export class CdfChartD3 {
|
|||
.domain([yMinDomain, yMaxDomain])
|
||||
.range([this.calc.chartHeight, 0]);
|
||||
|
||||
return {
|
||||
xMin, xMax,
|
||||
xScale, yScale,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param common
|
||||
*/
|
||||
addDistributionChart(common) {
|
||||
const areaColorRange = d3.scaleOrdinal().range(this.attrs.areaColors);
|
||||
const dataPoints = [this.getDataPoints('continuous')];
|
||||
|
||||
const { xMin, xMax, xScale, yScale } = common;
|
||||
|
||||
// X-axis.
|
||||
let xAxis = null;
|
||||
if (!!this.attrs.timeScale) {
|
||||
|
@ -287,16 +308,14 @@ export class CdfChartD3 {
|
|||
.on('mousemove', mouseover)
|
||||
.on('mouseout', mouseout);
|
||||
}
|
||||
|
||||
return { xScale, yScale };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} distributionChart
|
||||
* @param {object} distributionChart.xScale
|
||||
* @param {object} distributionChart.yScale
|
||||
* @param {object} common
|
||||
* @param {object} common.xScale
|
||||
* @param {object} common.yScale
|
||||
*/
|
||||
addLollipopsChart(distributionChart) {
|
||||
addLollipopsChart(common) {
|
||||
const data = this.getDataPoints('discrete');
|
||||
|
||||
const _yMin = d3.min(this.attrs.data.discrete.ys);
|
||||
|
@ -306,7 +325,7 @@ export class CdfChartD3 {
|
|||
this.chart.append('g')
|
||||
.attr('class', 'lollipops-x-axis')
|
||||
.attr('transform', `translate(0, ${this.calc.chartHeight})`)
|
||||
.call(d3.axisBottom(distributionChart.xScale));
|
||||
.call(d3.axisBottom(common.xScale));
|
||||
|
||||
// Y-domain.
|
||||
const yMaxDomainFactor = _.get(this.attrs, 'yMaxDiscreteDomainFactor', 1);
|
||||
|
@ -333,7 +352,7 @@ export class CdfChartD3 {
|
|||
tooltip.transition()
|
||||
.style('opacity', .9);
|
||||
tooltip.html(`X: ${d.x}, Y: ${d.y}`)
|
||||
.style('left', (distributionChart.xScale(d.x) + 60) + 'px')
|
||||
.style('left', (common.xScale(d.x) + 60) + 'px')
|
||||
.style('top', yScale(d.y) + 'px');
|
||||
}
|
||||
|
||||
|
@ -354,8 +373,8 @@ export class CdfChartD3 {
|
|||
.append('line')
|
||||
.attr('class', 'lollipops-line')
|
||||
.attr('id', d => 'lollipops-line-' + d.id)
|
||||
.attr('x1', d => distributionChart.xScale(d.x))
|
||||
.attr('x2', d => distributionChart.xScale(d.x))
|
||||
.attr('x1', d => common.xScale(d.x))
|
||||
.attr('x2', d => common.xScale(d.x))
|
||||
.attr('y1', d => yScale(d.y))
|
||||
.attr('y2', yScale(0));
|
||||
|
||||
|
@ -371,7 +390,7 @@ export class CdfChartD3 {
|
|||
.append('circle')
|
||||
.attr('class', 'lollipops-circle')
|
||||
.attr('id', d => 'lollipops-circle-' + d.id)
|
||||
.attr('cx', d => distributionChart.xScale(d.x))
|
||||
.attr('cx', d => common.xScale(d.x))
|
||||
.attr('cy', d => yScale(d.y))
|
||||
.attr('r', '4');
|
||||
|
||||
|
@ -382,7 +401,7 @@ export class CdfChartD3 {
|
|||
.append('rect')
|
||||
.attr('width', 30)
|
||||
.attr('height', this.calc.chartHeight)
|
||||
.attr('x', d => distributionChart.xScale(d.x) - 15)
|
||||
.attr('x', d => common.xScale(d.x) - 15)
|
||||
.attr('y', 0)
|
||||
.attr('opacity', 0)
|
||||
.attr('pointer-events', 'all')
|
||||
|
@ -439,7 +458,10 @@ export class CdfChartD3 {
|
|||
const len = data.xs.length;
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
dt.push({ x: data.xs[i], y: data.ys[i], id: i });
|
||||
const x = data.xs[i];
|
||||
const y = data.ys[i];
|
||||
const id = i;
|
||||
dt.push({ x, y, id });
|
||||
}
|
||||
|
||||
return dt;
|
||||
|
|
Loading…
Reference in New Issue
Block a user