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