date-fns#addDays JavaScript Examples
The following examples show how to use
date-fns#addDays.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: locations.js From app-personium-trails with Apache License 2.0 | 6 votes |
async getVisitsByDate(date) {
const from = date.getTime();
const to = addDays(date, 1).getTime() - 1;
return await (
await fetch(
`${handler.boxUrl}index/Visit?$filter=startTime ge ${from} and endTime lt ${to}`
)
).json();
}
Example #2
Source File: locations.js From app-personium-trails with Apache License 2.0 | 6 votes |
async getStaysByDate(date) {
const from = date.getTime();
const to = addDays(date, 1).getTime() - 1;
return await (
await fetch(
`${handler.boxUrl}index/Stay?$filter=startTime ge ${from} and endTime lt ${to}`
)
).json();
}
Example #3
Source File: Map.test.js From ProjectLockdown with GNU General Public License v3.0 | 6 votes |
props = {
dark: "false",
selectedDate: toJsonString(addDays(new Date(), startingPoint)),
startDate: addDays(new Date(), startingPoint),
onOpen: jest.fn(),
daysRange: 70,
isCountrySearchVisible: false,
mapCord: coords,
}
Example #4
Source File: locations_direct.js From app-personium-trails with Apache License 2.0 | 6 votes |
async getTimelineByDate(date) {
// fetch stat and fire event
const from = getYMDFromDate(date);
const to = getYMDFromDate(addDays(date, 1));
const days = Array.from(new Set([from, to]));
return Promise.all(
days.map(ymd =>
statDirectory(
`${this.current_box_url}locations/${ymd}`,
this.current_access_token
)
)
)
.then(results => new Map([].concat(...results.map(res => [...res]))))
.then(results => {
[...results].forEach(([key, val]) => statListener.fire(key, val));
return results;
});
}
Example #5
Source File: utils.js From nyc-makers-vs-covid with GNU General Public License v3.0 | 6 votes |
export function shouldFormatDateDistance(date) {
let deliveryDate = parse(date, 'MM/dd/yyyy', new Date())
let fourDaysFromDeliveryDate = addDays(deliveryDate, 4)
return isBefore(startOfToday(), fourDaysFromDeliveryDate)
}
Example #6
Source File: locations_direct.js From app-personium-trails with Apache License 2.0 | 6 votes |
async getEntityByDate(entityName, date) {
this.refreshOHandler();
const from = date.getTime();
const to = addDays(date, 1).getTime() - 1;
return await this.oHandler
.get(entityName)
.query({
$filter: `startTime ge ${from} and startTime lt ${to}`,
$format: 'json',
})
.then(res => {
console.log(res);
return res;
})
.then(res => res.d.results);
}
Example #7
Source File: GroupingLegend.js From discovery-mobile-ui with MIT License | 5 votes |
formatDays = (numDays) => {
const d = new Date();
return formatDistanceStrict(d, addDays(d, numDays), { unit: 'day' });
}
Example #8
Source File: DatePicker.js From react-horizontal-datepicker with MIT License | 5 votes |
DatePicker = (props) => {
const next = (event) => {
event.preventDefault();
const e = document.getElementById('container');
const width = e ? e.getBoundingClientRect().width : null;
e.scrollLeft += width - 60;
};
const prev = (event) => {
event.preventDefault();
const e = document.getElementById('container');
const width = e ? e.getBoundingClientRect().width : null;
e.scrollLeft -= width - 60;
};
const primaryColor = props.color? (props.color.indexOf("rgb") > 0?props.color:hexToRgb(props.color)):'rgb(54, 105, 238)';
const startDate = props.startDate || new Date();
const lastDate = addDays(startDate, props.days || 90);
let buttonzIndex = {zIndex: 2};
let buttonStyle = {background: primaryColor};
let Component = DateView;
if (props.type === "month") {
buttonzIndex = {zIndex: 5};
Component = MonthView;
buttonStyle = {background: primaryColor, marginBottom: "5px"};
}
return (
<div className={styles.container}>
<div className={styles.buttonWrapper} style={buttonzIndex}>
<button className={styles.button} style={buttonStyle} onClick={prev}><</button>
</div>
<Component {...props} primaryColor={primaryColor} startDate={startDate} lastDate={lastDate}/>
<div className={styles.buttonWrapper} style={buttonzIndex}>
<button className={styles.button} style={buttonStyle} onClick={next}>></button>
</div>
</div>
)
}
Example #9
Source File: DatePicker.js From react-horizontal-datepicker with MIT License | 5 votes |
DatePicker = props => {
const next = event => {
event.preventDefault();
const e = document.getElementById('container');
const width = e ? e.getBoundingClientRect().width : null;
e.scrollLeft += width - 60;
};
const prev = event => {
event.preventDefault();
const e = document.getElementById('container');
const width = e ? e.getBoundingClientRect().width : null;
e.scrollLeft -= width - 60;
};
const primaryColor = props.color ? props.color.indexOf("rgb") > 0 ? props.color : hexToRgb(props.color) : 'rgb(54, 105, 238)';
const startDate = props.startDate || new Date();
const lastDate = addDays(startDate, props.days || 90);
let buttonzIndex = {
zIndex: 2
};
let buttonStyle = {
background: primaryColor
};
let Component = DateView;
if (props.type === "month") {
buttonzIndex = {
zIndex: 5
};
Component = MonthView;
buttonStyle = {
background: primaryColor,
marginBottom: "5px"
};
}
return /*#__PURE__*/React.createElement("div", {
className: styles.container
}, /*#__PURE__*/React.createElement("div", {
className: styles.buttonWrapper,
style: buttonzIndex
}, /*#__PURE__*/React.createElement("button", {
className: styles.button,
style: buttonStyle,
onClick: prev
}, "<")), /*#__PURE__*/React.createElement(Component, _extends({}, props, {
primaryColor: primaryColor,
startDate: startDate,
lastDate: lastDate
})), /*#__PURE__*/React.createElement("div", {
className: styles.buttonWrapper,
style: buttonzIndex
}, /*#__PURE__*/React.createElement("button", {
className: styles.button,
style: buttonStyle,
onClick: next
}, ">")));
}
Example #10
Source File: LocationFilter.js From app-personium-trails with Apache License 2.0 | 5 votes |
export function LocationFilter({ year, month, day }) {
const [modalOpen, setModalOpen] = useState(false);
const handleOpen = useCallback(() => setModalOpen(true), [setModalOpen]);
const handleClose = useCallback(() => setModalOpen(false), [setModalOpen]);
const history = useHistory();
const handleDayClick = useCallback(
date => {
history.push(
`/locations/${date.getFullYear()}-${date.getMonth() +
1}-${date.getDate()}`
);
setModalOpen(false);
},
[history, setModalOpen]
);
const handleNextClick = useCallback(() => {
const date = new Date(year, month - 1, day);
history.push(getDateString(addDays(date, 1)));
}, [year, month, day, history]);
const handlePrevClick = useCallback(() => {
const date = new Date(year, month - 1, day);
history.push(getDateString(addDays(date, -1)));
}, [year, month, day, history]);
return (
<>
<Modal size="small" onClose={handleClose} open={modalOpen} basic>
<Card centered raised>
<Calendar
value={new Date(year, month - 1, day)}
onClickDay={handleDayClick}
/>
</Card>
</Modal>
<Grid>
<Grid.Column width={3}>
<Button
color="teal"
icon="chevron left"
fluid
onClick={handlePrevClick}
/>
</Grid.Column>
<Grid.Column width={10}>
<Button basic color="teal" onClick={handleOpen} fluid>
<Icon name="calendar" />
{new Date(
Number(year),
Number(month - 1),
Number(day)
).toLocaleDateString()}
</Button>
</Grid.Column>
<Grid.Column width={3}>
<Button
color="teal"
icon="chevron right"
fluid
onClick={handleNextClick}
/>
</Grid.Column>
</Grid>
<Divider />
</>
);
}
Example #11
Source File: init.client.js From audiobookshelf with GNU General Public License v3.0 | 5 votes |
Vue.prototype.$addDaysToDate = (jsdate, daysToAdd) => {
var date = addDays(jsdate, daysToAdd)
if (!date || !isDate(date)) return null
return date
}
Example #12
Source File: init.client.js From audiobookshelf with GNU General Public License v3.0 | 5 votes |
Vue.prototype.$addDaysToToday = (daysToAdd) => {
var date = addDays(new Date(), daysToAdd)
if (!date || !isDate(date)) return null
return date
}
Example #13
Source File: Calendar.js From umami with MIT License | 5 votes |
DaySelector = ({ date, minDate, maxDate, locale, onSelect }) => {
const dateLocale = getDateLocale(locale);
const weekStartsOn = dateLocale?.options?.weekStartsOn || 0;
const startWeek = startOfWeek(date, {
locale: dateLocale,
weekStartsOn,
});
const startMonth = startOfMonth(date);
const startDay = subDays(startMonth, startMonth.getDay() - weekStartsOn);
const month = date.getMonth();
const year = date.getFullYear();
const daysOfWeek = [];
for (let i = 0; i < 7; i++) {
daysOfWeek.push(addDays(startWeek, i));
}
const days = [];
for (let i = 0; i < 35; i++) {
days.push(addDays(startDay, i));
}
return (
<table>
<thead>
<tr>
{daysOfWeek.map((day, i) => (
<th key={i} className={locale}>
{dateFormat(day, 'EEE', locale)}
</th>
))}
</tr>
</thead>
<tbody>
{chunk(days, 7).map((week, i) => (
<tr key={i}>
{week.map((day, j) => {
const disabled = isBefore(day, minDate) || isAfter(day, maxDate);
return (
<td
key={j}
className={classNames({
[styles.selected]: isSameDay(date, day),
[styles.faded]: day.getMonth() !== month || day.getFullYear() !== year,
[styles.disabled]: disabled,
})}
onClick={!disabled ? () => onSelect(day) : null}
>
{day.getDate()}
</td>
);
})}
</tr>
))}
</tbody>
</table>
);
}
Example #14
Source File: date.js From umami with MIT License | 5 votes |
dateFuncs = { minute: [differenceInMinutes, addMinutes, startOfMinute], hour: [differenceInHours, addHours, startOfHour], day: [differenceInCalendarDays, addDays, startOfDay], month: [differenceInCalendarMonths, addMonths, startOfMonth], year: [differenceInCalendarYears, addYears, startOfYear], }
Example #15
Source File: DateView.js From react-horizontal-datepicker with MIT License | 4 votes |
DateView = ({
startDate,
lastDate,
selectDate,
getSelectedDay,
primaryColor,
labelFormat
}) => {
const [selectedDate, setSelectedDate] = useState(null);
const firstSection = {
marginLeft: '40px'
};
const selectedStyle = {
fontWeight: "bold",
width: "45px",
height: "45px",
borderRadius: "50%",
border: `2px solid ${primaryColor}`,
color: primaryColor
};
const labelColor = {
color: primaryColor
};
const getStyles = day => {
return isSameDay(day, selectedDate) ? selectedStyle : null;
};
const getId = day => {
return isSameDay(day, selectedDate) ? 'selected' : "";
};
const renderDays = () => {
const dayFormat = "E";
const dateFormat = "d";
const months = [];
let days = [];
for (let i = 0; i <= differenceInMonths(lastDate, startDate); i++) {
let start, end;
const month = startOfMonth(addMonths(startDate, i));
start = i === 0 ? Number(format(startDate, dateFormat)) - 1 : 0;
end = i === differenceInMonths(lastDate, startDate) ? Number(format(lastDate, "d")) : Number(format(lastDayOfMonth(month), "d"));
for (let j = start; j < end; j++) {
let currentDay = addDays(month, j);
days.push( /*#__PURE__*/React.createElement("div", {
id: `${getId(currentDay)}`,
className: styles.dateDayItem,
style: getStyles(currentDay),
key: currentDay,
onClick: () => onDateClick(currentDay)
}, /*#__PURE__*/React.createElement("div", {
className: styles.dayLabel
}, format(currentDay, dayFormat)), /*#__PURE__*/React.createElement("div", {
className: styles.dateLabel
}, format(currentDay, dateFormat))));
}
months.push( /*#__PURE__*/React.createElement("div", {
className: styles.monthContainer,
key: month
}, /*#__PURE__*/React.createElement("span", {
className: styles.monthYearLabel,
style: labelColor
}, format(month, labelFormat || "MMMM yyyy")), /*#__PURE__*/React.createElement("div", {
className: styles.daysContainer,
style: i === 0 ? firstSection : null
}, days)));
days = [];
}
return /*#__PURE__*/React.createElement("div", {
id: "container",
className: styles.dateListScrollable
}, months);
};
const onDateClick = day => {
setSelectedDate(day);
if (getSelectedDay) {
getSelectedDay(day);
}
};
useEffect(() => {
if (getSelectedDay) {
if (selectDate) {
getSelectedDay(selectDate);
} else {
getSelectedDay(startDate);
}
}
}, []);
useEffect(() => {
if (selectDate) {
if (!isSameDay(selectedDate, selectDate)) {
setSelectedDate(selectDate);
setTimeout(() => {
let view = document.getElementById('selected');
if (view) {
view.scrollIntoView({
behavior: "smooth",
inline: "center",
block: "nearest"
});
}
}, 20);
}
}
}, [selectDate]);
return /*#__PURE__*/React.createElement(React.Fragment, null, renderDays());
}
Example #16
Source File: dateFns.js From the-eye-knows-the-garbage with MIT License | 4 votes |
generateConfig = {
// get
getNow: function getNow() {
return new Date();
},
getWeekDay: function getWeekDay(date) {
return getDay(date);
},
getYear: function getYear(date) {
return _getYear(date);
},
getMonth: function getMonth(date) {
return _getMonth(date);
},
getDate: function getDate(date) {
return _getDate(date);
},
getHour: function getHour(date) {
return getHours(date);
},
getMinute: function getMinute(date) {
return getMinutes(date);
},
getSecond: function getSecond(date) {
return getSeconds(date);
},
// set
addYear: function addYear(date, diff) {
return addYears(date, diff);
},
addMonth: function addMonth(date, diff) {
return addMonths(date, diff);
},
addDate: function addDate(date, diff) {
return addDays(date, diff);
},
setYear: function setYear(date, year) {
return _setYear(date, year);
},
setMonth: function setMonth(date, month) {
return _setMonth(date, month);
},
setDate: function setDate(date, num) {
return _setDate(date, num);
},
setHour: function setHour(date, hour) {
return setHours(date, hour);
},
setMinute: function setMinute(date, minute) {
return setMinutes(date, minute);
},
setSecond: function setSecond(date, second) {
return setSeconds(date, second);
},
// Compare
isAfter: function isAfter(date1, date2) {
return _isAfter(date1, date2);
},
isValidate: function isValidate(date) {
return isValid(date);
},
locale: {
getWeekFirstDay: function getWeekFirstDay(locale) {
var clone = Locale[dealLocal(locale)];
return clone.options.weekStartsOn;
},
getWeek: function getWeek(locale, date) {
return _getWeek(date, {
locale: Locale[dealLocal(locale)]
});
},
format: function format(locale, date, _format) {
if (!isValid(date)) {
return null;
}
return formatDate(date, _format, {
locale: Locale[dealLocal(locale)]
});
},
parse: function parse(locale, text, formats) {
for (var i = 0; i < formats.length; i += 1) {
var format = formats[i];
var formatText = text;
var date = parseDate(formatText, format, new Date(), {
locale: Locale[dealLocal(locale)]
});
if (isValid(date)) {
return date;
}
}
return null;
}
}
}
Example #17
Source File: index.js From neutron with Mozilla Public License 2.0 | 4 votes |
DialogPauseNotifications = () => {
// const classes = useStyles();
const dispatch = useDispatch();
const pauseNotificationsInfo = useSelector((state) => state.notifications.pauseNotificationsInfo);
const showDateTimePicker = useSelector((state) => state.notifications.showDateTimePicker);
const shouldPauseNotifications = pauseNotificationsInfo !== null;
const quickShortcuts = [
{
name: '15 minutes',
calcDate: () => addMinutes(new Date(), 15),
},
{
name: '30 minutes',
calcDate: () => addMinutes(new Date(), 30),
},
{
name: '45 minutes',
calcDate: () => addMinutes(new Date(), 45),
},
{
name: '1 hour',
calcDate: () => addHours(new Date(), 1),
},
{
name: '2 hours',
calcDate: () => addHours(new Date(), 2),
},
{
name: '4 hours',
calcDate: () => addHours(new Date(), 4),
},
{
name: '6 hours',
calcDate: () => addHours(new Date(), 6),
},
{
name: '8 hours',
calcDate: () => addHours(new Date(), 8),
},
{
name: '10 hours',
calcDate: () => addHours(new Date(), 8),
},
{
name: '12 hours',
calcDate: () => addHours(new Date(), 12),
},
{
name: 'Until tomorrow',
calcDate: () => addDays(new Date(), 1),
},
{
name: 'Until next week',
calcDate: () => addWeeks(new Date(), 1),
},
];
const pauseNotif = (tilDate) => {
requestSetPreference('pauseNotifications', `pause:${tilDate.toString()}`);
requestShowNotification({
title: 'Notifications paused',
body: `Notifications paused until ${formatDate(tilDate)}.`,
});
getCurrentWindow().close();
};
const renderList = () => {
if (shouldPauseNotifications) {
return (
<List
dense
disablePadding
>
<ListItem sx={{
background: `url(${nightBackgroundPng})`,
height: 210,
backgroundSize: 400,
alignItems: 'flex-end',
}}
>
<ListItemText
primary={`Notifications paused until
${formatDate(new Date(pauseNotificationsInfo.tilDate))}.`}
sx={{
color: 'common.white',
}}
/>
</ListItem>
<ListItem button>
<ListItemText
primary="Resume notifications"
onClick={() => {
if (pauseNotificationsInfo.reason === 'scheduled') {
requestSetPreference('pauseNotifications', `resume:${pauseNotificationsInfo.tilDate}`);
} else if (pauseNotificationsInfo.schedule
&& new Date() < new Date(pauseNotificationsInfo.schedule.to)) {
requestSetPreference('pauseNotifications', `resume:${pauseNotificationsInfo.schedule.to}`);
} else {
requestSetPreference('pauseNotifications', null);
}
requestShowNotification({
title: 'Notifications resumed',
body: 'Notifications are now resumed.',
});
getCurrentWindow().close();
}}
/>
</ListItem>
{pauseNotificationsInfo.reason !== 'scheduled' && (
<>
<Divider />
<ListItem
button
onClick={() => {
const template = quickShortcuts.map((shortcut) => ({
label: shortcut.name,
click: () => pauseNotif(shortcut.calcDate()),
}));
template.push({
label: 'Custom',
click: () => dispatch(updateShowDateTimePicker(true)),
});
const menu = Menu.buildFromTemplate(template);
menu.popup({
window: getCurrentWindow(),
});
}}
>
<ListItemText primary="Adjust time" />
<ChevronRightIcon color="action" />
</ListItem>
</>
)}
<Divider />
<ListItem button>
<ListItemText
primary={pauseNotificationsInfo.reason === 'scheduled' ? 'Adjust schedule...' : 'Pause notifications by schedule...'}
onClick={() => {
requestShowPreferencesWindow('notifications');
getCurrentWindow().close();
}}
/>
</ListItem>
</List>
);
}
return (
<List
dense
disablePadding
subheader={<ListSubheader component="div">Pause notifications</ListSubheader>}
>
{quickShortcuts.map((shortcut) => (
<ListItem
button
key={shortcut.name}
onClick={() => pauseNotif(shortcut.calcDate())}
>
<ListItemText primary={shortcut.name} />
</ListItem>
))}
<ListItem
button
onClick={() => dispatch(updateShowDateTimePicker(true))}
>
<ListItemText primary="Custom..." />
</ListItem>
<Divider />
<DateTimePicker
value={new Date()}
onChange={pauseNotif}
label="Custom"
open={showDateTimePicker}
onOpen={() => dispatch(updateShowDateTimePicker(true))}
onClose={() => dispatch(updateShowDateTimePicker(false))}
disablePast
showTodayButton
// eslint-disable-next-line react/jsx-props-no-spreading
renderInput={() => (
<ListItem button>
<ListItemText
primary="Pause notifications by schedule..."
onClick={() => {
requestShowPreferencesWindow('notifications');
getCurrentWindow().close();
}}
/>
</ListItem>
)}
/>
</List>
);
};
return (
<>
{renderList()}
</>
);
}
Example #18
Source File: DateView.js From react-horizontal-datepicker with MIT License | 4 votes |
DateView = ({startDate, lastDate, selectDate, getSelectedDay, primaryColor, labelFormat, marked}) => {
const [selectedDate, setSelectedDate] = useState(null);
const firstSection = {marginLeft: '40px'};
const selectedStyle = {fontWeight:"bold",width:"45px",height:"45px",borderRadius:"50%",border:`2px solid ${primaryColor}`,color:primaryColor};
const labelColor = {color: primaryColor};
const markedStyle = {color: "#8c3737", padding: "2px", fontSize: 12};
const getStyles = (day) => {
return isSameDay(day, selectedDate)?selectedStyle:null;
};
const getId = (day) => {
return isSameDay(day, selectedDate)?'selected':"";
};
const getMarked = (day) => {
let markedRes = marked.find(i => isSameDay(i.date, day));
if (markedRes) {
if (!markedRes?.marked) {
return;
}
return <div style={{ ...markedRes?.style ?? markedStyle }} className={styles.markedLabel}>
{markedRes.text}
</div>;
}
return "";
};
const renderDays = () => {
const dayFormat = "E";
const dateFormat = "d";
const months = [];
let days = [];
// const styleItemMarked = marked ? styles.dateDayItemMarked : styles.dateDayItem;
for (let i = 0; i <= differenceInMonths(lastDate, startDate); i++) {
let start, end;
const month = startOfMonth(addMonths(startDate, i));
start = i === 0 ? Number(format(startDate, dateFormat)) - 1 : 0;
end = i === differenceInMonths(lastDate, startDate) ? Number(format(lastDate, "d")) : Number(format(lastDayOfMonth(month), "d"));
for (let j = start; j < end; j++) {
let currentDay = addDays(month, j);
days.push(
<div id={`${getId(currentDay)}`}
className={marked ? styles.dateDayItemMarked : styles.dateDayItem}
style={getStyles(currentDay)}
key={currentDay}
onClick={() => onDateClick(currentDay)}
>
<div className={styles.dayLabel}>{format(currentDay, dayFormat)}</div>
<div className={styles.dateLabel}>{format(currentDay, dateFormat)}</div>
{getMarked(currentDay)}
</div>
);
}
months.push(
<div className={styles.monthContainer}
key={month}
>
<span className={styles.monthYearLabel} style={labelColor}>
{format(month, labelFormat || "MMMM yyyy")}
</span>
<div className={styles.daysContainer} style={i===0?firstSection:null}>
{days}
</div>
</div>
);
days = [];
}
return <div id={"container"} className={styles.dateListScrollable}>{months}</div>;
}
const onDateClick = day => {
setSelectedDate(day);
if (getSelectedDay) {
getSelectedDay(day);
}
};
useEffect(() => {
if (getSelectedDay) {
if (selectDate) {
getSelectedDay(selectDate);
} else {
getSelectedDay(startDate);
}
}
}, []);
useEffect(() => {
if (selectDate) {
if (!isSameDay(selectedDate, selectDate)) {
setSelectedDate(selectDate);
setTimeout(() => {
let view = document.getElementById('selected');
if (view) {
view.scrollIntoView({behavior: "smooth", inline: "center", block: "nearest"});
}
}, 20);
}
}
}, [selectDate]);
return <React.Fragment>{renderDays()}</React.Fragment>
}
Example #19
Source File: DateRangePickerCalendar.test.js From react-nice-dates with MIT License | 4 votes |
describe('DateRangePickerCalendar', () => {
it('should render', () => {
const { getAllByText } = render(
<DateRangePickerCalendar
locale={locale}
onStartDateChange={() => {}}
onEndDateChange={() => {}}
onFocusChange={() => {}}
/>
)
expect(getAllByText('1').length).toBeGreaterThan(0)
})
it('should call callbacks on date selection', () => {
const handleStartDateChange = jest.fn()
const handleEndDateChange = jest.fn()
const handleFocusChange = jest.fn()
const { getAllByText, rerender } = render(
<DateRangePickerCalendar
locale={locale}
focus={START_DATE}
onStartDateChange={handleStartDateChange}
onEndDateChange={handleEndDateChange}
onFocusChange={handleFocusChange}
/>
)
fireEvent.click(getAllByText('1')[0])
expect(handleStartDateChange).toHaveBeenCalledTimes(1)
expect(handleEndDateChange).toHaveBeenCalledTimes(0)
expect(handleFocusChange).toHaveBeenCalledWith(END_DATE)
rerender(
<DateRangePickerCalendar
locale={locale}
focus={END_DATE}
startDate={startOfMonth(new Date())}
onStartDateChange={handleStartDateChange}
onEndDateChange={handleEndDateChange}
onFocusChange={handleFocusChange}
/>
)
fireEvent.click(getAllByText('2')[0])
expect(handleStartDateChange).toHaveBeenCalledTimes(1)
expect(handleEndDateChange).toHaveBeenCalledTimes(1)
expect(handleFocusChange).toHaveBeenCalledWith(null)
})
it('should display selected date range', () => {
const startDate = startOfMonth(new Date())
const endDate = addDays(startDate, 2)
const { container, getAllByText, rerender } = render(
<DateRangePickerCalendar locale={locale} startDate={startDate} />
)
expect(getAllByText('1')[0].parentElement).toHaveClass('-selected')
expect(container.querySelectorAll('.-selected').length).toBe(1)
rerender(<DateRangePickerCalendar locale={locale} startDate={startDate} endDate={endDate} />)
expect(getAllByText('1')[0].parentElement).toHaveClass('-selected -selected-start')
expect(getAllByText('2')[0].parentElement).toHaveClass('-selected -selected-middle')
expect(getAllByText('3')[0].parentElement).toHaveClass('-selected -selected-end')
expect(container.querySelectorAll('.-selected').length).toBe(3)
})
it('should display pre-selected start date’s month on initial render', () => {
const today = new Date()
const pastDate = subMonths(today, 1)
const monthName = format(pastDate, 'LLLL', { locale })
const { getByText } = render(<DateRangePickerCalendar locale={locale} startDate={pastDate} endDate={today} />)
expect(getByText(monthName, { exact: false })).toBeInTheDocument()
})
it('should display pre-selected end date’s month on initial render', () => {
const pastDate = subMonths(new Date(), 1)
const monthName = format(pastDate, 'LLLL', { locale })
const { getByText } = render(<DateRangePickerCalendar locale={locale} endDate={pastDate} />)
expect(getByText(monthName, { exact: false })).toBeInTheDocument()
})
it('should maintain the selected start date’s time when selecting a new date', () => {
const handleStartDateChange = jest.fn()
const { getByText } = render(
<DateRangePickerCalendar
locale={locale}
focus={START_DATE}
startDate={new Date(2020, 1, 24, 18, 30)}
onStartDateChange={handleStartDateChange}
/>
)
fireEvent.click(getByText('25'))
expect(handleStartDateChange).toHaveBeenCalledWith(new Date(2020, 1, 25, 18, 30))
})
it('should maintain the selected end date’s time when selecting a new date', () => {
const handleEndDateChange = jest.fn()
const { getByText } = render(
<DateRangePickerCalendar
locale={locale}
focus={END_DATE}
endDate={new Date(2020, 1, 24, 18, 30)}
onEndDateChange={handleEndDateChange}
/>
)
fireEvent.click(getByText('25'))
expect(handleEndDateChange).toHaveBeenCalledWith(new Date(2020, 1, 25, 18, 30))
})
it('should allow same day selection by default (when minimumLength is 0)', () => {
const startDate = startOfDay(set(new Date(), { date: 13 }))
const { getByText } = render(<DateRangePickerCalendar locale={locale} focus={END_DATE} startDate={startDate} />)
expect(getByText('13').parentElement).not.toHaveClass('-disabled')
})
it('should disable dates before the start date when selecting an end date with no existing end date selected', () => {
const startDate = startOfDay(set(new Date(), { date: 18 }))
const { getByText } = render(<DateRangePickerCalendar locale={locale} focus={END_DATE} startDate={startDate} />)
expect(getByText('16').parentElement).toHaveClass('-disabled')
expect(getByText('17').parentElement).toHaveClass('-disabled')
expect(getByText('18').parentElement).not.toHaveClass('-disabled')
})
it('should disable dates after the end date when selecting a start date with no existing start date selected', () => {
const endDate = startOfDay(set(new Date(), { date: 13 }))
const { getByText } = render(<DateRangePickerCalendar locale={locale} focus={START_DATE} endDate={endDate} />)
expect(getByText('13').parentElement).not.toHaveClass('-disabled')
expect(getByText('14').parentElement).toHaveClass('-disabled')
expect(getByText('15').parentElement).toHaveClass('-disabled')
})
it('should disable in-between dates when minimumLength is set', () => {
const startDate = startOfDay(set(new Date(), { date: 18 }))
const { getByText } = render(
<DateRangePickerCalendar locale={locale} focus={END_DATE} startDate={startDate} minimumLength={3} />
)
expect(getByText('18').parentElement).toHaveClass('-disabled')
expect(getByText('19').parentElement).toHaveClass('-disabled')
expect(getByText('20').parentElement).toHaveClass('-disabled')
expect(getByText('21').parentElement).not.toHaveClass('-disabled')
})
it('should disable in-between dates when selecting start date and minimumLength is set', () => {
const endDate = startOfDay(set(new Date(), { date: 18 }))
const { getByText } = render(
<DateRangePickerCalendar locale={locale} focus={START_DATE} endDate={endDate} minimumLength={3} />
)
expect(getByText('18').parentElement).toHaveClass('-disabled')
expect(getByText('17').parentElement).toHaveClass('-disabled')
expect(getByText('16').parentElement).toHaveClass('-disabled')
expect(getByText('15').parentElement).not.toHaveClass('-disabled')
})
it('should disable later dates when maximumLength is set', () => {
const startDate = startOfDay(set(new Date(), { date: 13 }))
const { getByText } = render(
<DateRangePickerCalendar locale={locale} focus={END_DATE} startDate={startDate} maximumLength={3} />
)
expect(getByText('13').parentElement).not.toHaveClass('-disabled')
expect(getByText('14').parentElement).not.toHaveClass('-disabled')
expect(getByText('15').parentElement).not.toHaveClass('-disabled')
expect(getByText('16').parentElement).not.toHaveClass('-disabled')
expect(getByText('17').parentElement).toHaveClass('-disabled')
})
it('should disable earlier dates when selecting start date and maximumLength is set', () => {
const endDate = startOfDay(set(new Date(), { date: 18 }))
const { getByText } = render(
<DateRangePickerCalendar locale={locale} focus={START_DATE} endDate={endDate} maximumLength={3} />
)
expect(getByText('18').parentElement).not.toHaveClass('-disabled')
expect(getByText('17').parentElement).not.toHaveClass('-disabled')
expect(getByText('16').parentElement).not.toHaveClass('-disabled')
expect(getByText('15').parentElement).not.toHaveClass('-disabled')
expect(getByText('14').parentElement).toHaveClass('-disabled')
})
})
Example #20
Source File: TimeseriesBrush.js From covid19india-react with MIT License | 4 votes |
function TimeseriesBrush({
timeseries,
dates,
currentBrushSelection,
endDate,
lookback,
setBrushSelectionEnd,
setLookback,
animationIndex,
}) {
const chartRef = useRef();
const [wrapperRef, {width, height}] = useMeasure();
const endDateMin =
lookback !== null
? min([
formatISO(addDays(parseIndiaDate(dates[0]), lookback), {
representation: 'date',
}),
endDate,
])
: endDate;
const xScale = useMemo(() => {
const T = dates.length;
// Chart extremes
const chartRight = width - margin.right;
return scaleTime()
.clamp(true)
.domain([
parseIndiaDate(dates[0] || endDate),
parseIndiaDate(dates[T - 1] || endDate),
])
.range([margin.left, chartRight]);
}, [width, endDate, dates]);
useEffect(() => {
if (!width || !height) return;
// Chart extremes
const chartBottom = height - margin.bottom;
const xAxis = (g) =>
g
.attr('class', 'x-axis')
.call(axisBottom(xScale).ticks(numTicksX(width)));
// Switched to daily confirmed instead of cumulative ARD
const timeseriesStacked = stack()
.keys(BRUSH_STATISTICS)
.value((date, statistic) =>
Math.max(0, getStatistic(timeseries[date], 'delta', statistic))
)(dates);
const yScale = scaleLinear()
.clamp(true)
.domain([
0,
max(
timeseriesStacked[timeseriesStacked.length - 1],
([, y1]) => yBufferTop * y1
),
])
.range([chartBottom, margin.top]);
const svg = select(chartRef.current);
const t = svg.transition().duration(D3_TRANSITION_DURATION);
svg
.select('.x-axis')
.attr('pointer-events', 'none')
.style('transform', `translate3d(0, ${chartBottom}px, 0)`)
.transition(t)
.call(xAxis);
const areaPath = area()
.curve(curveMonotoneX)
.x((d) => xScale(parseIndiaDate(d.data)))
.y0((d) => yScale(d[0]))
.y1((d) => yScale(d[1]));
svg
.select('.trend-areas')
.selectAll('.trend-area')
.data(timeseriesStacked)
.join(
(enter) =>
enter
.append('path')
.attr('class', 'trend-area')
.attr('fill', ({key}) => STATISTIC_CONFIGS[key].color)
.attr('fill-opacity', 0.4)
.attr('stroke', ({key}) => STATISTIC_CONFIGS[key].color)
.attr('d', areaPath)
.attr('pointer-events', 'none'),
(update) =>
update
.transition(t)
.attrTween('d', function (date) {
const previous = select(this).attr('d');
const current = areaPath(date);
return interpolatePath(previous, current);
})
.selection()
);
}, [dates, width, height, xScale, timeseries]);
const defaultSelection = currentBrushSelection.map((date) =>
xScale(parseIndiaDate(date))
);
const brush = useMemo(() => {
if (!width || !height) return;
// Chart extremes
const chartRight = width - margin.right;
const chartBottom = height - margin.bottom;
const brush = brushX()
.extent([
[margin.left, margin.top],
[chartRight, chartBottom],
])
.handleSize(20);
return brush;
}, [width, height]);
const brushed = useCallback(
({sourceEvent, selection}) => {
if (!sourceEvent) return;
const [brushStartDate, brushEndDate] = selection.map(xScale.invert);
ReactDOM.unstable_batchedUpdates(() => {
setBrushSelectionEnd(formatISO(brushEndDate, {representation: 'date'}));
setLookback(differenceInDays(brushEndDate, brushStartDate));
});
},
[xScale, setBrushSelectionEnd, setLookback]
);
const beforebrushstarted = useCallback(
(event) => {
const svg = select(chartRef.current);
const selection = brushSelection(svg.select('.brush').node());
if (!selection) return;
const dx = selection[1] - selection[0];
const [[cx]] = pointers(event);
const [x0, x1] = [cx - dx / 2, cx + dx / 2];
const [X0, X1] = xScale.range();
svg
.select('.brush')
.call(
brush.move,
x1 > X1 ? [X1 - dx, X1] : x0 < X0 ? [X0, X0 + dx] : [x0, x1]
);
},
[brush, xScale]
);
const brushended = useCallback(
({sourceEvent, selection}) => {
if (!sourceEvent || !selection) return;
const domain = selection
.map(xScale.invert)
.map((date) => formatISO(date, {representation: 'date'}));
const svg = select(chartRef.current);
svg
.select('.brush')
.call(
brush.move,
domain.map((date) => xScale(parseIndiaDate(date)))
)
.call((g) => g.select('.overlay').attr('cursor', 'pointer'));
},
[brush, xScale]
);
useEffect(() => {
if (!brush) return;
brush.on('start brush', brushed).on('end', brushended);
const svg = select(chartRef.current);
svg
.select('.brush')
.call(brush)
.call((g) =>
g
.select('.overlay')
.attr('cursor', 'pointer')
.datum({type: 'selection'})
.on('mousedown touchstart', beforebrushstarted)
);
}, [brush, brushed, brushended, beforebrushstarted]);
useEffect(() => {
if (!brush) return;
const svg = select(chartRef.current);
svg.select('.brush').call(brush.move, defaultSelection);
}, [brush, defaultSelection]);
const handleWheel = (event) => {
if (event.deltaX) {
setBrushSelectionEnd(
max([
endDateMin,
dates[
Math.max(
0,
Math.min(
dates.length - 1,
dates.indexOf(currentBrushSelection[1]) +
Math.sign(event.deltaX) * brushWheelDelta
)
)
],
])
);
}
};
return (
<div className="Timeseries">
<div
className={classnames('svg-parent is-brush fadeInUp')}
ref={wrapperRef}
onWheel={handleWheel}
style={{animationDelay: `${animationIndex * 250}ms`}}
>
<svg ref={chartRef} preserveAspectRatio="xMidYMid meet">
<defs>
<clipPath id="clipPath">
<rect
x={0}
y={`${margin.top}`}
width={width}
height={`${Math.max(0, height - margin.bottom)}`}
/>
</clipPath>
<mask id="mask">
<rect
x={0}
y={`${margin.top}`}
width={width}
height={`${Math.max(0, height - margin.bottom)}`}
fill="hsl(0, 0%, 40%)"
/>
<use href="#selection" fill="white" />
</mask>
</defs>
<g className="brush" clipPath="url(#clipPath)">
<g mask="url(#mask)">
<rect className="overlay" />
<g className="trend-areas" />
<rect className="selection" id="selection" />
</g>
</g>
<g className="x-axis" />
</svg>
</div>
</div>
);
}
Example #21
Source File: Home.js From covid19india-react with MIT License | 4 votes |
function Home() {
const [regionHighlighted, setRegionHighlighted] = useState({
stateCode: 'TT',
districtName: null,
});
const [anchor, setAnchor] = useLocalStorage('anchor', null);
const [expandTable, setExpandTable] = useLocalStorage('expandTable', false);
const [mapStatistic, setMapStatistic] = useSessionStorage(
'mapStatistic',
'active'
);
const [mapView, setMapView] = useLocalStorage('mapView', MAP_VIEWS.DISTRICTS);
const [date, setDate] = useState('');
const location = useLocation();
const {data: timeseries} = useStickySWR(
`${DATA_API_ROOT}/timeseries.min.json`,
fetcher,
{
revalidateOnMount: true,
refreshInterval: API_REFRESH_INTERVAL,
}
);
const {data} = useStickySWR(
`${DATA_API_ROOT}/data${date ? `-${date}` : ''}.min.json`,
fetcher,
{
revalidateOnMount: true,
refreshInterval: API_REFRESH_INTERVAL,
}
);
const homeRightElement = useRef();
const isVisible = useIsVisible(homeRightElement);
const {width} = useWindowSize();
const hideDistrictData = date !== '' && date < DISTRICT_START_DATE;
const hideDistrictTestData =
date === '' ||
date >
formatISO(
addDays(parseIndiaDate(DISTRICT_TEST_END_DATE), TESTED_EXPIRING_DAYS),
{representation: 'date'}
);
const hideVaccinated =
getStatistic(data?.['TT'], 'total', 'vaccinated') === 0;
const lastDataDate = useMemo(() => {
const updatedDates = [
data?.['TT']?.meta?.date,
data?.['TT']?.meta?.tested?.date,
data?.['TT']?.meta?.vaccinated?.date,
].filter((date) => date);
return updatedDates.length > 0
? formatISO(max(updatedDates.map((date) => parseIndiaDate(date))), {
representation: 'date',
})
: null;
}, [data]);
const lastUpdatedDate = useMemo(() => {
const updatedDates = Object.keys(data || {})
.map((stateCode) => data?.[stateCode]?.meta?.['last_updated'])
.filter((datetime) => datetime);
return updatedDates.length > 0
? formatDateObjIndia(
max(updatedDates.map((datetime) => parseIndiaDate(datetime)))
)
: null;
}, [data]);
const noDistrictDataStates = useMemo(
() =>
// Heuristic: All cases are in Unknown
Object.entries(data || {}).reduce((res, [stateCode, stateData]) => {
res[stateCode] = !!(
stateData?.districts &&
stateData.districts?.[UNKNOWN_DISTRICT_KEY] &&
PRIMARY_STATISTICS.every(
(statistic) =>
getStatistic(stateData, 'total', statistic) ===
getStatistic(
stateData.districts[UNKNOWN_DISTRICT_KEY],
'total',
statistic
)
)
);
return res;
}, {}),
[data]
);
const noRegionHighlightedDistrictData =
regionHighlighted?.stateCode &&
regionHighlighted?.districtName &&
regionHighlighted.districtName !== UNKNOWN_DISTRICT_KEY &&
noDistrictDataStates[regionHighlighted.stateCode];
return (
<>
<Helmet>
<title>Coronavirus Outbreak in India - covid19india.org</title>
<meta
name="title"
content="Coronavirus Outbreak in India: Latest Map and Case Count"
/>
</Helmet>
<div className="Home">
<div className={classnames('home-left', {expanded: expandTable})}>
<div className="header">
<Suspense fallback={<div />}>
<Search />
</Suspense>
{!data && !timeseries && <div style={{height: '60rem'}} />}
<>
{!timeseries && <div style={{minHeight: '61px'}} />}
{timeseries && (
<Suspense fallback={<div style={{minHeight: '61px'}} />}>
<Actions
{...{
date,
setDate,
dates: Object.keys(timeseries['TT']?.dates),
lastUpdatedDate,
}}
/>
</Suspense>
)}
</>
</div>
<div style={{position: 'relative', marginTop: '1rem'}}>
{data && (
<Suspense fallback={<div style={{height: '50rem'}} />}>
{width >= 769 && !expandTable && (
<MapSwitcher {...{mapStatistic, setMapStatistic}} />
)}
<Level data={data['TT']} />
</Suspense>
)}
<>
{!timeseries && <div style={{height: '123px'}} />}
{timeseries && (
<Suspense fallback={<div style={{height: '123px'}} />}>
<Minigraphs
timeseries={timeseries['TT']?.dates}
{...{date}}
/>
</Suspense>
)}
</>
</div>
{!hideVaccinated && <VaccinationHeader data={data['TT']} />}
{data && (
<Suspense fallback={<TableLoader />}>
<Table
{...{
data,
regionHighlighted,
setRegionHighlighted,
expandTable,
setExpandTable,
hideDistrictData,
hideDistrictTestData,
hideVaccinated,
lastDataDate,
noDistrictDataStates,
}}
/>
</Suspense>
)}
</div>
<div
className={classnames('home-right', {expanded: expandTable})}
ref={homeRightElement}
style={{minHeight: '4rem'}}
>
{(isVisible || location.hash) && (
<>
{data && (
<div
className={classnames('map-container', {
expanded: expandTable,
stickied:
anchor === 'mapexplorer' || (expandTable && width >= 769),
})}
>
<Suspense fallback={<div style={{height: '50rem'}} />}>
<StateHeader data={data['TT']} stateCode={'TT'} />
<MapExplorer
{...{
stateCode: 'TT',
data,
mapStatistic,
setMapStatistic,
mapView,
setMapView,
regionHighlighted,
setRegionHighlighted,
anchor,
setAnchor,
expandTable,
lastDataDate,
hideDistrictData,
hideDistrictTestData,
hideVaccinated,
noRegionHighlightedDistrictData,
}}
/>
</Suspense>
</div>
)}
{timeseries && (
<Suspense fallback={<div style={{height: '50rem'}} />}>
<TimeseriesExplorer
stateCode="TT"
{...{
timeseries,
date,
regionHighlighted,
setRegionHighlighted,
anchor,
setAnchor,
expandTable,
hideVaccinated,
noRegionHighlightedDistrictData,
}}
/>
</Suspense>
)}
</>
)}
</div>
</div>
{isVisible && (
<Suspense fallback={<div />}>
<Footer />
</Suspense>
)}
</>
);
}
Example #22
Source File: timeseries.js From covid19Nepal-react with MIT License | 4 votes |
function TimeSeries({timeseriesProp, chartType, mode, logMode, isTotal}) {
const {t} = useTranslation();
const [lastDaysCount, setLastDaysCount] = useState(
window.innerWidth > 512 ? Infinity : 30
);
const [timeseries, setTimeseries] = useState({});
const [datapoint, setDatapoint] = useState({});
const [index, setIndex] = useState(0);
const [moving, setMoving] = useState(false);
const svgRef1 = useRef();
const svgRef2 = useRef();
const svgRef3 = useRef();
const svgRef4 = useRef();
const svgRef5 = useRef();
const wrapperRef = useRef();
const dimensions = useResizeObserver(wrapperRef);
const transformTimeSeries = useCallback(
(timeseries) => {
if (timeseries.length > 1) {
const slicedTimeseries = sliceTimeseriesFromEnd(
timeseries,
lastDaysCount
);
setIndex(slicedTimeseries.length - 1);
setTimeseries(slicedTimeseries);
}
},
[lastDaysCount]
);
useEffect(() => {
transformTimeSeries(timeseriesProp);
}, [lastDaysCount, timeseriesProp, transformTimeSeries]);
const graphData = useCallback(
(timeseries) => {
if (!dimensions) return;
const width = dimensions.width;
const height = dimensions.height;
// Margins
const margin = {top: 15, right: 35, bottom: 25, left: 25};
const chartRight = width - margin.right;
const chartBottom = height - margin.bottom;
const T = timeseries.length;
const yBufferTop = 1.2;
const yBufferBottom = 1.1;
setDatapoint(timeseries[T - 1]);
setIndex(T - 1);
const svg1 = d3.select(svgRef1.current);
const svg2 = d3.select(svgRef2.current);
const svg3 = d3.select(svgRef3.current);
const svg4 = d3.select(svgRef4.current);
const svg5 = d3.select(svgRef5.current);
const dateMin = subDays(timeseries[0].date, 1);
const dateMax = addDays(timeseries[T - 1].date, 1);
const xScale = d3
.scaleTime()
.clamp(true)
.domain([dateMin, dateMax])
.range([margin.left, chartRight]);
// Number of x-axis ticks
const numTicksX = width < 480 ? 4 : 7;
const xAxis = (g) =>
g.attr('class', 'x-axis').call(d3.axisBottom(xScale).ticks(numTicksX));
const xAxis2 = (g, yScale) => {
g.attr('class', 'x-axis2')
.call(d3.axisBottom(xScale).tickValues([]).tickSize(0))
.select('.domain')
.style('transform', `translateY(${yScale(0)}px)`);
if (yScale(0) !== chartBottom) g.select('.domain').attr('opacity', 0.4);
else g.select('.domain').attr('opacity', 0);
};
const yAxis = (g, yScale) =>
g
.attr('class', 'y-axis')
.call(d3.axisRight(yScale).ticks(4, '0~s').tickPadding(5));
// Arrays of objects
const plotTotal = chartType === 1;
const dataTypesTotal = [
'totalconfirmed',
'totalactive',
'totalrecovered',
'totaldeceased',
'totaltested',
];
const dataTypesDaily = [
'dailyconfirmed',
'dailyactive',
'dailyrecovered',
'dailydeceased',
'dailytested',
];
const colors = ['#ff073a', '#007bff', '#28a745', '#6c757d', '#201aa2'];
const svgArray = [svg1, svg2, svg3, svg4, svg5];
let yScales;
if (plotTotal) {
const uniformScaleMin = d3.min(timeseries, (d) =>
Math.min(d.totalactive, d.totalrecovered, d.totaldeceased)
);
const uniformScaleMax = d3.max(timeseries, (d) => d.totalconfirmed);
const yScaleUniformLinear = d3
.scaleLinear()
.clamp(true)
.domain([uniformScaleMin, Math.max(1, yBufferTop * uniformScaleMax)])
.nice()
.range([chartBottom, margin.top]);
const yScaleUniformLog = d3
.scaleLog()
.clamp(true)
.domain([
Math.max(1, uniformScaleMin),
Math.max(10, yBufferTop * uniformScaleMax),
])
.nice()
.range([chartBottom, margin.top]);
yScales = dataTypesTotal.map((type) => {
const yScaleLinear = d3
.scaleLinear()
.clamp(true)
.domain([
d3.min(timeseries, (d) => d[type]),
Math.max(1, yBufferTop * d3.max(timeseries, (d) => d[type])),
])
.nice()
.range([chartBottom, margin.top]);
const yScaleLog = d3
.scaleLog()
.clamp(true)
.domain([
Math.max(
1,
d3.min(timeseries, (d) => d[type])
),
Math.max(10, yBufferTop * d3.max(timeseries, (d) => d[type])),
])
.nice()
.range([chartBottom, margin.top]);
if (mode && type !== 'totaltested')
return logMode ? yScaleUniformLog : yScaleUniformLinear;
else return logMode ? yScaleLog : yScaleLinear;
});
} else {
const yScaleDailyUniform = d3
.scaleLinear()
.clamp(true)
.domain([
yBufferBottom *
Math.min(
0,
d3.min(timeseries, (d) => d.dailyactive)
),
Math.max(
1,
yBufferTop *
d3.max(timeseries, (d) =>
Math.max(d.dailyconfirmed, d.dailyrecovered, d.dailydeceased)
)
),
])
.nice()
.range([chartBottom, margin.top]);
yScales = dataTypesDaily.map((type) => {
if (mode && type !== 'dailytested') return yScaleDailyUniform;
const yScaleLinear = d3
.scaleLinear()
.clamp(true)
.domain([
yBufferBottom *
Math.min(
0,
d3.min(timeseries, (d) => d[type])
),
Math.max(1, yBufferTop * d3.max(timeseries, (d) => d[type])),
])
.nice()
.range([chartBottom, margin.top]);
return yScaleLinear;
});
}
/* Focus dots */
const focus = svgArray.map((svg, i) => {
return svg
.selectAll('.focus')
.data([timeseries[T - 1]], (d) => d.date)
.join((enter) =>
enter.append('circle').attr('cx', (d) => xScale(d.date))
)
.attr('class', 'focus')
.attr('fill', colors[i])
.attr('stroke', colors[i])
.attr('r', 4);
});
function mousemove() {
const xm = d3.mouse(this)[0];
const date = xScale.invert(xm);
const bisectDate = d3.bisector((d) => d.date).left;
let i = bisectDate(timeseries, date, 1);
if (0 <= i && i < T) {
if (date - timeseries[i - 1].date < timeseries[i].date - date) --i;
setDatapoint(timeseries[i]);
setIndex(i);
setMoving(true);
const d = timeseries[i];
focus.forEach((f, j) => {
const yScale = yScales[j];
const type = plotTotal ? dataTypesTotal[j] : dataTypesDaily[j];
if (!isNaN(d[type]))
f.attr('cx', xScale(d.date))
.attr('cy', yScale(d[type]))
.attr('opacity', 1);
else f.attr('opacity', 0);
});
}
}
function mouseout() {
setDatapoint(timeseries[T - 1]);
setIndex(T - 1);
setMoving(false);
focus.forEach((f, j) => {
const yScale = yScales[j];
const type = plotTotal ? dataTypesTotal[j] : dataTypesDaily[j];
if (!isNaN(timeseries[T - 1][type]))
f.attr('cx', xScale(timeseries[T - 1].date))
.attr('cy', yScale(timeseries[T - 1][type]))
.attr('opacity', 1);
else f.attr('opacity', 0);
});
}
/* Begin drawing charts */
svgArray.forEach((svg, i) => {
// Transition interval
const t = svg.transition().duration(500);
const typeTotal = dataTypesTotal[i];
const typeDaily = dataTypesDaily[i];
const type = plotTotal ? typeTotal : typeDaily;
const filteredTimeseries = timeseries.filter((d) => !isNaN(d[type]));
const color = colors[i];
const yScale = yScales[i];
/* X axis */
svg
.select('.x-axis')
.style('transform', `translateY(${chartBottom}px)`)
.transition(t)
.call(xAxis);
svg.select('.x-axis2').transition(t).call(xAxis2, yScale);
/* Y axis */
svg
.select('.y-axis')
.style('transform', `translateX(${chartRight}px)`)
.transition(t)
.call(yAxis, yScale);
/* Path dots */
svg
.selectAll('.dot')
.data(filteredTimeseries, (d) => d.date)
.join((enter) =>
enter
.append('circle')
.attr('cy', chartBottom)
.attr('cx', (d) => xScale(d.date))
)
.attr('class', 'dot')
.attr('fill', color)
.attr('stroke', color)
.attr('r', 2)
.transition(t)
.attr('cx', (d) => xScale(d.date))
.attr('cy', (d) => yScale(d[type]));
if (!isNaN(timeseries[T - 1][type]))
focus[i]
.transition(t)
.attr('cx', (d) => xScale(d.date))
.attr('cy', (d) => yScale(d[type]))
.attr('opacity', 1);
else focus[i].transition(t).attr('opacity', 0);
if (plotTotal) {
/* TOTAL TRENDS */
svg.selectAll('.stem').remove();
const path = svg
.selectAll('.trend')
.data([[...filteredTimeseries].reverse()])
.join('path')
.attr('class', 'trend')
.attr('fill', 'none')
.attr('stroke', color + '99')
.attr('stroke-width', 4);
// HACK
// Path interpolation is non-trivial. Ideally, a custom path tween
// function should be defined which takes care that old path dots
// transition synchronously along with the path transition. This hack
// simulates that behaviour.
if (path.attr('d')) {
const n = path.node().getTotalLength();
const p = path.node().getPointAtLength(n);
// Append points at end of path for better interpolation
path.attr(
'd',
() => path.attr('d') + `L${p.x},${p.y}`.repeat(3 * T)
);
}
path
.transition(t)
.attr('opacity', plotTotal ? 1 : 0)
.attr(
'd',
d3
.line()
.x((d) => xScale(d.date))
.y((d) => yScale(d[typeTotal]))
.curve(d3.curveMonotoneX)
);
// Using d3-interpolate-path
// .attrTween('d', function (d) {
// var previous = path.attr('d');
// var current = line(d);
// return interpolatePath(previous, current);
// });
} else {
/* DAILY TRENDS */
svg.selectAll('.trend').remove();
svg
.selectAll('.stem')
.data(filteredTimeseries, (d) => d.date)
.join((enter) =>
enter
.append('line')
.attr('x1', (d) => xScale(d.date))
.attr('y1', chartBottom)
.attr('x2', (d) => xScale(d.date))
.attr('y2', chartBottom)
)
.attr('class', 'stem')
.style('stroke', color + '99')
.style('stroke-width', 4)
.transition(t)
.attr('x1', (d) => xScale(d.date))
.attr('y1', yScale(0))
.attr('x2', (d) => xScale(d.date))
.attr('y2', (d) => yScale(d[typeDaily]));
}
svg
.on('mousemove', mousemove)
.on('touchmove', mousemove)
.on('mouseout', mouseout)
.on('touchend', mouseout);
});
},
[chartType, dimensions, logMode, mode]
);
useEffect(() => {
if (timeseries.length > 1) {
graphData(timeseries);
}
}, [timeseries, graphData]);
const dateStr = datapoint.date ? format(datapoint.date, 'dd MMMM') : '';
const chartKey1 = chartType === 1 ? 'totalconfirmed' : 'dailyconfirmed';
const chartKey2 = chartType === 1 ? 'totalactive' : 'dailyactive';
const chartKey3 = chartType === 1 ? 'totalrecovered' : 'dailyrecovered';
const chartKey4 = chartType === 1 ? 'totaldeceased' : 'dailydeceased';
const chartKey5 = chartType === 1 ? 'totaltested' : 'dailytested';
// Function for calculate increased/decreased count for each type of data
const currentStatusCount = (chartType) => {
if (timeseries.length <= 0 || index <= 0 || index >= timeseries.length)
return '';
const currentDiff =
timeseries[index][chartType] - timeseries[index - 1][chartType];
const formatedDiff = formatNumber(currentDiff);
return currentDiff >= 0 ? `+${formatedDiff}` : formatedDiff;
};
return (
<React.Fragment>
<div className="TimeSeries fadeInUp" style={{animationDelay: '2.7s'}}>
<div className="svg-parent" ref={wrapperRef}>
<div className="stats">
<h5 className={`${!moving ? 'title' : ''}`}>{t('Confirmed')}</h5>
<h5 className={`${moving ? 'title' : ''}`}>{`${dateStr}`}</h5>
<div className="stats-bottom">
<h2>{formatNumber(datapoint[chartKey1])}</h2>
<h6>{currentStatusCount(chartKey1)}</h6>
</div>
</div>
<svg ref={svgRef1} preserveAspectRatio="xMidYMid meet">
<g className="x-axis" />
<g className="x-axis2" />
<g className="y-axis" />
</svg>
</div>
<div className="svg-parent is-blue">
<div className="stats is-blue">
<h5 className={`${!moving ? 'title' : ''}`}>{t('Active')}</h5>
<h5 className={`${moving ? 'title' : ''}`}>{`${dateStr}`}</h5>
<div className="stats-bottom">
<h2>{formatNumber(datapoint[chartKey2])}</h2>
<h6>{currentStatusCount(chartKey2)}</h6>
</div>
</div>
<svg ref={svgRef2} preserveAspectRatio="xMidYMid meet">
<g className="x-axis" />
<g className="x-axis2" />
<g className="y-axis" />
</svg>
</div>
<div className="svg-parent is-green">
<div className="stats is-green">
<h5 className={`${!moving ? 'title' : ''}`}>{t('Recovered')}</h5>
<h5 className={`${moving ? 'title' : ''}`}>{`${dateStr}`}</h5>
<div className="stats-bottom">
<h2>{formatNumber(datapoint[chartKey3])}</h2>
<h6>{currentStatusCount(chartKey3)}</h6>
</div>
</div>
<svg ref={svgRef3} preserveAspectRatio="xMidYMid meet">
<g className="x-axis" />
<g className="x-axis2" />
<g className="y-axis" />
</svg>
</div>
<div className="svg-parent is-gray">
<div className="stats is-gray">
<h5 className={`${!moving ? 'title' : ''}`}>{t('Deceased')}</h5>
<h5 className={`${moving ? 'title' : ''}`}>{`${dateStr}`}</h5>
<div className="stats-bottom">
<h2>{formatNumber(datapoint[chartKey4])}</h2>
<h6>{currentStatusCount(chartKey4)}</h6>
</div>
</div>
<svg ref={svgRef4} preserveAspectRatio="xMidYMid meet">
<g className="x-axis" />
<g className="x-axis2" />
<g className="y-axis" />
</svg>
</div>
<div className="svg-parent is-purple">
<div className="stats is-purple">
<h5 className={`${!moving ? 'title' : ''}`}>
{t('Tested')} {isTotal ? testedToolTip : ''}
</h5>
<h5 className={`${moving ? 'title' : ''}`}>{`${dateStr}`}</h5>
<div className="stats-bottom">
<h2>{formatNumber(datapoint[chartKey5])}</h2>
<h6>{currentStatusCount(chartKey5)}</h6>
</div>
</div>
<svg ref={svgRef5} preserveAspectRatio="xMidYMid meet">
<g className="x-axis" />
<g className="x-axis2" />
<g className="y-axis" />
</svg>
</div>
</div>
<div className="pills">
<button
type="button"
onClick={() => setLastDaysCount(Infinity)}
className={lastDaysCount === Infinity ? 'selected' : ''}
>
{t('Beginning')}
</button>
<button
type="button"
onClick={() => setLastDaysCount(30)}
className={lastDaysCount === 30 ? 'selected' : ''}
aria-label="1 month"
>
{`1 ${t('Month')}`}
</button>
<button
type="button"
onClick={() => setLastDaysCount(14)}
className={lastDaysCount === 14 ? 'selected' : ''}
aria-label="14 days"
>
{`2 ${t('Weeks')}`}
</button>
</div>
<div className="alert">
<Icon.AlertOctagon />
<div className="alert-right">
{t('Tested chart is independent of uniform scaling')}
</div>
</div>
</React.Fragment>
);
}
Example #23
Source File: TimeSlider.js From ProjectLockdown with GNU General Public License v3.0 | 4 votes |
TimeSlider = (props) => {
const dark = toBool(props.dark);
const [currentDateValue, setCurrentDateValue] = useState(
firstDayDefaultOffset,
);
const {
currentSelectedDay,
setCurrentSelectedDay,
firstDay,
lastDay,
days,
playerState,
onPlayerStateToggle
} = props;
const [datePickerPosition, setDatePickerPosition] = useState('left');
const [showDatePicker, setShowDatePicker] = useState(false);
const [currentSliderRange, setCurrentSliderRange] = useState([]);
const currentRange = mobileRange;
const dateRef = useRef();
const range = useRef();
const container = useRef();
const toSliderString = (date, currentLanguage) => {
let isoLanguage = 'enUS';
if (currentLanguage) {
isoLanguage = currentLanguage.replace('-', '');
if (isoLanguage === 'ar') {
isoLanguage = 'arSA';
} else if (isoLanguage === 'zhHK') {
isoLanguage = 'zhTW';
}
}
if (
languages[isoLanguage] === undefined ||
languages[isoLanguage] === null
) {
isoLanguage = currentLanguage.split('-')[0];
if (
languages[isoLanguage] === undefined ||
languages[isoLanguage] === null
) {
isoLanguage = 'enUS';
}
}
return format(date, 'yyyy-MM-dd', {
locale: languages ? languages[isoLanguage] : enUS,
});
};
useEffect(() => {
setCurrentSliderRange(days);
}, [days]);
const onSliderChange = (e) => {
const sliderDOM = dateRef.current;
const rangeDOM = range.current;
const containerDOM = container.current;
const newValue = e.target.value;
const basicWidth = containerDOM.offsetWidth - rangeDOM.offsetWidth;
const finalWidth = basicWidth / 2 - sliderDOM.offsetWidth / 4;
const stepsWidth = rangeDOM.offsetWidth / currentRange;
sliderDOM.style.left = `${finalWidth + stepsWidth * newValue}px`;
setCurrentDateValue(newValue);
const currentRangeDate = new Date(currentSliderRange[0][parseInt(newValue)]);
setCurrentSelectedDay(
toSliderString(
currentRangeDate,
props.i18n.locale,
),
);
submitChanges();
};
const onBtnClick = (newRange) => {
setShowDatePicker((prevState) => !prevState);
setDatePickerPosition(newRange);
};
const onChooseDate = (date) => {
props.setCurrentSelectedDay(date);
props.onChange(date);
props.setFirstDay(addDays(new Date(), -300));
const sliderDOM = dateRef.current;
const rangeDOM = range.current;
const containerDOM = container.current;
const basicWidth = containerDOM.offsetWidth - rangeDOM.offsetWidth;
const finalWidth = basicWidth / 2 - sliderDOM.offsetWidth / 4;
const stepsWidth = rangeDOM.offsetWidth / currentRange;
sliderDOM.style.left = `${
finalWidth +
stepsWidth *
((datePickerPosition === 'left' ? 0 : currentRange - 1) + 0.5)
}px`;
calendarWillClose();
if (datePickerPosition === 'left') {
let plusDays = 1;
days.push(date);
for (let i = 2; i <= currentRange; i++) {
days.push(rangePreProcces(date, plusDays));
plusDays++;
}
} else {
let lessDays = currentRange - 1;
for (let i = 1; i < currentRange; i++) {
days.push(rangePreProcces(date, -1 * lessDays));
lessDays--;
}
days.push(date);
}
setCurrentSliderRange(days);
setCurrentSelectedDay(toSliderString(date, props.i18n.locale));
submitChanges();
setCurrentDateValue(datePickerPosition === 'left' ? 0 : currentRange - 1);
submitChanges();
};
const calendarWillClose = () => {
setDatePickerPosition(`${datePickerPosition} hide`);
return () => setTimeout(() => closeDatePicker(), 400);
};
const closeDatePicker = () => {
setShowDatePicker(false);
setDatePickerPosition(datePickerPosition.replace(' hide', ''));
};
const rangePreProcces = (date, numDays) => {
const newDate = new Date(date);
newDate.setDate(date.getDate() + numDays);
return newDate;
};
const submitChanges = () => {
props.onChange(
currentSliderRange[0][parseInt(currentDateValue, 10)],
currentSliderRange[0],
currentSliderRange[currentSliderRange.length - 1],
);
};
return (
<div className={`sliderWrapper ${sliderWrapper} ${dark ? 'dark': ''}`}>
<PlayButton state={playerState} toggleState={onPlayerStateToggle} />
<div className={`${selectStyles} ${dark ? 'dark': ''} ${rangeStyles}`} ref={container}>
<DatePicker
startDate={new Date(firstDay)}
close={calendarWillClose}
onSelect={onChooseDate}
show={showDatePicker}
customClass={datePickerPosition}
/>
<div className={`${sliderSelector} ${dark ? 'dark': ''}`} ref={dateRef}>
<span>{currentSelectedDay?.toString()}</span>
</div>
<span
title="Select Start Date"
className={`first ${tooltipCss}`}
onClick={(e) => onBtnClick('left')}
>
<IconBtn /> {toSliderString(new Date(currentSelectedDay? currentSelectedDay : null), 'en')}
</span>
<button
onClick={(e) => onBtnClick('left')}
className={`first ${popBtn}`}
/>
<input
ref={range}
onInput={onSliderChange}
type="range"
min="0"
max={currentRange - 1}
step="1"
value={currentDateValue}
/>
<span title="Select End Date" className={`last ${tooltipCss}`}>
{toSliderString(new Date(lastDay? lastDay : null), 'en')}
</span>
</div>
</div>
);
}
Example #24
Source File: App.js From ProjectLockdown with GNU General Public License v3.0 | 4 votes |
App = (props) => {
const [environment, setEnvironment] = useState({});
const [loading, setIsLoading] = useState(false);
const [isDark, setIsDark] = useState('true');
const [playerState, setPlayerState] = useState(PAUSED);
const [days, setDays] = useState([]);
const [selectedDate, setSelectedDate] = useState(toJsonString(addDays(new Date(), startingPoint)));
const [startDate, setStartDate] = useState(addDays(new Date(), startingPoint));
const [endDate, setEndDate] = useState(addDays(new Date(), startingPoint + daysRange));
const [dialog, setDialog] = useState({
opened: false,
template: '',
title: '',
iso2: '',
country: '',
});
const [isLegendVisible, setIsLegendVisible] = useState(false);
const [isTimeSliderVisible, setIsTimeSliderVisible] = useState(false);
const [isCountrySearchVisible, setIsCountrySearchVisible] = useState(false);
const [isStatsBarVisible, setIsStatsBarVisible] = useState(false);
const [isTabMenuVisible, setIsTabMenuVisible] = useState(false);
const [isZoomVisible, setIsZoomVisible] = useState(false);
const [mapCord , setMapCord] = useState({
lng: coords.lng,
lat: coords.lat,
zoom: coords.zoom,
})
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
const getEnvData = useCallback( async () =>{
const data = await fetchEnvironments();
if(data && data.environment) {
const envt = data.environment;
const {components} = envt;
setEnvironment(envt)
setIsLegendVisible(_find(components,UIComponent.Legend).is_visible || false);
setIsTimeSliderVisible(_find(components, UIComponent.TimeSlider).is_visible || false);
setIsCountrySearchVisible(_find(components, UIComponent.CountriesSearcher).is_visible || false);
setIsStatsBarVisible(_find(components,UIComponent.StatsBar).is_visible || false);
setIsTabMenuVisible(_find(components,UIComponent.TabMenu).is_visible || false);
setIsZoomVisible(_find(components,UIComponent.Zoom).is_visible || false);
}
}, []);
const setNewDays = useCallback(
() => {
let date = startDate;
const newDays = [...days];
for (let i = 0; i <= daysRange; i++) {
newDays.push(format(date, 'yyyy-MM-dd'));
date = addDays(date, 1);
}
setDays((oldDays) => [...oldDays, newDays]);
},
[days,startDate],
)
const pausePlayerState = useCallback(
() => {
const formattedSelectedDate = new Date(selectedDate);
if (
formattedSelectedDate.getDate() === endDate.getDate() &&
formattedSelectedDate.getMonth() === endDate.getMonth() &&
formattedSelectedDate.getFullYear() === endDate.getFullYear()
) {
setPlayerState(PAUSED);
setSelectedDate(format(startDate, 'yyyy-MM-dd'))
}
},
[endDate,selectedDate,startDate],
)
const toggleState = useCallback(
(newState) => {
setPlayerState(newState)
},
[],
)
const updatePlayerState = useCallback(
() => {
const formattedSelectedDate = new Date(selectedDate);
let loop = null;
if (playerState === PLAYING) {
loop = setInterval(() => {
if (playerState === PAUSED || formattedSelectedDate === endDate) {
console.log('Stopped');
clearInterval(loop);
} else {
setSelectedDate(format(
addDays(formattedSelectedDate, 1),
'yyyy-MM-dd',
))
}
}, playSpeed);
}
return () => clearInterval(loop);
},
[selectedDate,endDate,playerState],
)
const updateIsDark = useCallback(
() => {
const darkModePreference = window.localStorage.getItem('darkmode');
if (!darkModePreference) {
const isDarkTheme = !window.matchMedia('(prefers-color-scheme: dark)').matches;
setIsDark(isDarkTheme.toString());
document.getElementsByTagName('html')[0].classList.add('dark');
window.localStorage.setItem('darkmode', isDarkTheme.toString());
}
if (darkModePreference === 'true') {
document.getElementsByTagName('html')[0].classList.add('dark');
setIsDark("true");
} else if (darkModePreference === 'false') {
setIsDark("false");
}
},
[],
)
const closeDialog = useCallback(
() => {
setDialog(prevState => ({
...prevState,
opened: false, template: '', title: ''
}));
},
[],
);
const openDialog = useCallback(
(countryIfo) => {
setDialog(prevState => ({
...prevState,
opened: true,
template: '',
title: '',
iso2: countryIfo.iso2,
country: countryIfo.country,
}
));
},
[],
);
useEffect(() =>{
getEnvData();
},[getEnvData]);
useEffect(() => {
updateIsDark();
},[updateIsDark]);
useEffect(() => {
setNewDays();
pausePlayerState();
router.resetLocalStorage();
updatePlayerState();
// eslint-disable-next-line react-hooks/exhaustive-deps
},[]);
const _find = (arr, param) => arr.find(value => value.name === param);
const updateEnv = async (queryString, value) =>{
const data = await fetchEnvironments();
if(data && data.environment){
const componentName = _.last(queryString.split("."));
const index = _.findIndex(data['environment']['components'] ,(component) => component.name=componentName);
_.update(data,`environment.components[${index}]`, (obj)=> {
obj.is_visible = toBool(value);
switch(componentName){
case UIComponent.Legend:
setIsLegendVisible(toBool(value));
break;
case UIComponent.TimeSlider:
setIsTimeSliderVisible(toBool(value));
break;
case UIComponent.CountriesSearcher:
setIsCountrySearchVisible(toBool(value));
break;
case UIComponent.StatsBar:
setIsStatsBarVisible(toBool(value));
break;
case UIComponent.TabMenu:
setIsTabMenuVisible(toBool(value));
break;
case UIComponent.Zoom:
setIsZoomVisible(toBool(value));
break;
default:
break
}
return obj
});
const envt = data.environment;
setEnvironment(envt);
}
}
const updateMapCord = (value) =>{
const cord = value.split("/");
if(cord.length === 3){
setMapCord((prevCord) => ({
...prevCord,
lng: cord[0],
lat: cord[1],
zoom: cord[2]
}));
}
}
const openOverlay = async (value) => {
const countryIso = await fetchCountryISO();
if(countryIso.length){
const selectedCountry =await _.find(countryIso, {"Iso": value});
if(selectedCountry){
setDialog(prevState => ({
...prevState,
opened: true,
template: '',
title: '',
iso2: value,
country: selectedCountry.name,
}
));
}
const [ minlon, minlat, maxlon, maxlat ] = selectedCountry.cord;
const avgLng = (maxlon + minlon)/2;
const avgLat = (maxlat + minlat) /2;
setMapCord((prevCord) => ({
...prevCord,
lng: avgLng,
lat: avgLat,
zoom: 4 // need to be parameterized
}));
}
}
useEffect(() =>{
const {search=""} = props.location;
const params = new URLSearchParams(search);
for (const [key, value] of params) {
if(key === "map"){
updateMapCord(value);
}
else if(key==="PLD"){
openOverlay(value);
}
updateEnv(key,value);
}
},[props.location])
const onSetSelectedDate =(date) => {
setSelectedDate(toJsonString(new Date(date)));
};
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<div
onKeyUp={(e) => {
if (e.key === ' ') {
const newState = playerState === PAUSED ? PLAYING : PAUSED;
toggleState(newState);
}
}}
>
<AppContext.Provider value={{environment, setEnvironment}} >
<ThemeContext.Provider value={{ isDark }}>
<LoadingAnimation isLoading={loading} />
<Map
selectedDate={selectedDate}
startDate={startDate}
endDate={endDate}
onOpen={openDialog}
setIsLoading={setIsLoading}
daysRange={daysRange}
isCountrySearchVisible={isCountrySearchVisible}
isZoomVisible={isZoomVisible}
mapCord={mapCord}
width={windowDimensions.width}
mobileWidth={fullTimeSliderWidth}
/>
{isTabMenuVisible && <TabMenu isDark={isDark}
setDarkMode={updateIsDark}
width={windowDimensions.width}
mobilewidth={fullTimeSliderWidth} />}
{isStatsBarVisible && <StatsBar width={windowDimensions.width} />}
{isLegendVisible && <Legend width={windowDimensions.width}
mobilewidth={fullTimeSliderWidth} />}
<Watermark fontsize={watermarkSize} />
{startDate && endDate && selectedDate && isTimeSliderVisible && (
<TimeSlider
playerState={playerState}
onPlayerStateToggle={toggleState}
dark={isDark}
days={days}
i18n={{ locale: 'en, en-US' }}
onChange={(CurrentSelectedDate) => {
setSelectedDate(CurrentSelectedDate);
}}
currentSelectedDay={selectedDate}
selectedDate={selectedDate}
sliderValue={getDaysDiff(startDate, endDate)}
setCurrentSelectedDay={onSetSelectedDate}
firstDay={format(new Date(startDate), 'yyyy-MM-dd')}
setFirstDay={setStartDate}
lastDay={format(new Date(endDate), 'yyyy-MM-dd')}
setLastDay={setEndDate}
/>
)}
{dialog.opened ? (
<CountryInfo
country={dialog.country}
iso2={dialog.iso2}
wikidata=""
date={selectedDate || new Date()}
startDate={startDate}
endDate={endDate}
daysRange={daysRange}
onClose={closeDialog}
onOpen={openDialog}
/>
) : (
''
)}
</ThemeContext.Provider>
</AppContext.Provider>
</div>
);
}
Example #25
Source File: fake-diary-data.js From monsuivipsy with Apache License 2.0 | 4 votes |
fakeDiaryData = {
[formatDay(startDate)]: null,
[formatDay(addDays(startDate, 1))]: null,
[formatDay(addDays(startDate, 2))]: null,
[formatDay(addDays(startDate, 3))]: {
MOOD: categoryStates.BAD,
ANXIETY_FREQUENCE: frequence.SEVERAL_TIMES,
ANXIETY_INTENSITY: categoryStates.MIDDLE,
BADTHOUGHTS_FREQUENCE: frequence.MANY_TIMES,
BADTHOUGHTS_INTENSITY: categoryStates.VERY_GOOD,
SENSATIONS_FREQUENCE: frequence.NEVER,
SENSATIONS_INTENSITY: categoryStates.VERY_BAD,
SLEEP: categoryStates.VERY_GOOD,
NOTES: "Test note",
POSOLOGY: [
{
id: "Imovane (Zopiclone)",
name1: "Imovane",
name2: "Zopiclone",
values: ["3.75 mg", "7.5 mg"],
value: "3.75 mg",
},
{
id: "Lamictal (Lamotrigine)",
name1: "Lamictal",
name2: "Lamotrigine",
value: "25 mg",
values: [
"12.5 mg",
"25 mg",
"37.5 mg",
"50 mg",
"62.5mg",
"75mg",
"87.5mg",
"100mg",
"112.5 mg",
"125 mg",
"137.5 mg",
"150 mg",
"162.5 mg",
"175 mg",
"200 mg",
"212.5 mg",
"225 mg",
"237.5 mg",
"250 mg",
"262.5 mg",
"275 mg",
"300 mg",
"312.5 mg",
"325 mg",
"350 mg",
"362.5 mg",
"375 mg",
"400 mg",
],
},
{
id: "Mélatonine",
name1: "Mélatonine",
value: "10 mg",
values: ["10 mg", "25 mg", "50 mg"],
},
],
},
[formatDay(addDays(startDate, 4))]: {
MOOD: categoryStates.GOOD,
ANXIETY_FREQUENCE: frequence.NEVER,
ANXIETY_INTENSITY: categoryStates.GOOD,
BADTHOUGHTS_FREQUENCE: frequence.SEVERAL_TIMES,
BADTHOUGHTS_INTENSITY: categoryStates.MIDDLE,
SENSATIONS_FREQUENCE: frequence.MANY_TIMES,
SENSATIONS_INTENSITY: categoryStates.BAD,
SLEEP: categoryStates.VERY_BAD,
NOTES: null,
},
[formatDay(addDays(startDate, 5))]: {
MOOD: categoryStates.MIDDLE,
ANXIETY_FREQUENCE: frequence.MANY_TIMES,
ANXIETY_INTENSITY: categoryStates.VERY_BAD,
BADTHOUGHTS_FREQUENCE: frequence.MANY_TIMES,
BADTHOUGHTS_INTENSITY: categoryStates.VERY_GOOD,
SENSATIONS_FREQUENCE: frequence.MANY_TIMES,
SENSATIONS_INTENSITY: categoryStates.GOOD,
SLEEP: categoryStates.MIDDLE,
NOTES: "",
},
[formatDay(addDays(startDate, 6))]: {
MOOD: categoryStates.VERY_GOOD,
ANXIETY_FREQUENCE: frequence.MANY_TIMES,
ANXIETY_INTENSITY: categoryStates.VERY_BAD,
BADTHOUGHTS_FREQUENCE: frequence.MANY_TIMES,
BADTHOUGHTS_INTENSITY: categoryStates.VERY_GOOD,
SENSATIONS_FREQUENCE: frequence.MANY_TIMES,
SENSATIONS_INTENSITY: categoryStates.GOOD,
SLEEP: categoryStates.MIDDLE,
POSOLOGY: [
{
id: "Imovane (Zopiclone)",
name1: "Imovane",
name2: "Zopiclone",
values: ["3.75 mg", "7.5 mg"],
value: "7.5 mg",
},
{
id: "Lamictal (Lamotrigine)",
name1: "Lamictal",
name2: "Lamotrigine",
value: "50 mg",
values: [
"12.5 mg",
"25 mg",
"37.5 mg",
"50 mg",
"62.5mg",
"75mg",
"87.5mg",
"100mg",
"112.5 mg",
"125 mg",
"137.5 mg",
"150 mg",
"162.5 mg",
"175 mg",
"200 mg",
"212.5 mg",
"225 mg",
"237.5 mg",
"250 mg",
"262.5 mg",
"275 mg",
"300 mg",
"312.5 mg",
"325 mg",
"350 mg",
"362.5 mg",
"375 mg",
"400 mg",
],
},
{
id: "Mélatonine",
name1: "Mélatonine",
value: "10 mg",
values: ["10 mg", "25 mg", "50 mg"],
},
],
NOTES:
"This is a very long note. This is a very long note. This is a very long note. This is a very long note. This is a very long note. This is a very long note. This is a very long note. ",
},
[formatDay(addDays(startDate, 7))]: {
MOOD: categoryStates.BAD,
ANXIETY_FREQUENCE: frequence.MANY_TIMES,
ANXIETY_INTENSITY: categoryStates.VERY_BAD,
BADTHOUGHTS_FREQUENCE: frequence.MANY_TIMES,
BADTHOUGHTS_INTENSITY: categoryStates.VERY_GOOD,
SENSATIONS_FREQUENCE: frequence.MANY_TIMES,
SENSATIONS_INTENSITY: categoryStates.GOOD,
SLEEP: categoryStates.MIDDLE,
NOTES: "",
},
[formatDay(addDays(startDate, 8))]: {
MOOD: categoryStates.GOOD,
ANXIETY_FREQUENCE: frequence.MANY_TIMES,
ANXIETY_INTENSITY: categoryStates.VERY_BAD,
BADTHOUGHTS_FREQUENCE: frequence.MANY_TIMES,
BADTHOUGHTS_INTENSITY: categoryStates.VERY_GOOD,
SENSATIONS_FREQUENCE: frequence.MANY_TIMES,
SENSATIONS_INTENSITY: categoryStates.GOOD,
SLEEP: categoryStates.MIDDLE,
NOTES: {},
},
[formatDay(addDays(startDate, 9))]: {
MOOD: categoryStates.GOOD,
ANXIETY_FREQUENCE: frequence.MANY_TIMES,
ANXIETY_INTENSITY: categoryStates.VERY_BAD,
BADTHOUGHTS_FREQUENCE: frequence.MANY_TIMES,
BADTHOUGHTS_INTENSITY: categoryStates.VERY_GOOD,
SENSATIONS_FREQUENCE: frequence.MANY_TIMES,
SENSATIONS_INTENSITY: categoryStates.GOOD,
SLEEP: categoryStates.MIDDLE,
POSOLOGY: [
{
id: "Lamictal (Lamotrigine)",
name1: "Lamictal",
name2: "Lamotrigine",
value: "300 mg",
values: [
"12.5 mg",
"25 mg",
"37.5 mg",
"50 mg",
"62.5mg",
"75mg",
"87.5mg",
"100mg",
"112.5 mg",
"125 mg",
"137.5 mg",
"150 mg",
"162.5 mg",
"175 mg",
"200 mg",
"212.5 mg",
"225 mg",
"237.5 mg",
"250 mg",
"262.5 mg",
"275 mg",
"300 mg",
"312.5 mg",
"325 mg",
"350 mg",
"362.5 mg",
"375 mg",
"400 mg",
],
},
],
},
[formatDay(addDays(startDate, 10))]: {
MOOD: categoryStates.VERY_GOOD,
ANXIETY_FREQUENCE: frequence.SEVERAL_TIMES,
ANXIETY_INTENSITY: categoryStates.GOOD,
BADTHOUGHTS_FREQUENCE: frequence.MANY_TIMES,
BADTHOUGHTS_INTENSITY: categoryStates.VERY_GOOD,
SENSATIONS_FREQUENCE: frequence.MANY_TIMES,
SENSATIONS_INTENSITY: categoryStates.GOOD,
SLEEP: categoryStates.MIDDLE,
NOTES: { notesEvents: "ceci est une note d'event" },
},
}