Merge pull request #12 from foretold-app/improvements/1097

Improvements/1097
This commit is contained in:
Ozzie Gooen 2020-03-02 08:08:33 +00:00 committed by GitHub
commit d772dc3841
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 36 deletions

View File

@ -169,7 +169,7 @@ export class CdfChartD3 {
const areaColorRange = d3.scaleOrdinal().range(this.attrs.areaColors); const areaColorRange = d3.scaleOrdinal().range(this.attrs.areaColors);
const dataPoints = [this.getDataPoints('continuous')]; const dataPoints = [this.getDataPoints('continuous')];
const { xMin, xMax, xScale, yScale } = common; const { xMin, xMax, xScale, yScale } = common;
// X-axis. // X-axis.
let xAxis = null; let xAxis = null;
@ -337,11 +337,14 @@ export class CdfChartD3 {
.domain([yMinDomain, yMaxDomain]) .domain([yMinDomain, yMaxDomain])
.range([this.calc.chartHeight, 0]); .range([this.calc.chartHeight, 0]);
const yTicks = Math.floor(this.calc.chartHeight / 20);
const yAxis = d3.axisLeft(yScale).ticks(yTicks);
// Adds 'g' for an y-axis. // Adds 'g' for an y-axis.
this.chart.append('g') this.chart.append('g')
.attr('class', 'lollipops-y-axis') .attr('class', 'lollipops-y-axis')
.attr('transform', `translate(${this.calc.chartWidth}, 0)`) .attr('transform', `translate(${this.calc.chartWidth}, 0)`)
.call(d3.axisLeft(yScale)); .call(yAxis);
function showTooltip(d) { function showTooltip(d) {
d3.select('#lollipops-line-' + d.id) d3.select('#lollipops-line-' + d.id)
@ -400,9 +403,9 @@ export class CdfChartD3 {
.enter() .enter()
.append('rect') .append('rect')
.attr('width', 30) .attr('width', 30)
.attr('height', this.calc.chartHeight) .attr('height', d => this.calc.chartHeight - yScale(d.y) + 10)
.attr('x', d => common.xScale(d.x) - 15) .attr('x', d => common.xScale(d.x) - 15)
.attr('y', 0) .attr('y', d => yScale(d.y) - 10)
.attr('opacity', 0) .attr('opacity', 0)
.attr('pointer-events', 'all') .attr('pointer-events', 'all')
.on('mouseover', showTooltip) .on('mouseover', showTooltip)
@ -427,7 +430,10 @@ export class CdfChartD3 {
case 'months': case 'months':
return d3.timeMonth.every(4); return d3.timeMonth.every(4);
case 'quarters': case 'quarters':
return d3.timeMonth.every(3); // It is temporary solution, but it works
// if the difference between edge dates is not
// much more than 10 units.
return d3.timeMonth.every(12);
case 'hours': case 'hours':
return d3.timeHour.every(10); return d3.timeHour.every(10);
case 'days': case 'days':

View File

@ -34,15 +34,29 @@ const ratioSize = samples => {
}; };
/**
* @param values
* @param outputResolutionCount
* @param min
* @param max
* @returns {{discrete: {ys: *, xs: *}, continuous: {ys: [], xs: []}}}
*/
const toPdf = (values, outputResolutionCount, min, max) => { const toPdf = (values, outputResolutionCount, min, max) => {
let duplicateSamples = _(values).groupBy().pickBy(x => x.length > 1).keys().value(); let duplicateSamples = _(values).groupBy().pickBy(x => x.length > 1).keys().value();
let totalLength = _.size(values); let totalLength = _.size(values);
let frequencies = duplicateSamples.map(s => ({value: parseFloat(s), percentage: _(values).filter(x => x ==s).size()/totalLength})); let frequencies = duplicateSamples.map(s => ({
value: parseFloat(s),
percentage: _(values).filter(x => x == s).size() / totalLength
}));
let continuousSamples = _.difference(values, frequencies.map(f => f.value)); let continuousSamples = _.difference(values, frequencies.map(f => f.value));
let discrete = {xs: frequencies.map(f => f.value), ys: frequencies.map(f => f.percentage)}; let discrete = {
let continuous = {ys: [], xs: []}; xs: frequencies.map(f => f.value),
if (continuousSamples.length > 20){ ys: frequencies.map(f => f.percentage)
};
let continuous = { ys: [], xs: [] };
if (continuousSamples.length > 20) {
const samples = new Samples(continuousSamples); const samples = new Samples(continuousSamples);
const ratioSize$ = ratioSize(samples); const ratioSize$ = ratioSize(samples);
@ -51,38 +65,53 @@ const toPdf = (values, outputResolutionCount, min, max) => {
const pdf = samples.toPdf({ size: outputResolutionCount, width, min, max }); const pdf = samples.toPdf({ size: outputResolutionCount, width, min, max });
continuous = pdf; continuous = pdf;
} }
return {continuous, discrete};
return { continuous, discrete };
}; };
let run = (text, sampleCount, outputResolutionCount, inputs=[], min=false, max=false) => { /**
let [_error, item] = Guesstimator.parse({ text: "=" + text }); * @param text
const { parsedInput } = item; * @param sampleCount
const { guesstimateType } = parsedInput; * @param outputResolutionCount
* @param inputs
* @param min
* @param max
* @returns {{discrete: {ys: *, xs: *}, continuous: {ys: *[], xs: *[]}}}
*/
const run = (
text,
sampleCount,
outputResolutionCount,
inputs = [],
min = false,
max = false,
) => {
const [_error, item] = Guesstimator.parse({ text: "=" + text });
const { parsedInput } = item;
const guesstimator = new Guesstimator({ parsedInput }); const guesstimator = new Guesstimator({ parsedInput });
const value = guesstimator.sample( const value = guesstimator.sample(
sampleCount, sampleCount,
inputs, inputs,
); );
const samplerType = guesstimator.samplerType();
const values = _.filter(value.values, _.isFinite); const values = _.filter(value.values, _.isFinite);
let update; let update;
let blankResponse = { let blankResponse = {
continuous: {ys: [], xs: []}, continuous: { ys: [], xs: [] },
discrete: {ys: [], xs: []} discrete: { ys: [], xs: [] }
}; };
if (values.length === 0) { if (values.length === 0) {
update = blankResponse; update = blankResponse;
} else if (values.length === 1) { } else if (values.length === 1) {
update = blankResponse; update = blankResponse;
} else { } else {
update = toPdf(values, outputResolutionCount, min, max); update = toPdf(values, outputResolutionCount, min, max);
} }
return update; return update;
} };
module.exports = { module.exports = {
run, run,
}; };