Allow shifting by time range
This commit is contained in:
parent
e549afce96
commit
e5dbb0af39
|
@ -22,6 +22,22 @@ const durations = [
|
||||||
{id: 3, len: 'Year', win: '2h', full: '2 hour', delta: [1, 'years'], format: 'M/D', num: 4380, secs: 7200},
|
{id: 3, len: 'Year', win: '2h', full: '2 hour', delta: [1, 'years'], format: 'M/D', num: 4380, secs: 7200},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const parseSlider = (end, duration, slider) => {
|
||||||
|
//console.log(slider);
|
||||||
|
// good luck remembering how this works
|
||||||
|
const lowOffset = slider[0] * duration.secs - duration.num * duration.secs;
|
||||||
|
const highOffset = slider[1] * duration.secs - duration.num * duration.secs;
|
||||||
|
|
||||||
|
const low = moment.unix(end.unix() + lowOffset);
|
||||||
|
const high = moment.unix(end.unix() + highOffset);
|
||||||
|
|
||||||
|
const lowStr = low.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
|
||||||
|
const highStr = high.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
|
||||||
|
|
||||||
|
//console.log(lowStr, highStr);
|
||||||
|
return [lowStr, highStr];
|
||||||
|
};
|
||||||
|
|
||||||
function useSensor(measurement, name, end, duration) {
|
function useSensor(measurement, name, end, duration) {
|
||||||
const [data, setData] = useState(false);
|
const [data, setData] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
@ -51,9 +67,11 @@ function useSensor(measurement, name, end, duration) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function Owntracks({end, duration, range}) {
|
function Owntracks({end, duration, slider}) {
|
||||||
const [data, loading] = useSensor('owntracks', 'OwnTracks', end, duration);
|
const [data, loading] = useSensor('owntracks', 'OwnTracks', end, duration);
|
||||||
|
|
||||||
|
const range = parseSlider(end, duration, slider);
|
||||||
|
|
||||||
const coords = data.length ? data.filter(x => !range || (x.time >= range[0] && x.time <= range[1])).map(({ lat, lon }) => [lat, lon]).filter(([lat, lon]) => lat !== null || lon !== null) : [];
|
const coords = data.length ? data.filter(x => !range || (x.time >= range[0] && x.time <= range[1])).map(({ lat, lon }) => [lat, lon]).filter(([lat, lon]) => lat !== null || lon !== null) : [];
|
||||||
|
|
||||||
const handleSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
|
@ -90,73 +108,89 @@ function Owntracks({end, duration, range}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function Graphs({end, duration, range}) {
|
function Graphs({end, duration, slider}) {
|
||||||
return (
|
return (
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<Owntracks end={end} duration={duration} range={range} />
|
<Owntracks end={end} duration={duration} slider={slider} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Menu({duration, setDuration, end, setEnd, range, setRange}) {
|
function Menu({duration, setDuration, end, setEnd, slider, setSlider}) {
|
||||||
const [submenu, setSubmenu] = useState(false);
|
const [submenu, setSubmenu] = useState(false);
|
||||||
const [showRange, setShowRange] = useState(false);
|
const [showRange, setShowRange] = useState(false);
|
||||||
|
|
||||||
const chooseDuration = (x) => {
|
const chooseDuration = (x) => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setRange(false);
|
setSlider([0, x.num]);
|
||||||
setDuration(x);
|
setDuration(x);
|
||||||
};
|
};
|
||||||
|
|
||||||
const chooseEnd = (x) => {
|
const chooseEnd = (x) => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
const newEnd = x.add(...duration.delta);
|
const newEnd = x.add(...duration.delta);
|
||||||
setRange(false);
|
setSlider([0, duration.num]);
|
||||||
setEnd(newEnd);
|
setEnd(newEnd);
|
||||||
};
|
};
|
||||||
|
|
||||||
const chooseNow = (x) => {
|
const chooseNow = (x) => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setRange(false);
|
setSlider([0, duration.num]);
|
||||||
setEnd(moment());
|
setEnd(moment());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const rangeStart = (x) => {
|
||||||
|
setEnd(moment(range[0]).add(...duration.delta));
|
||||||
|
setSlider([0, duration.num]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const rangeEnd = (x) => {
|
||||||
|
setEnd(moment(range[1]));
|
||||||
|
setSlider([0, duration.num]);
|
||||||
|
};
|
||||||
|
|
||||||
const next = () => {
|
const next = () => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setRange(false);
|
setSlider([0, duration.num]);
|
||||||
setEnd(prevEnd => moment(prevEnd).add(...duration.delta));
|
setEnd(prevEnd => moment(prevEnd).add(...duration.delta));
|
||||||
}
|
}
|
||||||
|
|
||||||
const prev = () => {
|
const prev = () => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setRange(false);
|
setSlider([0, duration.num]);
|
||||||
setEnd(prevEnd => moment(prevEnd).subtract(...duration.delta));
|
setEnd(prevEnd => moment(prevEnd).subtract(...duration.delta));
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSlider = (slider) => {
|
const range = parseSlider(end, duration, slider);
|
||||||
console.log(slider);
|
|
||||||
// good luck remembering how this works
|
|
||||||
const lowOffset = slider[0] * duration.secs - duration.num * duration.secs;
|
|
||||||
const highOffset = slider[1] * duration.secs - duration.num * duration.secs;
|
|
||||||
|
|
||||||
const low = moment.unix(end.unix() + lowOffset);
|
|
||||||
const high = moment.unix(end.unix() + highOffset);
|
|
||||||
|
|
||||||
const lowStr = low.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
|
|
||||||
const highStr = high.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
|
|
||||||
|
|
||||||
console.log(lowStr, highStr);
|
|
||||||
setRange([lowStr, highStr]);
|
|
||||||
|
|
||||||
|
const rangeTime = (x) => {
|
||||||
|
if (new Date().getTimezoneOffset()) { // non-librewolf browser
|
||||||
|
return moment(x).format('lll'); // default to browser's TZ
|
||||||
|
} else {
|
||||||
|
return moment(x).tz('America/Edmonton').format('lll');
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='menu'>
|
<div className='menu'>
|
||||||
{showRange && <div className='range'>
|
{(showRange || !!submenu) && <div className='range'>
|
||||||
{moment(range[0]).format('lll')} - {moment(range[1]).format('lll')}
|
{rangeTime(range[0])} - {rangeTime(range[1])}
|
||||||
</div>}
|
</div>}
|
||||||
|
|
||||||
{submenu ?
|
<div className='time-slider'>
|
||||||
|
<RangeSlider
|
||||||
|
min={0}
|
||||||
|
max={duration.num}
|
||||||
|
value={slider}
|
||||||
|
onInput={setSlider}
|
||||||
|
onThumbDragStart={() => setShowRange(true)}
|
||||||
|
onThumbDragEnd={() => setShowRange(false)}
|
||||||
|
onRangeDragStart={() => setShowRange(true)}
|
||||||
|
onRangeDragEnd={() => setShowRange(false)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!!submenu &&
|
||||||
<div className='submenu'>
|
<div className='submenu'>
|
||||||
{submenu === 'end' &&
|
{submenu === 'end' &&
|
||||||
<>
|
<>
|
||||||
|
@ -174,6 +208,8 @@ function Menu({duration, setDuration, end, setEnd, range, setRange}) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onClick={chooseNow}>Jump to Now</button>
|
<button onClick={chooseNow}>Jump to Now</button>
|
||||||
|
<button onClick={rangeStart}>Shift to Range Start</button>
|
||||||
|
<button onClick={rangeEnd}>Shift to Range End</button>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,20 +226,6 @@ function Menu({duration, setDuration, end, setEnd, range, setRange}) {
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
:
|
|
||||||
<div className='time-slider'>
|
|
||||||
<RangeSlider
|
|
||||||
min={0}
|
|
||||||
max={duration.num}
|
|
||||||
defaultValue={[0, duration.num]}
|
|
||||||
onInput={onSlider}
|
|
||||||
onThumbDragStart={() => setShowRange(true)}
|
|
||||||
onThumbDragEnd={() => setShowRange(false)}
|
|
||||||
onRangeDragStart={() => setShowRange(true)}
|
|
||||||
onRangeDragEnd={() => setShowRange(false)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<div className='menu-container'>
|
<div className='menu-container'>
|
||||||
|
@ -232,7 +254,7 @@ function Menu({duration, setDuration, end, setEnd, range, setRange}) {
|
||||||
function App() {
|
function App() {
|
||||||
const [duration, setDuration] = useState(durations[0]);
|
const [duration, setDuration] = useState(durations[0]);
|
||||||
const [end, setEnd] = useState(moment());
|
const [end, setEnd] = useState(moment());
|
||||||
const [range, setRange] = useState(false);
|
const [slider, setSlider] = useState([0, duration.num]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -241,14 +263,14 @@ function App() {
|
||||||
setDuration={setDuration}
|
setDuration={setDuration}
|
||||||
end={end}
|
end={end}
|
||||||
setEnd={setEnd}
|
setEnd={setEnd}
|
||||||
range={range}
|
slider={slider}
|
||||||
setRange={setRange}
|
setSlider={setSlider}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Graphs
|
<Graphs
|
||||||
end={end}
|
end={end}
|
||||||
duration={duration}
|
duration={duration}
|
||||||
range={range}
|
slider={slider}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user