diff --git a/assets/src/scripts/components/hydrograph/axes.js b/assets/src/scripts/components/hydrograph/axes.js index c9133a4dcafc7056f7aaeb11eeb560d969d1bf90..3c9f97c75da3688f12f5b2b8155ead4cbc9dbb1d 100644 --- a/assets/src/scripts/components/hydrograph/axes.js +++ b/assets/src/scripts/components/hydrograph/axes.js @@ -1,249 +1,24 @@ -import { axisBottom, axisLeft, axisRight } from 'd3-axis'; +import {axisBottom, axisLeft, axisRight} from 'd3-axis'; import memoize from 'fast-memoize'; -import { DateTime, Interval } from 'luxon'; -import { createSelector } from 'reselect'; +import {createSelector} from 'reselect'; -import config from '../../config'; -import { getCurrentDateRange, getCurrentParmCd } from '../../selectors/time-series-selector'; -import { convertCelsiusToFahrenheit, convertFahrenheitToCelsius, mediaQuery, deltaDays } from '../../utils'; +import {generateTimeTicks} from '../../d3-rendering/tick-marks'; +import {getCurrentDateRange, getCurrentParmCd} from '../../selectors/time-series-selector'; +import {convertCelsiusToFahrenheit, convertFahrenheitToCelsius} from '../../utils'; -import { getYTickDetails } from './domain'; +import {getYTickDetails} from './domain'; import {getLayout} from './layout'; -import { getXScale, getBrushXScale, getYScale, getSecondaryYScale } from './scales'; -import { yLabelSelector, secondaryYLabelSelector, tsTimeZoneSelector, TEMPERATURE_PARAMETERS } from './time-series'; - - -const FORMAT = { - P7D: 'MMM dd', - P30D: 'MMM dd', - P1Y: 'MMM yyyy', - custom: null -}; - -/** - * Generate the values for ticks to place on a hydrograph. - * - * @param startDate - start datetime in the form of milliseconds since 1970-01-01 UTC - * @param endDate - end datetime in the form of milliseconds since 1970-01-01 UTC - * @param ianaTimeZone - Internet Assigned Numbers Authority designation for a time zone - * @returns {Object} with two properties, dates {Array of Number timestamp in milliseconds} and - * format {String} the format that should be used used to display the dates. - */ -export const generateDateTicks = function(startDate, endDate, ianaTimeZone) { - - const startDateTime = DateTime.fromMillis(startDate, {zone: ianaTimeZone}); - const endDateTime = DateTime.fromMillis(endDate, {zone: ianaTimeZone}); - const length = Interval.fromDateTimes(startDateTime, endDateTime); - const dayCount = length.count('days'); - const weekCount = length.count('weeks'); - const monthCount = length.count('months'); - const yearCount = length.count('years'); - - const formatFnc = (format) => { - return function(dateTime) { - return DateTime.fromMillis(dateTime, {zone: ianaTimeZone}).toFormat(format); - }; - }; - - const getTicks = function(interval, startOffset ) { - let dateTime; - const startOffsetKind = Object.keys(startOffset)[0]; - if (startOffsetKind === 'years') { - dateTime = startDateTime.startOf('year'); - } else if (startOffsetKind === 'months') { - dateTime = startDateTime.startOf('month'); - } else { - dateTime = startDateTime.startOf('day'); - } - dateTime = dateTime.plus(startOffset); - - let result = []; - while (dateTime < endDateTime) { - console.log(`${dateTime.toFormat('f')}`); - result.push(dateTime.toMillis()); - dateTime = dateTime.plus(interval); - } - return result; - }; - - const getDefaultTicks = function (unit, tickCount) { - const tickInterval = (endDate - startDate) / (tickCount + 1); - let result = []; - - let dateTime = DateTime.fromMillis(startDate + tickInterval, {zone: ianaTimeZone}); - while (dateTime < endDateTime) { - let tickDateTime = dateTime.startOf(unit); - console.log(`Default ${tickDateTime.toFormat('f')}`); - result.push(tickDateTime.toMillis()); - dateTime = dateTime.plus(tickInterval); - } - - return result; - }; - - let result = { - dates: [], - format: null - }; - - if (dayCount <= 3) { - result = { - dates: getDefaultTicks('minute', 4), - format: formatFnc('MMM dd HH:mm') - }; - } else if (dayCount > 3 && dayCount <= 8) { - // Tick marks are daily - result = { - dates: getTicks({days: 1}, {days: 1}), - format: formatFnc('MMM dd') - }; - - } else if (dayCount > 8 && dayCount <= 15) { - // Tick marks are ever other day - result = { - dates: getTicks({days: 2}, {days: 1}), - format: formatFnc('MMM dd') - }; - } else if (dayCount > 15 && dayCount <= 29) { - //Tick marks every fourth day - result = { - dates: getTicks({days: 4}, {days: 1}), - format: formatFnc('MMM dd') - }; - } else if (weekCount > 4 && weekCount <= 8) { - //Tick marks every week - result = { - dates: getTicks({weeks: 1}, {days: 3}), - format: formatFnc('MMM dd') - }; - } else if (weekCount > 8 && weekCount <= 15) { - // Tick marks every other week - result = { - dates: getTicks({weeks: 2}, {days: 7}), - format: formatFnc('MMM dd') - }; - } else if (weekCount > 15 && monthCount <= 8) { - //Tick marks every month - result = { - dates: getTicks({months: 1}, {months : 1}), - format: formatFnc('MMM yyyy') - }; - } else if (monthCount > 8 && monthCount <= 15) { - //Tick marks every other month - result = { - dates: getTicks({months: 2}, {months: 1}), - format: formatFnc('MMM yyyy') - }; - } else if (monthCount > 15 && monthCount <= 29){ - // Tick marks every 4 months - result = { - dates: getTicks({months: 4}, {months: 2}), - format: formatFnc('MMM yyyy') - }; - } else if (monthCount > 29 && monthCount <= 43) { - // Tick marks every 6 months - result = { - dates: getTicks({months: 6}, {months: 3}), - format: formatFnc('MMM yyyy') - }; - } else if (monthCount > 43 && yearCount <= 8) { - // Tick marks every year - result = { - dates: getTicks({years: 1}, {years: 1}), - format: formatFnc('yyyy') - }; - } else { - // Generate 8 tick marks and put them at the beginning of the year of that date. - result = { - dates: getDefaultTicks('year', 7), - format: formatFnc('yyyy') - }; - } - - - return result; - /* - const tzStartDate = DateTime.fromMillis(startDate, {zone: ianaTimeZone}); - let dates = []; - let date; - let timePeriod; - let interval; - let dateDiff; - - const setP7D = () => { - date = tzStartDate.startOf('day'); - timePeriod = 'days'; - interval = 1; - }; - const setP30D = () => { - date = tzStartDate.minus({days: tzStartDate.weekday}).startOf('day'); - timePeriod = 'weeks'; - interval = 1; - }; - const setP1Y = () => { - date = tzStartDate.startOf('month'); - timePeriod = 'months'; - if (mediaQuery(config.USWDS_LARGE_SCREEN)) { - interval = 1; - } else { - interval = 2; - } - }; - switch (period) { - case 'P7D': - setP7D(); - break; - case 'P30D': - setP30D(); - break; - case 'P1Y': - setP1Y(); - break; - case 'custom': - dateDiff = deltaDays(new Date(startDate), new Date(endDate)); - if (dateDiff <= 7) { - setP7D(); - FORMAT.custom = 'MMM dd'; - } else if (7 < dateDiff && dateDiff <= 30) { - setP30D(); - FORMAT.custom = 'MMM dd'; - } else if (30 < dateDiff && dateDiff <= 365) { - setP1Y(); - FORMAT.custom = 'MMM yyyy'; - } else { - date = tzStartDate.startOf('month'); - timePeriod = 'months'; - interval = Math.ceil(dateDiff/365.25); - FORMAT.custom = 'MMM yyyy'; - } - break; - default: - date = tzStartDate.startOf('day'); - timePeriod = 'days'; - interval = 1; - } - while (date.valueOf() <= endDate) { - date = date.plus({[timePeriod]: interval}); - if (startDate <= date.valueOf() && date.valueOf() <= endDate) { - dates.push(date.valueOf()); - } - } - return dates; - */ -}; - - +import {getXScale, getBrushXScale, getYScale, getSecondaryYScale} from './scales'; +import {yLabelSelector, secondaryYLabelSelector, tsTimeZoneSelector, TEMPERATURE_PARAMETERS} from './time-series'; const createXAxis = function(xScale, period, ianaTimeZone) { - const [startDate, endDate] = xScale.domain(); - const tickDates = generateDateTicks(startDate, endDate, period, ianaTimeZone); + const [startMillis, endMillis] = xScale.domain(); + const ticks = generateTimeTicks(startMillis, endMillis, ianaTimeZone); return axisBottom() .scale(xScale) - .tickValues(tickDates) + .tickValues(ticks.dates) .tickSizeOuter(0) - .tickFormat(d => { - return DateTime.fromMillis(d, {zone: ianaTimeZone}).toFormat(FORMAT[period]); - }); + .tickFormat(ticks.format); }; /** diff --git a/assets/src/scripts/components/hydrograph/axes.spec.js b/assets/src/scripts/components/hydrograph/axes.spec.js deleted file mode 100644 index 13c82f30c514c92acf470242716cdf807268a020..0000000000000000000000000000000000000000 --- a/assets/src/scripts/components/hydrograph/axes.spec.js +++ /dev/null @@ -1,349 +0,0 @@ -import {DateTime} from 'luxon'; - -import {generateDateTicks } from './axes'; - - -describe('Chart axes', () => { - - const timeZone = 'America/Chicago'; - - fdescribe('generateDateTicks', () => { - const startTime = 1520538281000; - - it('Generates 4 ticks with format MMM dd HH:mm when the day length is 2', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 2}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(4); - expect(result.dates.map(result.format)).toEqual( - ['Mar 08 23:20', 'Mar 09 08:56', 'Mar 09 18:32', 'Mar 10 04:08'] - ); - }); - - it('Generates day length tick marks with format MMM dd when length is 7 days', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 7}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['Mar 09', 'Mar 10', 'Mar 11', 'Mar 12', 'Mar 13', 'Mar 14', 'Mar 15'] - ); - }); - it('Generates day length tick marks with format MMM dd when length is 4 days', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 3}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(3); - expect(result.dates.map(result.format)).toEqual( - ['Mar 09', 'Mar 10', 'Mar 11'] - ); - }); - - it('Generates every other day tick marks with format MMM dd when length is 8 days', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 8}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(4); - expect(result.dates.map(result.format)).toEqual( - ['Mar 09', 'Mar 11', 'Mar 13', 'Mar 15'] - ); - }); - - it('Generates every other day tick marks with format MM dd when length is 14', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 14}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['Mar 09', 'Mar 11', 'Mar 13', 'Mar 15', 'Mar 17', 'Mar 19', 'Mar 21'] - ); - }); - - it('Generates every fourth day tick marks with format MM dd when length is 15', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 15}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(4); - expect(result.dates.map(result.format)).toEqual( - ['Mar 09', 'Mar 13', 'Mar 17', 'Mar 21'] - ); - }); - - it('Generates every fourth day tick marks with format MM dd when length is 28', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 28}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['Mar 09', 'Mar 13', 'Mar 17', 'Mar 21', 'Mar 25', 'Mar 29', 'Apr 02'] - ); - }); - - it('Generates every week tick marks with format MM dd when day count is 29', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 29}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(4); - expect(result.dates.map(result.format)).toEqual( - ['Mar 11', 'Mar 18', 'Mar 25', 'Apr 01'] - ); - }); - - it('Generates every week tick marks with format MM dd when week count is 8', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 50}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['Mar 11', 'Mar 18', 'Mar 25', 'Apr 01', 'Apr 08', 'Apr 15', 'Apr 22'] - ); - }); - - it('Generates every two week tick marks with format MM dd when week count is 9', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 53}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(4); - expect(result.dates.map(result.format)).toEqual( - ['Mar 15', 'Mar 29', 'Apr 12', 'Apr 26'] - ); - }); - - it('Generates every two week tick marks with format MM dd when week count is 16', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 98}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['Mar 15', 'Mar 29', 'Apr 12', 'Apr 26', 'May 10', 'May 24', 'Jun 07'] - ); - }); - - it('Generates every month tick marks with format MM YYYY when week count is 17', () => { - const endTime = DateTime.fromMillis(startTime).plus({days: 126}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(4); - expect(result.dates.map(result.format)).toEqual( - ['Apr 2018', 'May 2018', 'Jun 2018', 'Jul 2018'] - ); - }); - - it('Generates every month tick marks with format MM YYYY when month count is 7', () => { - const endTime = DateTime.fromMillis(startTime).plus({month: 7, days: 1}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['Apr 2018', 'May 2018', 'Jun 2018', 'Jul 2018', 'Aug 2018', 'Sep 2018', 'Oct 2018'] - ); - }); - - it('Generates every other month tick marks with format MM YYYY when month count is 8', () => { - const endTime = DateTime.fromMillis(startTime).plus({month: 8, days: 18}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(4); - expect(result.dates.map(result.format)).toEqual( - ['Apr 2018', 'Jun 2018', 'Aug 2018', 'Oct 2018'] - ); - }); - - it('Generates every other month tick marks with format MM YYYY when month count is 14', () => { - const endTime = DateTime.fromMillis(startTime).plus({month: 14, days: 18}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['Apr 2018', 'Jun 2018', 'Aug 2018', 'Oct 2018', 'Dec 2018', 'Feb 2019', 'Apr 2019'] - ); - }); - - it('Generates every four month tick marks with format MM YYYY when month count is 15', () => { - const endTime = DateTime.fromMillis(startTime).plus({month: 15, days: 18}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(4); - expect(result.dates.map(result.format)).toEqual( - ['May 2018', 'Sep 2018', 'Jan 2019', 'May 2019'] - ); - }); - - it('Generates every four month tick marks with format MM YYYY when month count is 28', () => { - const endTime = DateTime.fromMillis(startTime).plus({month: 28, days: 18}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['May 2018', 'Sep 2018', 'Jan 2019', 'May 2019', 'Sep 2019', 'Jan 2020', 'May 2020'] - ); - }); - - it('Generates every six month tick marks with format MM YYYY when month count is 29', () => { - const endTime = DateTime.fromMillis(startTime).plus({month: 29, days: 18}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(5); - expect(result.dates.map(result.format)).toEqual( - ['Jun 2018', 'Dec 2018', 'Jun 2019', 'Dec 2019', 'Jun 2020'] - ); - }); - - it('Generates every six month tick marks with format MM YYYY when month count is 43', () => { - const endTime = DateTime.fromMillis(startTime).plus({month: 42, days: 18}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['Jun 2018', 'Dec 2018', 'Jun 2019', 'Dec 2019', 'Jun 2020', 'Dec 2020', 'Jun 2021'] - ); - }); - - it('Generates every year tick marks with format MM YYYY when month count is 44', () => { - const endTime = DateTime.fromMillis(startTime).plus({month: 44, days: 18}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(3); - expect(result.dates.map(result.format)).toEqual( - ['2019', '2020', '2021'] - ); - }); - - it('Generates every year tick marks with format MM YYYY when year count is 8', () => { - const endTime = DateTime.fromMillis(startTime).plus({year : 7}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['2019', '2020', '2021', '2022', '2023', '2024', '2025'] - ); - }); - - it('Generates 7 tick marks with format YYYY when year count is 9', () => { - const endTime = DateTime.fromMillis(startTime).plus({year : 9}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['2019', '2020', '2021', '2022', '2023', '2024', '2026'] - ); - }); - - it('Generates 7 tick marks with format YYYY when year count is large', () => { - const endTime = DateTime.fromMillis(startTime).plus({year : 20}).toMillis(); - const result = generateDateTicks(startTime, endTime, timeZone); - - expect(result.dates.length).toBe(7); - expect(result.dates.map(result.format)).toEqual( - ['2020', '2023', '2025', '2028', '2030', '2033', '2035'] - ); - }); - - -/* - const endDate = 1504215240000; - const startP7D = 1503610440000; - const startP30D = 1501623240000; - const startP1Y = 1472679240000; - const startCustomUnderOneDecade = 1274590800000; - const startCustomOverTwoDecades = 651906000000; - - it('creates tick marks for a 7 day period', () => { - const result = generateDateTicks(startP7D, endDate, 'P7D', timeZone); - expect(result).toEqual([ - 1503644400000, - 1503730800000, - 1503817200000, - 1503903600000, - 1503990000000, - 1504076400000, - 1504162800000 - ]); - }); - - it('uses weekly ticks for 7 or fewer days for a custom date range', () => { - const result = generateDateTicks(startP7D, endDate, 'custom', timeZone); - expect(result).toEqual([ - 1503644400000, - 1503730800000, - 1503817200000, - 1503903600000, - 1503990000000, - 1504076400000, - 1504162800000 - ]); - }); - - it('creates tick marks for a 30 day period', () => { - const result = generateDateTicks(startP30D, endDate, 'P30D', timeZone); - expect(result).toEqual([ - 1502002800000, - 1502607600000, - 1503212400000, - 1503817200000 - ]); - }); - - it('uses weekly ticks for a different of days 7 between 30 for a custom date range', () => { - const result = generateDateTicks(startP30D, endDate, 'custom', timeZone); - expect(result).toEqual([ - 1502002800000, - 1502607600000, - 1503212400000, - 1503817200000 - ]); - }); - - it('creates tick marks for a 1 year period', () => { - const result = generateDateTicks(startP1Y, endDate, 'P1Y', timeZone); - expect(result.length).toBeGreaterThanOrEqual(6); - expect(result.includes(1475305200000)).toBe(true); - expect(result.includes(1480579200000)).toBe(true); - expect(result.includes(1496300400000)).toBe(true); - expect(result.includes(1501570800000)).toBe(true); - }); - - it('custom uses monthly marks for 30 days through a year', () => { - const result = generateDateTicks(startP1Y, endDate, 'custom', timeZone); - expect(result.length).toBeGreaterThanOrEqual(6); - expect(result.includes(1475305200000)).toBe(true); - expect(result.includes(1480579200000)).toBe(true); - expect(result.includes(1496300400000)).toBe(true); - expect(result.includes(1501570800000)).toBe(true); - }); - - it('custom ticks are correctly generated for dates under one decade', () => { - const result = generateDateTicks(startCustomUnderOneDecade, endDate, 'custom', timeZone); - expect(result).toEqual([ - 1293868800000, - 1314860400000, - 1335855600000, - 1357027200000, - 1378018800000, - 1398927600000, - 1420099200000, - 1441090800000, - 1462086000000, - 1483257600000 - ]); - }); - - it('custom ticks use correctly for dates over two decades', () => { - const result = generateDateTicks(startCustomOverTwoDecades, endDate, 'custom', timeZone); - expect(result).toEqual([ - 723196800000, - 796723200000, - 870418800000, - 944035200000, - 1017648000000, - 1091343600000, - 1164960000000, - 1238569200000, - 1312182000000, - 1385884800000, - 1459494000000 - ]); - }); - */ - }); -}); diff --git a/assets/src/scripts/d3-rendering/axes-spec.js b/assets/src/scripts/d3-rendering/axes-spec.js deleted file mode 100644 index 7ff4d78434e796d72e785d42bb0a256bb517fbf9..0000000000000000000000000000000000000000 --- a/assets/src/scripts/d3-rendering/axes-spec.js +++ /dev/null @@ -1,100 +0,0 @@ -import {select} from 'd3-selection'; - -import {appendXAxis, appendYAxis, appendSecondaryYAxis, appendAxes} from './axes'; - -describe('axes module', () => { - let svg, layout; - - beforeEach(() => { - layout = { - width: 550, - height: 900, - margin: { - top: 10, - bottom: 10, - left: 25, - right: 25 - } - }; - svg = select('body').append('svg'); - }); - - afterEach(() => { - svg.remove(); - }); - - describe('appendXAxis', () => { - let xAxis; - beforeEach(() => { - xAxis = jasmine.createSpy('mockXAxis'); - - }); - it('should render the xAxis', () => { - appendXAxis(svg, {xAxis, layout}); - - expect(svg.selectAll('.x-axis').size()).toBe(1); - expect(xAxis).toHaveBeenCalled(); - }); - }); - - describe('appendYAxis', () => { - let yAxis; - beforeEach(() => { - yAxis = jasmine.createSpy('mockYAxis'); - }); - - it('should render the yAxis', () => { - appendYAxis(svg, {yAxis, layout, yTitle: 'The Y Axis Title'}); - - expect(svg.selectAll('.y-axis').size()).toBe(1); - expect(svg.selectAll('.y-axis-label').size()).toBe(1); - expect(svg.select('.y-axis-label').select('tspan').html()).toEqual('The Y Axis Title'); - expect(yAxis).toHaveBeenCalled(); - }); - }); - - describe('appendSecondaryYAxis', () => { - let yAxis; - beforeEach(() => { - yAxis = jasmine.createSpy('mockYAxis'); - }); - - it('should render the secondaryYAxis', () => { - appendSecondaryYAxis(svg, {yAxis, layout, yTitle: 'The Secondary Y Axis Title'}); - - expect(svg.selectAll('.secondary-y-axis').size()).toBe(1); - expect(svg.selectAll('.secondary-y-axis-label').size()).toBe(1); - expect(svg.select('.secondary-y-axis-label').select('tspan').html()).toEqual('The Secondary Y Axis Title'); - expect(yAxis).toHaveBeenCalled(); - }); - }); - - describe('appendAxes', () => { - let xAxis, yAxis, secondaryYAxis; - beforeEach(() => { - xAxis = jasmine.createSpy('mockXAxis'); - yAxis = jasmine.createSpy('mockYAxis'); - }); - - it('should render all three axes if a secondaryYAxis is defined', () => { - secondaryYAxis = jasmine.createSpy('mockYAxis'); - appendAxes(svg, {xAxis, yAxis, secondaryYAxis, layout, ytitle: 'One Title', secondaryYTitle: 'Two Title'}); - - expect(svg.selectAll('.x-axis').size()).toBe(1); - expect(svg.selectAll('.y-axis').size()).toBe(1); - expect(svg.selectAll('.y-axis-label').size()).toBe(1); - expect(svg.selectAll('.secondary-y-axis').size()).toBe(1); - expect(svg.selectAll('.secondary-y-axis-label').size()).toBe(1); - }); - - it('should render only one y axis if a secondaryYAxis is not defined', () => { - appendAxes(svg, {xAxis, yAxis, secondaryYAxis: null, layout, ytitle: 'One Title', secondaryYTitle: 'Two Title'}); - - expect(svg.selectAll('.x-axis').size()).toBe(1); - expect(svg.selectAll('.y-axis').size()).toBe(1); - expect(svg.selectAll('.y-axis-label').size()).toBe(1); - expect(svg.selectAll('.secondary-y-axis').size()).toBe(0); - expect(svg.selectAll('.secondary-y-axis-label').size()).toBe(0); - }); - }); -}); \ No newline at end of file diff --git a/assets/src/scripts/d3-rendering/tick-marks.js b/assets/src/scripts/d3-rendering/tick-marks.js new file mode 100644 index 0000000000000000000000000000000000000000..e2d31191c2ed95b9f14cc6cf3e3b3f2174414685 --- /dev/null +++ b/assets/src/scripts/d3-rendering/tick-marks.js @@ -0,0 +1,171 @@ +import {DateTime, Interval} from 'luxon'; + +/* + * Return ticks between startDateTime and endDateTime where the tick marks are interval apart and + * start at startOffset + * @param {DateTime} startDateTime + * @param {DateTime} endDateTime + * @param {Object} interval - a Luxon object that can be used in the .plus method + * @param {Object} startOffset - a Luxon object than can be used in the .plus method + * @return {Array of Number} - tick marks in milliseconds. + */ +const getTicks = function(startDateTime, endDateTime, interval, startOffset ) { + let dateTime; + const startOffsetKind = Object.keys(startOffset)[0]; + if (startOffsetKind === 'years') { + dateTime = startDateTime.startOf('year'); + } else if (startOffsetKind === 'months') { + dateTime = startDateTime.startOf('month'); + } else { + dateTime = startDateTime.startOf('day'); + } + dateTime = dateTime.plus(startOffset); + + let result = []; + while (dateTime < endDateTime) { + console.log(`${dateTime.toFormat('f')}`); + result.push(dateTime.toMillis()); + dateTime = dateTime.plus(interval); + } + return result; +}; + +/* + * Returns an array of tickCount tick marks between startDate and endDate. The tick marks will + * always start on unit where unit represents a string that can be used by the Luxon method .startOf. + * @param {Number} startMillis in milliseconds + * @param {Number} endMillis in milliseconds + * @param {String} unit - string that can be used with the luxon method .startOf + * @param {String} tickCount - the desired number of ticks + * @param {String} ianaTimeZone - used when converting time in milliseconds to DateTime. + * @return {Array of Number} - tick marks in milliseconds. + */ +const getDefaultTicks = function (startMillis, endMillis, unit, tickCount, ianaTimeZone) { + const tickInterval = (endMillis - startMillis) / (tickCount + 1); + const endDateTime = DateTime.fromMillis(endMillis, {zone: ianaTimeZone}); + let result = []; + + let dateTime = DateTime.fromMillis(startMillis + tickInterval, {zone: ianaTimeZone}); + while (dateTime < endDateTime) { + let tickDateTime = dateTime.startOf(unit); + console.log(`Default ${tickDateTime.toFormat('f')}`); + result.push(tickDateTime.toMillis()); + dateTime = dateTime.plus(tickInterval); + } + + return result; + }; + +/** + * Generate the values for ticks to place on a time series graph along with an appropriate format function + * that can be used to produce a string representing the tick value. This should be used for time series that have + * minute accuracy. + * + * @param startMillis - start datetime in the form of milliseconds since 1970-01-01 UTC + * @param endMillis - end datetime in the form of milliseconds since 1970-01-01 UTC + * @param ianaTimeZone - Internet Assigned Numbers Authority designation for a time zone + * @returns {Object} with two properties, dates {Array of Number timestamp in milliseconds} and + * format {String} the format that should be used used to display the dates. + */ +export const generateTimeTicks = function(startMillis, endMillis, ianaTimeZone) { + const startDateTime = DateTime.fromMillis(startMillis, {zone: ianaTimeZone}); + const endDateTime = DateTime.fromMillis(endMillis, {zone: ianaTimeZone}); + const length = Interval.fromDateTimes(startDateTime, endDateTime); + const dayCount = length.count('days'); + const weekCount = length.count('weeks'); + const monthCount = length.count('months'); + const yearCount = length.count('years'); + + const formatFnc = (format) => { + return function(timeInMillis) { + return DateTime.fromMillis(timeInMillis, {zone: ianaTimeZone}).toFormat(format); + }; + }; + + let result = { + dates: [], + format: null + }; + + if (length.count('hours') <= 4) { + result = { + dates: getDefaultTicks(startMillis, endMillis, 'minute', 4, ianaTimeZone), + format: formatFnc('MMM dd HH:mm') + }; + } else if (dayCount <= 3) { + // Generates 4 tick marks that are on the start of a minute + result = { + dates: getDefaultTicks(startMillis, endMillis,'hour', 4, ianaTimeZone), + format: formatFnc('MMM dd HH:mm') + }; + } else if (dayCount > 3 && dayCount <= 8) { + // Tick marks are daily + result = { + dates: getTicks(startDateTime, endDateTime,{days: 1}, {days: 1}), + format: formatFnc('MMM dd') + }; + + } else if (dayCount > 8 && dayCount <= 15) { + // Tick marks are ever other day + result = { + dates: getTicks(startDateTime, endDateTime,{days: 2}, {days: 1}), + format: formatFnc('MMM dd') + }; + } else if (dayCount > 15 && dayCount <= 29) { + //Tick marks every fourth day + result = { + dates: getTicks(startDateTime, endDateTime,{days: 4}, {days: 1}), + format: formatFnc('MMM dd') + }; + } else if (weekCount > 4 && weekCount <= 8) { + //Tick marks every week + result = { + dates: getTicks(startDateTime, endDateTime,{weeks: 1}, {days: 3}), + format: formatFnc('MMM dd') + }; + } else if (weekCount > 8 && weekCount <= 15) { + // Tick marks every other week + result = { + dates: getTicks(startDateTime, endDateTime,{weeks: 2}, {days: 7}), + format: formatFnc('MMM dd') + }; + } else if (weekCount > 15 && monthCount <= 8) { + //Tick marks every month + result = { + dates: getTicks(startDateTime, endDateTime,{months: 1}, {months : 1}), + format: formatFnc('MMM yyyy') + }; + } else if (monthCount > 8 && monthCount <= 15) { + //Tick marks every other month + result = { + dates: getTicks(startDateTime, endDateTime,{months: 2}, {months: 1}), + format: formatFnc('MMM yyyy') + }; + } else if (monthCount > 15 && monthCount <= 29){ + // Tick marks every 4 months + result = { + dates: getTicks(startDateTime, endDateTime,{months: 4}, {months: 2}), + format: formatFnc('MMM yyyy') + }; + } else if (monthCount > 29 && monthCount <= 43) { + // Tick marks every 6 months + result = { + dates: getTicks(startDateTime, endDateTime,{months: 6}, {months: 3}), + format: formatFnc('MMM yyyy') + }; + } else if (monthCount > 43 && yearCount <= 8) { + // Tick marks every year + result = { + dates: getTicks(startDateTime, endDateTime,{years: 1}, {years: 1}), + format: formatFnc('yyyy') + }; + } else { + // Generate 7 tick marks and put them at the beginning of the year of that date. + result = { + dates: getDefaultTicks(startMillis, endMillis, 'year', 7, ianaTimeZone), + format: formatFnc('yyyy') + }; + } + + return result; +}; \ No newline at end of file diff --git a/assets/src/scripts/d3-rendering/tick-marks.spec.js b/assets/src/scripts/d3-rendering/tick-marks.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..96926de3ccfe32bb54ba21f000059aec78fa75c8 --- /dev/null +++ b/assets/src/scripts/d3-rendering/tick-marks.spec.js @@ -0,0 +1,288 @@ +import {DateTime} from 'luxon'; + +import {generateTimeTicks} from './tick-marks'; + +describe('generateTimeTicks', () => { + const startTime = 1520538281000; + const timeZone = 'America/Chicago'; + + it('Generates 4 ticks when the hours length is less than 4', () => { + const endTime = DateTime.fromMillis(startTime).plus({hours: 3}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(4); + expect(result.dates.map(result.format)).toEqual( + ['Mar 08 14:20', 'Mar 08 14:56', 'Mar 08 15:32', 'Mar 08 16:08'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).second).toBe(0); + }); + + it('Generates 4 ticks when the hours length is greater than 4', () => { + const endTime = DateTime.fromMillis(startTime).plus({hours: 5}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(4); + expect(result.dates.map(result.format)).toEqual( + ['Mar 08 14:00', 'Mar 08 15:00', 'Mar 08 16:00', 'Mar 08 17:00'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).minute).toBe(0); + }); + + it('Generates 4 ticks with format MMM dd HH:mm when the day length is 2', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 2}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(4); + expect(result.dates.map(result.format)).toEqual( + ['Mar 08 23:00', 'Mar 09 08:00', 'Mar 09 18:00', 'Mar 10 04:00'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).second).toBe(0); + }); + + it('Generates day length tick marks with format MMM dd when length is 7 days', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 7}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['Mar 09', 'Mar 10', 'Mar 11', 'Mar 12', 'Mar 13', 'Mar 14', 'Mar 15'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).hour).toBe(0); + }); + + it('Generates day length tick marks with format MMM dd when length is 4 days', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 3}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(3); + expect(result.dates.map(result.format)).toEqual( + ['Mar 09', 'Mar 10', 'Mar 11'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).hour).toBe(0); + }); + + it('Generates every other day tick marks with format MMM dd when length is 8 days', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 8}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(4); + expect(result.dates.map(result.format)).toEqual( + ['Mar 09', 'Mar 11', 'Mar 13', 'Mar 15'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).hour).toBe(0); + }); + + it('Generates every other day tick marks with format MMM dd when length is 14', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 14}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['Mar 09', 'Mar 11', 'Mar 13', 'Mar 15', 'Mar 17', 'Mar 19', 'Mar 21'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).hour).toBe(0); + }); + + it('Generates every fourth day tick marks with format MMM dd when length is 15', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 15}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(4); + expect(result.dates.map(result.format)).toEqual( + ['Mar 09', 'Mar 13', 'Mar 17', 'Mar 21'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).hour).toBe(0); + }); + + it('Generates every fourth day tick marks with format MMM dd when length is 28', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 28}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['Mar 09', 'Mar 13', 'Mar 17', 'Mar 21', 'Mar 25', 'Mar 29', 'Apr 02'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).hour).toBe(0); + }); + + it('Generates every week tick marks with format MM dd when day count is 29', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 29}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(4); + expect(result.dates.map(result.format)).toEqual( + ['Mar 11', 'Mar 18', 'Mar 25', 'Apr 01'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).hour).toBe(0); + }); + + it('Generates every week tick marks with format MM dd when week count is 8', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 50}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['Mar 11', 'Mar 18', 'Mar 25', 'Apr 01', 'Apr 08', 'Apr 15', 'Apr 22'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).hour).toBe(0); + }); + + it('Generates every two week tick marks with format MM dd when week count is 9', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 53}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(4); + expect(result.dates.map(result.format)).toEqual( + ['Mar 15', 'Mar 29', 'Apr 12', 'Apr 26'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).hour).toBe(0); + }); + + it('Generates every two week tick marks with format MM dd when week count is 16', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 98}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['Mar 15', 'Mar 29', 'Apr 12', 'Apr 26', 'May 10', 'May 24', 'Jun 07'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).hour).toBe(0); + }); + + it('Generates every month tick marks with format MM YYYY when week count is 17', () => { + const endTime = DateTime.fromMillis(startTime).plus({days: 126}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(4); + expect(result.dates.map(result.format)).toEqual( + ['Apr 2018', 'May 2018', 'Jun 2018', 'Jul 2018'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); + + it('Generates every month tick marks with format MM YYYY when month count is 7', () => { + const endTime = DateTime.fromMillis(startTime).plus({month: 7, days: 1}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['Apr 2018', 'May 2018', 'Jun 2018', 'Jul 2018', 'Aug 2018', 'Sep 2018', 'Oct 2018'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); + + it('Generates every other month tick marks with format MM YYYY when month count is 8', () => { + const endTime = DateTime.fromMillis(startTime).plus({month: 8, days: 18}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(4); + expect(result.dates.map(result.format)).toEqual( + ['Apr 2018', 'Jun 2018', 'Aug 2018', 'Oct 2018'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); + + it('Generates every other month tick marks with format MM YYYY when month count is 14', () => { + const endTime = DateTime.fromMillis(startTime).plus({month: 14, days: 18}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['Apr 2018', 'Jun 2018', 'Aug 2018', 'Oct 2018', 'Dec 2018', 'Feb 2019', 'Apr 2019'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); + + it('Generates every four month tick marks with format MM YYYY when month count is 15', () => { + const endTime = DateTime.fromMillis(startTime).plus({month: 15, days: 18}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(4); + expect(result.dates.map(result.format)).toEqual( + ['May 2018', 'Sep 2018', 'Jan 2019', 'May 2019'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); + + it('Generates every four month tick marks with format MM YYYY when month count is 28', () => { + const endTime = DateTime.fromMillis(startTime).plus({month: 28, days: 18}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['May 2018', 'Sep 2018', 'Jan 2019', 'May 2019', 'Sep 2019', 'Jan 2020', 'May 2020'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); + + it('Generates every six month tick marks with format MM YYYY when month count is 29', () => { + const endTime = DateTime.fromMillis(startTime).plus({month: 29, days: 18}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(5); + expect(result.dates.map(result.format)).toEqual( + ['Jun 2018', 'Dec 2018', 'Jun 2019', 'Dec 2019', 'Jun 2020'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); + + it('Generates every six month tick marks with format MM YYYY when month count is 43', () => { + const endTime = DateTime.fromMillis(startTime).plus({month: 42, days: 18}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['Jun 2018', 'Dec 2018', 'Jun 2019', 'Dec 2019', 'Jun 2020', 'Dec 2020', 'Jun 2021'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); + + it('Generates every year tick marks with format YYYY when month count is 44', () => { + const endTime = DateTime.fromMillis(startTime).plus({month: 44, days: 18}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(3); + expect(result.dates.map(result.format)).toEqual( + ['2019', '2020', '2021'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).month).toBe(1); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + + }); + + it('Generates every year tick marks with format MM YYYY when year count is 8', () => { + const endTime = DateTime.fromMillis(startTime).plus({year: 7}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['2019', '2020', '2021', '2022', '2023', '2024', '2025'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).month).toBe(1); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); + + it('Generates 7 tick marks with format YYYY when year count is 9', () => { + const endTime = DateTime.fromMillis(startTime).plus({year: 9}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['2019', '2020', '2021', '2022', '2023', '2024', '2026'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).month).toBe(1); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); + + it('Generates 7 tick marks with format YYYY when year count is large', () => { + const endTime = DateTime.fromMillis(startTime).plus({year: 20}).toMillis(); + const result = generateTimeTicks(startTime, endTime, timeZone); + + expect(result.dates.length).toBe(7); + expect(result.dates.map(result.format)).toEqual( + ['2020', '2023', '2025', '2028', '2030', '2033', '2035'] + ); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).month).toBe(1); + expect(DateTime.fromMillis(result.dates[0], {zone: timeZone}).day).toBe(1); + }); +}); \ No newline at end of file diff --git a/assets/src/scripts/index.spec.js b/assets/src/scripts/index.spec.js index d76d52388f7970f3c6810c864b8cbd97cc523819..b37f248ced2fbd81126b13c743ed9ea902e75ec7 100644 --- a/assets/src/scripts/index.spec.js +++ b/assets/src/scripts/index.spec.js @@ -8,17 +8,19 @@ */ import './polyfills'; -/* + import './ajax.spec'; import './d3-rendering/accessibility.spec'; import './d3-rendering/alerts.spec'; import './d3-rendering/axes.spec'; import './d3-rendering/cursor-slider.spec'; -import './d3-rendering/loading-indicator.spec'; import './d3-rendering/graph-tooltip.spec'; -import './d3-rendering/markers.spec'; import './d3-rendering/legend.spec'; +import './d3-rendering/loading-indicator.spec'; +import './d3-rendering/markers.spec'; +import './d3-rendering/tick-marks.spec'; + import './components/dailyValueHydrograph/selectors/labels.spec'; import './components/dailyValueHydrograph/selectors/scales.spec'; @@ -32,9 +34,6 @@ import './components/dailyValueHydrograph/tooltip.spec'; import './components/embed.spec'; import './components/hydrograph/audible.spec'; - */ -import './components/hydrograph/axes.spec'; -/* import './components/hydrograph/cursor.spec'; import './components/hydrograph/date-controls.spec'; import './components/hydrograph/domain.spec'; @@ -86,4 +85,3 @@ import './web-services/models.spec'; import './web-services/nldi-data.spec'; import './web-services/observations-spec'; import './web-services/statistics-data.spec'; -*/ \ No newline at end of file diff --git a/assets/src/scripts/utils.js b/assets/src/scripts/utils.js index 200c309c9dc397b7b4eeec2c409cc1a7bad000b9..0d5d3520ee03c6ec54655b0624af7e2a93d250d8 100644 --- a/assets/src/scripts/utils.js +++ b/assets/src/scripts/utils.js @@ -45,23 +45,6 @@ export const replaceHtmlEntities = function (someString) { return someString; }; -/** - * Calculate the difference in days between two Date objects - * - * @param date1 - * @param date2 - * @returns {number} - */ -export const deltaDays = function (date1, date2) { - let one_day_ms = 24*60*60*1000; - let date1_ms = date1.getTime(); - let date2_ms = date2.getTime(); - - let delta_ms = date2_ms - date1_ms; - - return Math.round(delta_ms/one_day_ms); -}; - /** * Determine if two sets are equal * diff --git a/assets/src/scripts/utils.spec.js b/assets/src/scripts/utils.spec.js index 3bd77fd821791a81648f8bd16adbff3300f83117..1556f1937bd7d186b3d1bdda375595f8b501dc5f 100644 --- a/assets/src/scripts/utils.spec.js +++ b/assets/src/scripts/utils.spec.js @@ -1,6 +1,6 @@ import {select} from 'd3-selection'; import { - unicodeHtmlEntity, getHtmlFromString, deltaDays, replaceHtmlEntities, setEquality, + unicodeHtmlEntity, getHtmlFromString, replaceHtmlEntities, setEquality, wrap, mediaQuery, calcStartTime, callIf, parseRDB, convertFahrenheitToCelsius, convertCelsiusToFahrenheit, sortedParameters, getNearestTime} from './utils'; @@ -32,29 +32,6 @@ describe('Utils module', () => { }); }); - describe('deltaDays', () => { - - const date1 = new Date(2017, 2, 26, 16, 15, 0); - const date2 = new Date(2017, 3, 2, 4, 30, 0); - const date3 = new Date(2017, 3, 2, 21, 15, 0); - const date4 = new Date(2017, 2, 30, 16, 15, 0); - - it('Returns the correct number of days when it is a bit less than an integer number of days', () => { - let result = deltaDays(date1, date2); - expect(result).toBe(7); - }); - - it('Returns the correct number of days when it is a bit more than an integer number of days', () => { - let result = deltaDays(date1, date3); - expect(result).toBe(7); - }); - - it('Returns the correct number of days when it is an exact integer number days', () => { - let result = deltaDays(date1, date4); - expect(result).toBe(4); - }); - }); - describe('replaceHtmlEntities', () => { it('replaces html entities with unicode', () => {