Skip to content
Snippets Groups Projects
Commit b8d5acda authored by Bucknell, Mary S.'s avatar Bucknell, Mary S.
Browse files

Removed the statistics module and fixed the legend module tests.

parent 4df09e15
No related branches found
No related tags found
No related merge requests found
......@@ -130,28 +130,6 @@ describe('Legend module', () => {
approved: false,
estimated: false
}]
},
'00065:median': {
tsKey: 'median',
endTime: new Date('2017-03-13T13:45:00.000Z'),
variable: '45807202',
points: [{
value: 1,
month: 2,
day: 6
}, {
value: 2,
month: 2,
day: 7
}, {
value: 3,
month: 2,
day: 7
}],
metadata: {
beginYear: '1931',
endYear: '2017'
}
}
},
variables: {
......@@ -168,6 +146,20 @@ describe('Legend module', () => {
}
}
},
statisticsData: {
median: {
'00060': {
'1': [{
month_nu: '2',
day_nu: '25',
p50_va: '43',
begin_yr: '1970',
end_yr: '2017',
loc_web_ds: 'This method'
}]
}
}
},
timeSeriesState: {
currentVariableID: '45807197',
currentDateRange: 'P7D',
......@@ -185,7 +177,8 @@ describe('Legend module', () => {
series: {
...TEST_DATA.series,
timeSeries: {}
}
},
statisticsData: {}
};
expect(legendMarkerRowsSelector(newData)).toEqual([]);
......@@ -194,12 +187,15 @@ describe('Legend module', () => {
it('Should return markers for the selected variable', () => {
const result = legendMarkerRowsSelector(TEST_DATA);
expect(result.length).toBe(1);
expect(result.length).toBe(2);
expect(result[0].length).toBe(4);
expect(result[0][0].type).toEqual(textOnlyMarker);
expect(result[0][1].type).toEqual(lineMarker);
expect(result[0][2].type).toEqual(rectangleMarker);
expect(result[0][3].type).toEqual(rectangleMarker);
expect(result[1].length).toBe(2);
expect(result[1][0].type).toEqual(textOnlyMarker);
expect(result[1][1].type).toEqual(lineMarker);
});
it('Should return markers for a different selected variable', () => {
......@@ -212,14 +208,11 @@ describe('Legend module', () => {
};
const result = legendMarkerRowsSelector(newData);
expect(result.length).toBe(2);
expect(result.length).toBe(1);
expect(result[0].length).toBe(3);
expect(result[0][0].type).toEqual(textOnlyMarker);
expect(result[0][1].type).toEqual(lineMarker);
expect(result[0][2].type).toEqual(lineMarker);
expect(result[1].length).toBe(2);
expect(result[1][0].type).toEqual(textOnlyMarker);
expect(result[1][1].type).toEqual(lineMarker);
});
it('Should return markers only for time series shown', () => {
......@@ -227,11 +220,10 @@ describe('Legend module', () => {
...TEST_DATA,
timeSeriesState: {
...TEST_DATA.timeSeriesState,
currentVariableID: '45807202',
showSeries: {
'current': true,
'compare': false,
'median': true
'median': false
}
}
};
......@@ -239,9 +231,11 @@ describe('Legend module', () => {
const result = legendMarkerRowsSelector(newData);
expect(result.length).toBe(1);
expect(result[0].length).toBe(2);
expect(result[0].length).toBe(4);
expect(result[0][0].type).toEqual(textOnlyMarker);
expect(result[0][1].type).toEqual(lineMarker);
expect(result[0][2].type).toEqual(rectangleMarker);
expect(result[0][3].type).toEqual(rectangleMarker);
});
});
});
const range = require('lodash/range');
const { DateTime } = require('luxon');
const { isLeapYear } = require('../../models');
const { calcStartTime } = require('../../utils');
/**
* Make statistical data look like a timeseries for plotting purposes
*
* @param series -- an object with the following keys: points, startTime, and endTime at a minimum. Each point should have a javascript month and day
* @param period -- ISO duration for date range of the time series
* @param ianaTimeZone -- Internet Assigned Numbers Authority designation for a time zone
* @returns {*[]}
*/
export const coerceStatisticalSeries = function (series, period, ianaTimeZone) {
const startTime = calcStartTime(period, series.endTime, ianaTimeZone); // calculate when the start time based on the period
const startYear = DateTime.fromMillis(startTime, {zone: ianaTimeZone}).year;
const endYear = DateTime.fromMillis(series.endTime, {zone: ianaTimeZone}).year;
const yearRange = range(startYear, endYear + 1);
const points = series.points;
let plotablePoints = [];
// for each year in the time range, coerce each median value to the appropriate date in that year
// exclude February 29th if the year is not a leap year
yearRange.forEach(year => {
points.forEach(point => {
const month = point.month;
const day = point.day;
let dataPoint = Object.assign({}, point);
dataPoint.dateTime = dataPoint.dateTime ? dataPoint.dateTime : DateTime.fromObject({
year: year,
day: day,
month: month,
zone: ianaTimeZone
}).valueOf();
if (!isLeapYear(year)) {
if(!(month === 1 && day === 29)) {
plotablePoints.push(dataPoint);
}
} else {
plotablePoints.push(dataPoint);
}
});
});
// sort the points by date in ascending order
const sortedPoints = plotablePoints.sort(function(a, b) {
return a.dateTime - b.dateTime;
});
// include median points that fall within the hydrograph's start and end datetime
let filtered = sortedPoints.filter(x => startTime <= x.dateTime && x.dateTime <= series.endTime);
// handle the far left and far right ends of the graph
const first = filtered[0];
if (first.dateTime > startTime) {
// if the hydrograph's start time doesn't line with the first median point, grab
// the value of the previous median date's value and create a new point using the
// start time as its x-value, so that the median step function extends to the left
// terminus of the graph
let previousIndex;
if (sortedPoints.indexOf(first) === 0) {
previousIndex = sortedPoints.length - 1;
} else {
previousIndex = sortedPoints.indexOf(first) - 1;
}
const previousVal = sortedPoints[previousIndex];
let leftVal = Object.assign({}, previousVal);
leftVal.dateTime = startTime;
filtered.unshift(leftVal);
}
const last = filtered[filtered.length - 1];
if (last.dateTime < series.endTime) {
// if the hydrograph's end time doesn't line with the last median point, create
// an additional data point with it's x-value as the graph's end time and its value
// as the last median point's value, so that the median step function extends to the
// far right terminus of the graph
let rightVal = Object.assign({}, last);
rightVal.dateTime = series.endTime;
filtered.push(rightVal);
}
return filtered;
};
const range = require('lodash/range');
const { coerceStatisticalSeries } = require('./statistics');
const { DateTime } = require('luxon');
describe('Statistics module', () => {
const timeZone = 'America/Chicago';
describe('coerceStatisticalSeries', () => {
// generate a year's worth of fake median data
const MONTHS = range(1, 13);
const DAYS = range(1, 32);
const YEAR = 2016;
let time = [];
MONTHS.forEach(month => {
DAYS.forEach(day => {
let someDay = DateTime.fromObject({
year: YEAR,
month: month,
day: day,
zone: timeZone
}).valueOf();
if (!time.includes(someDay) && !isNaN(someDay)) {
time.push(someDay);
}
});
});
const dates = time.map(t => new DateTime.fromMillis(t, {zone: timeZone}));
const points = dates.map(dt => {
const month = dt.month;
const day = dt.day;
return {
dateTime: null,
month: month,
day: day,
value: month + day*2
};
});
const series1 = {
points: points,
endTime: 1425362400000
};
const series2 = {
points: points,
endTime: 1456984800000
};
const series3 = {
points: points,
endTime: 1520385960000
};
it('handles coercion to a single year of data without a leap day', () => {
const result = coerceStatisticalSeries(series1, 'P7D', timeZone);
const dates = result.map(x => DateTime.fromMillis(x.dateTime, {zone: timeZone}));
expect(result.length).toEqual(8);
dates.forEach(x => {
expect(x.year).toEqual(2015);
});
expect(dates.map(x => x.day).includes(29)).toBe(false);
});
it('handles coercion to a single year of data with a leap day', () => {
const result = coerceStatisticalSeries(series2, 'P7D', timeZone);
const dates = result.map(x => DateTime.fromMillis(x.dateTime, {zone: timeZone}));
expect(result.length).toEqual(8);
dates.forEach(x => {
expect(x.year).toEqual(2016);
});
expect(dates.map(x => x.day).includes(29)).toBe(true);
});
it('handles a 30 day period', () => {
let result = coerceStatisticalSeries(series1, 'P30D', timeZone);
expect(result.length).toEqual(31);
});
it('handles a non-leap year period', () => {
const result = coerceStatisticalSeries(series1, 'P1Y', timeZone);
const dates = result.map(x => DateTime.fromMillis(x.dateTime, {zone: timeZone}));
const years = dates.map(x => x.year);
expect(result.length).toEqual(365);
expect(years.includes(2015)).toBe(true);
expect(years.includes(2014)).toBe(true);
});
it('handles a leap year period', () => {
const result = coerceStatisticalSeries(series2, 'P1Y', timeZone);
const dates = result.map(x => DateTime.fromMillis(x.dateTime, {zone: timeZone}));
const years = dates.map(x => x.year);
expect(result.length).toEqual(367);
expect(years.includes(2016)).toBe(true);
expect(years.includes(2015)).toBe(true);
});
it('handles times in the middle of the day', () => {
const result = coerceStatisticalSeries(series3, 'P7D', timeZone);
expect(result.length).toEqual(9);
expect(result[0].dateTime).toEqual(1519781160000);
expect(result[1].dateTime).toEqual(1519797600000);
expect(result[result.length - 2].dateTime).toEqual(1520316000000);
expect(result[result.length - 1].dateTime).toEqual(1520385960000);
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment