-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fetching data from Space-Track, fixing some bugs, adding cron tasks f…
…or updating database with tool functions
- Loading branch information
Florian Graule
committed
Jul 9, 2024
1 parent
1e497fd
commit 44a7505
Showing
14 changed files
with
350 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // backend/config/functions/cronTask.js | ||
| /* | ||
| * Function to fetch data from Space-Track such as Eccentricy, SMA, Inclination every month | ||
| * and update the database with the new data | ||
| */ | ||
| 'use strict'; | ||
|
|
||
| module.exports = { | ||
| updateAllSatellitesData: { | ||
| task: async ({ strapi }) => { | ||
| try { | ||
| // Fetching all satellites | ||
| const satellites = await strapi.entityService.findMany('api::satellite.satellite'); | ||
|
|
||
| // Waiting for all promises to be resolved | ||
| await Promise.all( | ||
| satellites.map(async satellite => { | ||
| await strapi.service('api::satellite.satellite').fetchOrbitalData(satellite.id); | ||
| }) | ||
| ); | ||
| } catch (error) { | ||
| console.error(error); | ||
| } | ||
| }, | ||
| options: new Date(Date.now() + 10000), | ||
| }, | ||
| }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,6 +51,9 @@ | |
| }, | ||
| "massKg": { | ||
| "type": "float" | ||
| }, | ||
| "historicalOrbitalData": { | ||
| "type": "json" | ||
| } | ||
| } | ||
| } | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
frontend/src/app/satellites/[satelliteSlug]/_orbitDataGraphComponents/ScrollBarThumb.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| "use client"; | ||
|
|
||
| import React, { useState, useEffect, useRef } from 'react'; | ||
|
|
||
| interface ScrollBarThumbProps { | ||
| scrollBarThumbWidth: number; | ||
| svgContainerRect: {topLeft: number, width: number, height: number}; | ||
| } | ||
|
|
||
| const ScrollBarThumb : React.FC<ScrollBarThumbProps> = ({ scrollBarThumbWidth, svgContainerRect}) => { | ||
| const isDragging = useRef<boolean>(false); | ||
| {/* SB is used for ScrollBar */} | ||
| const [sBThumbX, setSBThumbX] = useState(0); | ||
| const thumbRef = useRef<SVGRectElement>(null); | ||
| // Distance between the left of the thumb and the mouse click | ||
| const distThumbClick = useRef<number | null>(null); | ||
|
|
||
| /* Be careful useEffect runs before parent props are received */ | ||
| useEffect(() => { | ||
| const handleMouseUp = (e: any) => { | ||
| if (thumbRef.current) { | ||
| isDragging.current = false; | ||
| } | ||
| } | ||
|
|
||
| const handleMouseMove = (e: MouseEvent) => { | ||
| if (isDragging.current && thumbRef.current) { | ||
| // Scrollbar starts at the right of the svg container and goes to the left by increasing SBThumbX | ||
| setSBThumbX(() => { | ||
| // Calculating min and max x positions following the SBThumbX axis for moving the thumb with mouse movement | ||
| const minX= 0.5; | ||
| const maxX = svgContainerRect.width - scrollBarThumbWidth; | ||
| // newPos represents left border of the thumb | ||
| const newPos = svgContainerRect.topLeft + svgContainerRect.width - scrollBarThumbWidth - (e.clientX - (distThumbClick.current? distThumbClick.current : 0)); | ||
|
|
||
| // If mouse movement isn't in the scrollable area | ||
| if (newPos <= minX) { | ||
| return minX; | ||
| } else if (newPos >= maxX) { | ||
| return maxX; | ||
| } | ||
| return newPos; | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| window.addEventListener('mouseup', handleMouseUp); | ||
| window.addEventListener('mousemove', handleMouseMove); | ||
|
|
||
| // Managing the resize of the thumb | ||
| if (thumbRef.current && thumbRef.current.getBoundingClientRect().x < svgContainerRect.topLeft) { | ||
| setSBThumbX(svgContainerRect.width - scrollBarThumbWidth); | ||
| } | ||
|
|
||
| return () => { | ||
| window.removeEventListener('mouseup', handleMouseUp); | ||
| window.removeEventListener('mousemove', handleMouseMove); | ||
| } | ||
| }, [scrollBarThumbWidth, svgContainerRect]); | ||
|
|
||
| const handleMouseDown = (e: React.MouseEvent<SVGRectElement, MouseEvent>) => { | ||
| // If the thumb is clicked with left mouse button, we start dragging | ||
| if (thumbRef.current && e.button === 0) { | ||
| isDragging.current = true; | ||
| distThumbClick.current = e.clientX - thumbRef.current.getBoundingClientRect().left; | ||
| } | ||
| } | ||
|
|
||
| return ( | ||
| <> | ||
| <g className="scrollbar-thumb" transform={`translate(${20 + svgContainerRect.width - scrollBarThumbWidth - sBThumbX}, 0)`}> | ||
| <rect x="0.5" y="-50.5" width={scrollBarThumbWidth} height="50" fill="#cccccc" opacity="0.1"/> | ||
| <rect ref={thumbRef} x="0.5" y="0.5" width={scrollBarThumbWidth} height={(svgContainerRect.height-1)} fill="#cccccc" style={{cursor: 'pointer'}} onMouseDown={handleMouseDown}/> | ||
| <path d={`M ${scrollBarThumbWidth/2} ${(svgContainerRect.height-1)*0.25} L ${scrollBarThumbWidth/2} ${(svgContainerRect.height-1)*0.75} | ||
| M ${scrollBarThumbWidth*0.5 - svgContainerRect.width*0.005} ${(svgContainerRect.height-1)*0.25} L ${scrollBarThumbWidth*0.5 - svgContainerRect.width*0.005} ${(svgContainerRect.height-1)*0.75} | ||
| M ${scrollBarThumbWidth*0.5 + svgContainerRect.width*0.005} ${(svgContainerRect.height-1)*0.25} L ${scrollBarThumbWidth*0.5 + svgContainerRect.width*0.005} ${(svgContainerRect.height-1)*0.75}`} | ||
| fill="none" stroke="#333333" style={{cursor: 'pointer'}} onMouseDown={handleMouseDown}/> | ||
| </g> | ||
| </> | ||
| ); | ||
| } | ||
|
|
||
| export default ScrollBarThumb; |
2 changes: 1 addition & 1 deletion
2
frontend/src/app/satellites/[satelliteSlug]/launchDateCountDown.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
frontend/src/app/satellites/[satelliteSlug]/orbitDataGraph.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| "use client"; | ||
|
|
||
| import React, { useState, useLayoutEffect, useRef, SyntheticEvent } from 'react' | ||
| import { SatelliteNumber } from '@/lib/store' | ||
| import { Line } from 'react-chartjs-2' | ||
| import Chart from 'chart.js' | ||
| import { LaunchDateCountDownProps } from './launchDateCountDown'; | ||
| import ScrollBarThumb from './_orbitDataGraphComponents/ScrollBarThumb'; | ||
|
|
||
| type OrbitDataProps = { | ||
| satNum : SatelliteNumber; | ||
| launchDateString: LaunchDateCountDownProps['launchDate']; | ||
| orbitalData: any; | ||
| } | ||
|
|
||
| const OrbitDataGraph : React.FC<OrbitDataProps> = ({ satNum, launchDateString, orbitalData }) => { | ||
|
|
||
| // href for the svg component, tracking the size of the container | ||
| const svgContainer = useRef<HTMLDivElement>(null); | ||
| const [svgSize, setSvgSize] = useState({width: 0, height: 0}); | ||
| {/* SB use for ScrollBar*/} | ||
| const [scrollBarThumbWidth, setSBThumbWidth] = useState(0); | ||
|
|
||
| // Handling button for zooming in and out of the graph on a time scale | ||
| const launchDate = launchDateString? new Date(launchDateString) : new Date(); | ||
| const calculateMonthsDiff = () => { | ||
| const currentDate = new Date(); | ||
| return currentDate.getMonth() - launchDate.getMonth() + (12 * (currentDate.getFullYear() - launchDate.getFullYear())); | ||
| } | ||
|
|
||
| const months = calculateMonthsDiff(); | ||
|
|
||
| const handleZoomClick = (e: React.MouseEvent<HTMLButtonElement>) => { | ||
| // We round the width of the scrollbar thumb at one decimal | ||
| const period = e.currentTarget.textContent; | ||
| const regExp = new RegExp('^([1234567890]+)([my])$'); | ||
| const match = period?.match(regExp); | ||
| let SBThumbWidth = 0; | ||
|
|
||
| if (period === "All") { | ||
| SBThumbWidth = svgSize.width*0.8-40.5; | ||
| setSBThumbWidth(SBThumbWidth); | ||
| } else { | ||
| const number = match ? parseInt(match[1]) : 0; | ||
| const periodType = match? match[2] : ""; | ||
|
|
||
| if (periodType === "m") { | ||
| SBThumbWidth = Math.round((svgSize.width*0.8 * number *10) / months) / 10; | ||
| setSBThumbWidth(SBThumbWidth); | ||
| } else if (periodType === "y") { | ||
| SBThumbWidth = Math.round((svgSize.width*0.8 * number * 12 *10) / months) / 10 | ||
| setSBThumbWidth(SBThumbWidth); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Layout effect to track the size of the container and update the svg size | ||
| useLayoutEffect(() => { | ||
| const updateSize = () => { | ||
| if (svgContainer.current) { | ||
| const width = svgContainer.current.offsetWidth; | ||
| const height = width / 2; | ||
| setSvgSize({width, height}); | ||
| setSBThumbWidth( width*0.1 ); | ||
| } | ||
| } | ||
| window.addEventListener('resize', updateSize); | ||
| updateSize(); | ||
|
|
||
| return () => window.removeEventListener('resize', updateSize); | ||
| }, []); | ||
|
|
||
| return ( | ||
| <> | ||
| <h1> | ||
| Graph goes here. | ||
| </h1> | ||
| <div ref={svgContainer} className="w-full flex flex-col"> | ||
| <div className="zoom-container flex"> | ||
| <h2 className="mx-5 text-white">Zoom : </h2> | ||
| {/* Scrollbar thumb represents the zoom period selected, in case it fits bad we don't display | ||
| ie. containerSize > SBThumbWidth > 20px */} | ||
| { (Math.round((svgSize.width*0.8 * 1 * 10) / months) / 10 < svgSize.width) && (Math.round((svgSize.width*0.8 * 1 * 10) / months) / 10 > 20) && <button onClick={handleZoomClick} className="mx-2 bg-[#f2f2f2] text-black w-10 h-8 rounded-lg hover:bg-[#cccccc]">1m</button> } | ||
| { (Math.round((svgSize.width*0.8 * 3 * 10) / months) / 10 < svgSize.width) && (Math.round((svgSize.width*0.8 * 3 * 10) / months) / 10 > 40) && <button onClick={handleZoomClick} className="mx-2 bg-[#f2f2f2] text-black w-10 h-8 rounded-lg hover:bg-[#cccccc]">3m</button> } | ||
| { (Math.round((svgSize.width*0.8 * 6 * 10) / months) / 10 < svgSize.width) && (Math.round((svgSize.width*0.8 * 6 * 10) / months) / 10 > 40) && <button onClick={handleZoomClick} className="mx-2 bg-[#f2f2f2] text-black w-10 h-8 rounded-lg hover:bg-[#cccccc]">6m</button> } | ||
| { (Math.round((svgSize.width*0.8 * 12 * 10) / months) / 10 < svgSize.width) && (Math.round((svgSize.width*0.8 * 12 * 10) / months) / 10 > 40) && <button onClick={handleZoomClick} className="mx-2 bg-[#f2f2f2] text-black w-10 h-8 rounded-lg hover:bg-[#cccccc]">1y</button> } | ||
| { (Math.round((svgSize.width*0.8 * 12 * 5 * 10) / months) / 10 < svgSize.width) && (Math.round((svgSize.width*0.8 * 12 * 5 * 10) / months) / 10 > 40) && <button onClick={handleZoomClick} className="mx-2 bg-[#f2f2f2] text-black w-10 h-8 rounded-lg hover:bg-[#cccccc]">5y</button> } | ||
| { (Math.round((svgSize.width*0.8 * 12 * 10 * 10) / months) / 10 < svgSize.width) && (Math.round((svgSize.width*0.8 * 12 * 10 * 10) / months) / 10 > 40) && <button onClick={handleZoomClick} className="mx-2 bg-[#f2f2f2] text-black w-10 h-8 rounded-lg hover:bg-[#cccccc]">10y</button> } | ||
| { (Math.round((svgSize.width*0.8 * 12 * 20 * 10) / months) / 10 < svgSize.width) && (Math.round((svgSize.width*0.8 * 12 * 20 * 10) / months) / 10 > 40) && <button onClick={handleZoomClick} className="mx-2 bg-[#f2f2f2] text-black w-10 h-8 rounded-lg hover:bg-[#cccccc]">20y</button> } | ||
|
|
||
| <button onClick={handleZoomClick} className="mx-2 bg-[#f2f2f2] text-black w-10 h-8 rounded-lg hover:bg-[#cccccc]">All</button> | ||
| </div> | ||
| <div className="w-full flex justify-center items-center"> | ||
| <svg className="relative" width="100%" height="600"> | ||
| {/* Scrollbar for time navigation */} | ||
| <g transform={`translate(${svgSize.width*0.1}, ${svgSize.height-75})`} fill="#f2f2f2"> | ||
| <g> | ||
| <rect y="-50" width="80%" height="1"/> | ||
| </g> | ||
| <rect width="80%" height="20"/> | ||
| {/* Scrollbar left navigation arrow */} | ||
| <g> | ||
| <rect x="0.5" y="0.5" width="19" height="19" fill="#e6e6e6" stroke="#cccccc" strokeWidth="1"/> | ||
| <path d="M 13 5 L 6 10 L 13 15" fill="#333333"/> | ||
| </g> | ||
| {/* Scrollbar right navigation arrow */} | ||
| <g transform={`translate(${svgSize.width*0.8 - 20}, 0)`}> | ||
| <rect x="0.5" y="0.5" width="19" height="19" fill="#e6e6e6" stroke="#cccccc" strokeWidth="1"/> | ||
| <path d="M 7 5 L 14 10 L 7 15" fill="#333333"/> | ||
| </g> | ||
| {/* Scrollbar thumb */} | ||
| <ScrollBarThumb scrollBarThumbWidth={scrollBarThumbWidth} svgContainerRect={{topLeft: (svgContainer.current?.getBoundingClientRect()?(svgContainer.current?.getBoundingClientRect().x) : 0) + svgSize.width*0.1 + 20.5 , width: (svgSize.width*0.8-40.5), height: 20}}/> | ||
| </g> | ||
| </svg> | ||
| </div> | ||
| </div> | ||
| </> | ||
| ) | ||
| } | ||
|
|
||
| export default OrbitDataGraph; |
Oops, something went wrong.