From f00ac29dff86169e5dee9d816961cc13979f9a50 Mon Sep 17 00:00:00 2001 From: Michael Foiani Date: Fri, 16 Apr 2021 15:13:02 -0400 Subject: Working on adapting maps frontend. Finished the time selector to change the time interval. --- maps-frontend/src/css/App.css | 76 ++++++++++++++++++++++++++ maps-frontend/src/css/Canvas.css | 6 +++ maps-frontend/src/css/CoordSelector.css | 51 ++++++++++++++++++ maps-frontend/src/css/Route.css | 56 ++++++++++++++++++++ maps-frontend/src/css/UserCheckin.css | 94 +++++++++++++++++++++++++++++++++ 5 files changed, 283 insertions(+) create mode 100644 maps-frontend/src/css/App.css create mode 100644 maps-frontend/src/css/Canvas.css create mode 100644 maps-frontend/src/css/CoordSelector.css create mode 100644 maps-frontend/src/css/Route.css create mode 100644 maps-frontend/src/css/UserCheckin.css (limited to 'maps-frontend/src/css') diff --git a/maps-frontend/src/css/App.css b/maps-frontend/src/css/App.css new file mode 100644 index 0000000..90e9046 --- /dev/null +++ b/maps-frontend/src/css/App.css @@ -0,0 +1,76 @@ +.App { + display: grid; + grid-template-areas: "head canvasFill2 canvasFill3 checkin" + "canvasFill1 canvasFill2 canvasFill3 checkin" + "route canvasFill2 canvasFill3 checkin"; + grid-template-rows: max-content auto max-content; + grid-template-columns: max-content auto max-content max-content; + background-color: #121212; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + + +.Canvas-filler { + width: 100%; + height: 100%; + + z-index: 1; +} + +.Canvas-filler-1 { + grid-area: canvasFill1; +} +.Canvas-filler-2 { + grid-area: canvasFill2; +} +.Canvas-filler-3 { + grid-area: canvasFill3; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + grid-area: head; + min-height: 7vh; + width: max-content; + display: flex; + padding: 0 20px; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; + z-index: 10; + background-color: #333333; + border-radius: 5px; + margin: 5px; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.Loading { + z-index: 100; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} \ No newline at end of file diff --git a/maps-frontend/src/css/Canvas.css b/maps-frontend/src/css/Canvas.css new file mode 100644 index 0000000..1bc45b5 --- /dev/null +++ b/maps-frontend/src/css/Canvas.css @@ -0,0 +1,6 @@ +.Map-canvas { + touch-action: none; + + position: absolute; + z-index: 5; +} \ No newline at end of file diff --git a/maps-frontend/src/css/CoordSelector.css b/maps-frontend/src/css/CoordSelector.css new file mode 100644 index 0000000..696c888 --- /dev/null +++ b/maps-frontend/src/css/CoordSelector.css @@ -0,0 +1,51 @@ +/* CSS adapted from w3school buttons */ +.Btn-select-left > p, .Btn-select-right > p { + padding: 0; + margin: 0; +} + +.Btn-select-left { + background-color: #424242; + border: 4px solid pink; +} + +.Btn-select-left:hover { + box-shadow: 3px 3px #888888; + color: black; + background-color: pink; +} + +.Btn-select-right { + background-color: #424242; + border: 4px solid lightblue; +} + +.Btn-select-right:hover { + box-shadow: 3px 3px #888888; + color: black; + background-color: lightblue; +} + +.Btn:disabled, +.Btn[disabled]{ + border: 1px solid #999999; + background-color: #cccccc; + color: #666666; + box-shadow: none; + cursor: default; +} + +.Btn:disabled:hover, +.Btn[disabled]:hover{ + cursor: crosshair; +} + +.Textbox { + width: 100px; +} + +.Number-input { + width: 90%; +} + + diff --git a/maps-frontend/src/css/Route.css b/maps-frontend/src/css/Route.css new file mode 100644 index 0000000..eaa69c4 --- /dev/null +++ b/maps-frontend/src/css/Route.css @@ -0,0 +1,56 @@ +.Route { + grid-area: route; + z-index: 10; + color: white; + border-radius: 10px; + background-color: #121212; + cursor: default; + /* Transparent background */ + background: rgba(0, 0, 0, 0); +} + +.Coord-selectors-flex { + display: flex; + gap: 20px; + padding: 8px; + margin: 0; + align-content: flex-end; + background-color: #333333; + margin: 5px; + border-radius: 3px; +} + +/* CSS adapted from w3school buttons */ +.Btn { + color: white; + padding: 16px 32px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin: 4px 2px; + transition-duration: 0.4s; + cursor: pointer; + outline: none; +} + +.Route-btn:hover { + box-shadow: 3px 3px #ccc; + color: black; + background-color: lightgreen; +} + +.Route-btn { + background-color: #424242; + border: 2px solid lightgreen; + box-shadow: .5px .5px 0 2px lightgreen; +} + +.Btn:disabled, +.Btn[disabled]{ + border: 1px solid #999999; + background-color: #cccccc; + color: #666666; + cursor: default; + box-shadow: none; +} \ No newline at end of file diff --git a/maps-frontend/src/css/UserCheckin.css b/maps-frontend/src/css/UserCheckin.css new file mode 100644 index 0000000..3e16ffd --- /dev/null +++ b/maps-frontend/src/css/UserCheckin.css @@ -0,0 +1,94 @@ +.User-checkin { + grid-area: checkin; + height: 100vh; + background-color: #121212; + z-index: 10; + color: white; + border-radius: 10px; + display: flex; + font-size: 18px; + cursor: default; + /* Transparent background */ + background: rgba(0, 0, 0, 0); +} + +ul { + list-style-type: none; +} + +.User-checkin > div { + z-index: 10; + background-color: #333333; + border-radius: 20px; + margin: 5px; +} + +.Coord-ex { + height: 1vh; + margin: 0; + padding: 0; + text-align: center; +} + +.Chosen-user > h2, .Checkins > h2 { + display: flex; + justify-content: space-evenly; + height: 5vh; + padding: 0 10px; +} + +.Checkin-list { + padding: 0 20px; + height: 86vh; + overflow-y: scroll; + cursor: default; +} + +.User-checkin-list { + height: 80vh; + overflow-y: scroll; + + list-style-position: inside; + padding: 0 20px; + text-align: center; + text-indent: -12px; +} + +.User-checkin-list > li { + margin-bottom: 20px; +} + + +.Checkin { + padding-bottom: 20px; + border-bottom: 1px solid #e6ecf0; +} + +.Checkin:last-child { + border-bottom: none; +} + +.Img-flex { + margin: 5px 10px 10px 0; + gap: 20px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.Img-btn { + background-color: #424242; + border-radius: 50%; + margin-right: 10px; +} + +.Img-btn:hover { + box-shadow: 3px 3px #333333; + cursor: pointer; +} + +.Clickable-name { + cursor: pointer; + text-decoration: underline; + color: lightgreen; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 3182aec0fa9f1707435f92b0c0644c602125b0be Mon Sep 17 00:00:00 2001 From: Michael Foiani Date: Fri, 16 Apr 2021 16:32:02 -0400 Subject: Fixed bugs. Looking pretty good. --- frontend/public/index.html | 3 ++ maps-frontend/src/App.js | 44 ++++++++------------ maps-frontend/src/components/Canvas.js | 20 --------- maps-frontend/src/components/CoordSelector.js | 17 -------- maps-frontend/src/components/DateSelector.js | 17 ++++++++ maps-frontend/src/components/HubList.js | 5 ++- maps-frontend/src/components/TimeSelector.js | 24 ++++++----- maps-frontend/src/components/Visualization.js | 59 +++++++++++++++++++++++++++ maps-frontend/src/css/Canvas.css | 3 +- maps-frontend/src/css/CoordSelector.css | 3 +- maps-frontend/src/css/Route.css | 4 +- package-lock.json | 22 ++++++++++ package.json | 1 + 13 files changed, 141 insertions(+), 81 deletions(-) delete mode 100644 maps-frontend/src/components/Canvas.js delete mode 100644 maps-frontend/src/components/CoordSelector.js create mode 100644 maps-frontend/src/components/DateSelector.js create mode 100644 maps-frontend/src/components/Visualization.js (limited to 'maps-frontend/src/css') diff --git a/frontend/public/index.html b/frontend/public/index.html index b38af31..19c75dd 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -23,6 +23,9 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> + + + React App diff --git a/maps-frontend/src/App.js b/maps-frontend/src/App.js index 659b8f5..765455e 100644 --- a/maps-frontend/src/App.js +++ b/maps-frontend/src/App.js @@ -1,7 +1,7 @@ // React/component imports import React, {useEffect, useState} from 'react'; import TimeSelector from './components/TimeSelector.js'; -import Canvas from './components/Canvas.js'; +import Visualization from './components/Visualization.js'; import HubList from './components/HubList.js'; import Loading from './components/Loading.js'; @@ -24,13 +24,8 @@ function App() { }); // State for visualization data const [data, setData] = useState([]); - // States to control cursor. - const [cursor, setCursor] = useState('grab'); - // State for routing. - const [route, setRoute] = useState([]); const toEpochMilli = date => Date.parse(date); - const getGraphData = () => { fetch("http://localhost:4567/data", { method: "POST", @@ -45,42 +40,37 @@ function App() { }) .then(res => res.json()) .then(data => { - setData(data); + console.log(data); + setData(data.holders); setHasLoaded(true); }) .catch(err => console.log(err)); -} - /** - * Sets the coordinate for routing. - * @param {Object} coord The coordinate to replace. - */ - const setCoord = coord => { - setCursor('grab'); + setIsChanging(false); } - // Hooks to update data on init and switching of data useEffect(() => getGraphData(), []); useEffect(() => { setIsChanging(true); getGraphData(); - return () => setIsChanging(false); }, [dates]); return ( -
-
Welcome to WatchDogs!
-
-
-
- - - {(!hasLoaded) ? : - } -
+ <> + {(!hasLoaded) ? : +
+
Welcome to WatchDogs!
+
+
+
+ + + +
+ } + ); } diff --git a/maps-frontend/src/components/Canvas.js b/maps-frontend/src/components/Canvas.js deleted file mode 100644 index 9686f29..0000000 --- a/maps-frontend/src/components/Canvas.js +++ /dev/null @@ -1,20 +0,0 @@ -// JS module imports -import { useEffect, useRef, useState } from "react"; - -// CSS imports -import '../css/Canvas.css'; - -/** - * This function renders and mantains thhe canvas. - * @param {Object} props The props for the canvas. - * @returns {import("react").HtmlHTMLAttributes} The canvas to be retured. - */ -function Visualization(props) { - // instance variables - - - return -} - -export default Visualization; - diff --git a/maps-frontend/src/components/CoordSelector.js b/maps-frontend/src/components/CoordSelector.js deleted file mode 100644 index 5d5e5f5..0000000 --- a/maps-frontend/src/components/CoordSelector.js +++ /dev/null @@ -1,17 +0,0 @@ -// CSS import -import '../css/Route.css'; -import '../css/CoordSelector.css'; - -/** - * The component that selects and displays a coordinate. - * @param {Object} props The props for the element. - */ -function DateSelector(props) { - return ( -
- props.setStart(e.target.value)}/> -
- ); -} - -export default DateSelector; \ No newline at end of file diff --git a/maps-frontend/src/components/DateSelector.js b/maps-frontend/src/components/DateSelector.js new file mode 100644 index 0000000..5bb00fb --- /dev/null +++ b/maps-frontend/src/components/DateSelector.js @@ -0,0 +1,17 @@ +// CSS import +import '../css/Route.css'; +import '../css/CoordSelector.css'; + +/** + * The component that selects and displays a coordinate. + * @param {Object} props The props for the element. + */ +function DateSelector(props) { + return ( +
+ props.changedFunc(Date.parse(e.target.value))} onClick={() => props.clickedFunc()}/> +
+ ); +} + +export default DateSelector; \ No newline at end of file diff --git a/maps-frontend/src/components/HubList.js b/maps-frontend/src/components/HubList.js index 3bbcca6..41cf07a 100644 --- a/maps-frontend/src/components/HubList.js +++ b/maps-frontend/src/components/HubList.js @@ -19,6 +19,7 @@ function HubList(props) { const updateHubItems = () => { // sort and create the elemnts let hubs = []; + console.log(props.data); const sorted = props.data.sort((a, b) => b.suspicionScore - a.suspicionScore); console.log(sorted); sorted.forEach(hub => hubs.push( @@ -34,11 +35,11 @@ function HubList(props) { return (
-

Individual Suspicion

+

Suspicion Ranks

    {hubItems}
); } -export default HubList \ No newline at end of file +export default HubList; \ No newline at end of file diff --git a/maps-frontend/src/components/TimeSelector.js b/maps-frontend/src/components/TimeSelector.js index 2a26fd9..b396d81 100644 --- a/maps-frontend/src/components/TimeSelector.js +++ b/maps-frontend/src/components/TimeSelector.js @@ -1,5 +1,5 @@ // React/Component imports -import { useState } from "react"; +import { useEffect, useState } from "react"; import DateSelector from './DateSelector.js'; // CSS imports @@ -13,29 +13,33 @@ import '../css/Route.css'; function TimeSelector(props) { const [current, setCurrent] = useState(""); + const toValue = date => new Date(date).toISOString().slice(0, 10); + const [startDate, setStartDate] = useState(props.dates.start); const [endDate, setEndDate] = useState(props.dates.end); const changeTimeframe = () => { props.setDates({ - start: startDate, - end: endDate - }) + start: Date.parse(startDate), + end: Date.parse(endDate) + }); } + useEffect(() => setCurrent(""), [startDate, endDate]); + // The div with the html elements for routing. return (
- +

Adjust Timeframe :)

- +
- +
); diff --git a/maps-frontend/src/components/Visualization.js b/maps-frontend/src/components/Visualization.js new file mode 100644 index 0000000..3a9692d --- /dev/null +++ b/maps-frontend/src/components/Visualization.js @@ -0,0 +1,59 @@ +// JS module imports +import { useEffect, useRef, useState } from "react"; +import Graph from 'vis-react'; + +// CSS imports +import '../css/Canvas.css'; + +/** + * This function renders and mantains thhe canvas. + * @param {Object} props The props for the canvas. + * @returns {import("react").HtmlHTMLAttributes} The canvas to be retured. + */ +function Visualization(props) { + const [graphState, setGraphState] = useState({ + nodes: [], + edges: [] + }); + + const getNodes = () => { + console.log(props.data) + let nodes = [] + props.data.forEach(hub => { + nodes.push({ + id: hub.id, + label: hub.name, + size: hub.suspicionScore * 25 + }); + }); + return nodes; + } + + const getEdges = () => { + let edges = [] + props.data.forEach(hub => { + hub.followers.forEach(follower => { + edges.push({ + from: hub.id, + to: follower.id + }); + }); + }); + return edges; + } + + // Hooks to update graph state + useEffect(() => setGraphState({nodes: getNodes(), edges: getEdges()}), []); + useEffect(() => setGraphState({nodes: getNodes(), edges: getEdges()}), [props.data]); + + return ( +
+ + +
+ ); +} + +export default Visualization; + diff --git a/maps-frontend/src/css/Canvas.css b/maps-frontend/src/css/Canvas.css index 1bc45b5..8dee765 100644 --- a/maps-frontend/src/css/Canvas.css +++ b/maps-frontend/src/css/Canvas.css @@ -1,6 +1,5 @@ .Map-canvas { - touch-action: none; - + /*touch-action: none; */ position: absolute; z-index: 5; } \ No newline at end of file diff --git a/maps-frontend/src/css/CoordSelector.css b/maps-frontend/src/css/CoordSelector.css index 696c888..881be08 100644 --- a/maps-frontend/src/css/CoordSelector.css +++ b/maps-frontend/src/css/CoordSelector.css @@ -35,10 +35,11 @@ cursor: default; } +/* .Btn:disabled:hover, .Btn[disabled]:hover{ - cursor: crosshair; } +*/ .Textbox { width: 100px; diff --git a/maps-frontend/src/css/Route.css b/maps-frontend/src/css/Route.css index eaa69c4..efc4868 100644 --- a/maps-frontend/src/css/Route.css +++ b/maps-frontend/src/css/Route.css @@ -4,7 +4,7 @@ color: white; border-radius: 10px; background-color: #121212; - cursor: default; + /*cursor: default;*/ /* Transparent background */ background: rgba(0, 0, 0, 0); } @@ -51,6 +51,6 @@ border: 1px solid #999999; background-color: #cccccc; color: #666666; - cursor: default; + /*cursor: default;*/ box-shadow: none; } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c39ae04..7f58d3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14313,6 +14313,28 @@ "extsprintf": "^1.2.0" } }, + "vis-react": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/vis-react/-/vis-react-0.5.1.tgz", + "integrity": "sha512-jXwTM7mbGpTohOiiKAYXPXyEEvm6X0oE7hdV0aKnZEmqnSMbsAI1AxQbyZdP7iPrmn0D/RbeotTh05614XjI9w==", + "requires": { + "lodash": "^4.17.15", + "uuid": "^7.0.2", + "vis-react-core": "1.0.0" + }, + "dependencies": { + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==" + } + } + }, + "vis-react-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vis-react-core/-/vis-react-core-1.0.0.tgz", + "integrity": "sha512-K5bJNbd04cOapL2oqTP7AgxLajaaXH9r7z5CsO/uFccbeidzfcX7ZZeV4yXuGMRB70uXGScMa/ZrC3L3+u+i7Q==" + }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", diff --git a/package.json b/package.json index 93b47d2..47492f2 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "react-awesome-button": "^6.5.1", "react-dom": "^17.0.1", "react-scripts": "4.0.3", + "vis-react": "^0.5.1", "web-vitals": "^1.0.1" }, "scripts": { -- cgit v1.2.3-70-g09d2 From 5f1c8ad8dd2944d6791971ba7fc5a4da97a9e9ac Mon Sep 17 00:00:00 2001 From: Michael Foiani Date: Fri, 16 Apr 2021 17:36:25 -0400 Subject: Got the canvas to show. Looking pretty good --- maps-frontend/package-lock.json | 5 +++ maps-frontend/package.json | 1 + maps-frontend/src/App.js | 5 +-- maps-frontend/src/components/DateSelector.js | 2 +- maps-frontend/src/components/Hub.js | 2 +- maps-frontend/src/components/HubList.js | 4 +- maps-frontend/src/components/TimeSelector.js | 4 +- maps-frontend/src/components/Visualization.js | 25 ++++++++--- maps-frontend/src/css/Canvas.css | 2 + package-lock.json | 62 ++++++++++++++++++++++++++- package.json | 1 + 11 files changed, 96 insertions(+), 17 deletions(-) (limited to 'maps-frontend/src/css') diff --git a/maps-frontend/package-lock.json b/maps-frontend/package-lock.json index 7805071..b3d7279 100644 --- a/maps-frontend/package-lock.json +++ b/maps-frontend/package-lock.json @@ -12493,6 +12493,11 @@ "workbox-webpack-plugin": "5.1.4" } }, + "react-uuid": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/react-uuid/-/react-uuid-1.0.2.tgz", + "integrity": "sha512-5e0GM16uuQj9MdRJlZ0GdLC8LKMwpU9PIqYmF27s3fIV2z+rLyASTaiW4aKzSY4DyGanz+ImzsECkftwGWfAwA==" + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", diff --git a/maps-frontend/package.json b/maps-frontend/package.json index 0807122..275780d 100644 --- a/maps-frontend/package.json +++ b/maps-frontend/package.json @@ -10,6 +10,7 @@ "react": "^17.0.1", "react-dom": "^17.0.1", "react-scripts": "4.0.3", + "react-uuid": "^1.0.2", "web-vitals": "^1.1.1" }, "scripts": { diff --git a/maps-frontend/src/App.js b/maps-frontend/src/App.js index 765455e..a080adc 100644 --- a/maps-frontend/src/App.js +++ b/maps-frontend/src/App.js @@ -19,8 +19,8 @@ function App() { const [isChanging, setIsChanging] = useState(false); // State to hold dates -> two weeks apart on initialization. const [dates, setDates] = useState({ - start: new Date(), - end: new Date(Date.now() - 12096e5) + start: new Date(Date.now() - 12096e5), + end: new Date() }); // State for visualization data const [data, setData] = useState([]); @@ -40,7 +40,6 @@ function App() { }) .then(res => res.json()) .then(data => { - console.log(data); setData(data.holders); setHasLoaded(true); }) diff --git a/maps-frontend/src/components/DateSelector.js b/maps-frontend/src/components/DateSelector.js index 5bb00fb..bf01d44 100644 --- a/maps-frontend/src/components/DateSelector.js +++ b/maps-frontend/src/components/DateSelector.js @@ -9,7 +9,7 @@ import '../css/CoordSelector.css'; function DateSelector(props) { return (
- props.changedFunc(Date.parse(e.target.value))} onClick={() => props.clickedFunc()}/> + props.changedFunc(new Date(e.target.value))} onClick={() => props.clickedFunc()}/>
); } diff --git a/maps-frontend/src/components/Hub.js b/maps-frontend/src/components/Hub.js index cd160ea..0504e3b 100644 --- a/maps-frontend/src/components/Hub.js +++ b/maps-frontend/src/components/Hub.js @@ -16,7 +16,7 @@ function Hub(props) { return (
  • - props.getUserCheckins(props.value.id, props.value.name)}>{props.value.name} just checked in! + console.log(props.name)}>{props.name} just checked in! setIsToggled((toggle) => !toggle)} src="/round_expand_more_white_18dp.png" alt="image"/> setIsToggled((toggle) => !toggle)} src="/round_expand_less_white_18dp.png" alt="image"/>
    diff --git a/maps-frontend/src/components/HubList.js b/maps-frontend/src/components/HubList.js index 41cf07a..af6c9b0 100644 --- a/maps-frontend/src/components/HubList.js +++ b/maps-frontend/src/components/HubList.js @@ -19,11 +19,9 @@ function HubList(props) { const updateHubItems = () => { // sort and create the elemnts let hubs = []; - console.log(props.data); const sorted = props.data.sort((a, b) => b.suspicionScore - a.suspicionScore); - console.log(sorted); sorted.forEach(hub => hubs.push( - + )); setHubItems(hubs); diff --git a/maps-frontend/src/components/TimeSelector.js b/maps-frontend/src/components/TimeSelector.js index b396d81..6960807 100644 --- a/maps-frontend/src/components/TimeSelector.js +++ b/maps-frontend/src/components/TimeSelector.js @@ -20,8 +20,8 @@ function TimeSelector(props) { const changeTimeframe = () => { props.setDates({ - start: Date.parse(startDate), - end: Date.parse(endDate) + start: startDate, + end: endDate }); } diff --git a/maps-frontend/src/components/Visualization.js b/maps-frontend/src/components/Visualization.js index 3a9692d..c33339b 100644 --- a/maps-frontend/src/components/Visualization.js +++ b/maps-frontend/src/components/Visualization.js @@ -1,5 +1,6 @@ // JS module imports import { useEffect, useRef, useState } from "react"; +import uuid from 'react-uuid'; import Graph from 'vis-react'; // CSS imports @@ -11,19 +12,31 @@ import '../css/Canvas.css'; * @returns {import("react").HtmlHTMLAttributes} The canvas to be retured. */ function Visualization(props) { + const options = { + edges: { + color: "#ffffff" + } + }; + + const events = { + select: event => { + console.log(event); + } + }; + + const [graphState, setGraphState] = useState({ nodes: [], edges: [] }); const getNodes = () => { - console.log(props.data) - let nodes = [] + let nodes = []; props.data.forEach(hub => { nodes.push({ id: hub.id, label: hub.name, - size: hub.suspicionScore * 25 + size: hub.suspicionScore * 50 }); }); return nodes; @@ -43,13 +56,15 @@ function Visualization(props) { } // Hooks to update graph state - useEffect(() => setGraphState({nodes: getNodes(), edges: getEdges()}), []); useEffect(() => setGraphState({nodes: getNodes(), edges: getEdges()}), [props.data]); return (
    + key={uuid()} + graph={graphState} + options={options} + events={events}>
    ); diff --git a/maps-frontend/src/css/Canvas.css b/maps-frontend/src/css/Canvas.css index 8dee765..e67d87d 100644 --- a/maps-frontend/src/css/Canvas.css +++ b/maps-frontend/src/css/Canvas.css @@ -2,4 +2,6 @@ /*touch-action: none; */ position: absolute; z-index: 5; + width: 100vw; + height: 100vh; } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7f58d3a..ef860f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3304,6 +3304,15 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "optional": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -6159,6 +6168,12 @@ } } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, "filesize": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", @@ -9330,6 +9345,12 @@ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "optional": true + }, "nanoid": { "version": "3.1.22", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz", @@ -11647,6 +11668,25 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==" }, + "react-graph-vis": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/react-graph-vis/-/react-graph-vis-1.0.7.tgz", + "integrity": "sha512-FI35zlBMKU22JEvG1ukd1DDwW185y4YrDvHm6Bom9EGdA+UNMrZrIV/lyPIRWPcRkzbKaA1w1NvOYcRApD4KdQ==", + "requires": { + "lodash": "^4.17.15", + "prop-types": "^15.5.10", + "uuid": "^2.0.1", + "vis-data": "^7.1.2", + "vis-network": "^9.0.0" + }, + "dependencies": { + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" + } + } + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -14313,6 +14353,16 @@ "extsprintf": "^1.2.0" } }, + "vis-data": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-7.1.2.tgz", + "integrity": "sha512-RPSegFxEcnp3HUEJSzhS2vBdbJ2PSsrYYuhRlpHp2frO/MfRtTYbIkkLZmPkA/Sg3pPfBlR235gcoKbtdm4mbw==" + }, + "vis-network": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/vis-network/-/vis-network-9.0.4.tgz", + "integrity": "sha512-F/pq8yBJUuB9lNKXHhtn4GP2h91FV0c2O2nvfU34RX4VCYOlqs+mINdz+J+QkWiYhiPdlVy15gzVEzkhJ9hpaw==" + }, "vis-react": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/vis-react/-/vis-react-0.5.1.tgz", @@ -14487,7 +14537,11 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } }, "glob-parent": { "version": "3.1.0", @@ -15107,7 +15161,11 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } }, "glob-parent": { "version": "3.1.0", diff --git a/package.json b/package.json index 47492f2..227e59b 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "react": "^17.0.1", "react-awesome-button": "^6.5.1", "react-dom": "^17.0.1", + "react-graph-vis": "^1.0.7", "react-scripts": "4.0.3", "vis-react": "^0.5.1", "web-vitals": "^1.0.1" -- cgit v1.2.3-70-g09d2 From 868c250d5c9ab45be1c5a478d2ff5cd82ec60f2d Mon Sep 17 00:00:00 2001 From: Michael Foiani Date: Fri, 16 Apr 2021 18:27:46 -0400 Subject: Working on the request to get info on an investor. --- maps-frontend/src/App.js | 7 +-- maps-frontend/src/components/Hub.js | 9 +--- maps-frontend/src/components/HubList.js | 18 +++++++- maps-frontend/src/components/InvestorInfo.js | 65 +++++++++++++++++++++++++++ maps-frontend/src/components/Loading.js | 2 +- maps-frontend/src/components/Visualization.js | 13 ++---- maps-frontend/src/css/UserCheckin.css | 2 +- 7 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 maps-frontend/src/components/InvestorInfo.js (limited to 'maps-frontend/src/css') diff --git a/maps-frontend/src/App.js b/maps-frontend/src/App.js index a080adc..2eb0c81 100644 --- a/maps-frontend/src/App.js +++ b/maps-frontend/src/App.js @@ -24,6 +24,8 @@ function App() { }); // State for visualization data const [data, setData] = useState([]); + // State for selected person + const [selected, setSelected] = useState(-1); const toEpochMilli = date => Date.parse(date); const getGraphData = () => { @@ -55,7 +57,6 @@ function App() { getGraphData(); }, [dates]); - return ( <> {(!hasLoaded) ? : @@ -64,9 +65,9 @@ function App() {
    - + - + } diff --git a/maps-frontend/src/components/Hub.js b/maps-frontend/src/components/Hub.js index 0504e3b..b5b3f28 100644 --- a/maps-frontend/src/components/Hub.js +++ b/maps-frontend/src/components/Hub.js @@ -11,17 +11,12 @@ import '../css/UserCheckin.css'; */ function Hub(props) { // State - toggled - const [isToggled, setIsToggled] = useState(false); return (
  • - console.log(props.name)}>{props.name} just checked in! - setIsToggled((toggle) => !toggle)} src="/round_expand_more_white_18dp.png" alt="image"/> - setIsToggled((toggle) => !toggle)} src="/round_expand_less_white_18dp.png" alt="image"/> -
    -
  • ); } diff --git a/maps-frontend/src/components/HubList.js b/maps-frontend/src/components/HubList.js index af6c9b0..d046e94 100644 --- a/maps-frontend/src/components/HubList.js +++ b/maps-frontend/src/components/HubList.js @@ -1,6 +1,7 @@ // React and component imports import { useEffect, useState } from "react"; import Hub from "./Hub.js"; +import InvestorInfo from "./InvestorInfo.js"; // CSS import import '../css/UserCheckin.css'; @@ -12,6 +13,7 @@ import '../css/UserCheckin.css'; */ function HubList(props) { const [hubItems, setHubItems] = useState([]); + const [isSelected, setIsSelected] = useState(false); /** * Loads new the checkins into the current cache/map of hubs. @@ -21,21 +23,35 @@ function HubList(props) { let hubs = []; const sorted = props.data.sort((a, b) => b.suspicionScore - a.suspicionScore); sorted.forEach(hub => hubs.push( - + )); setHubItems(hubs); } + const getName = () => { + console.log(props.selected); + props.data.forEach(hub => { + if (hub.id == props.selected) { + return hub.name; + } + }) + return ''; + } + // React hook that updates when the hubs are recalculated useEffect(() => updateHubItems(), [props.data]); + //React hook to show data for an investor + useEffect(() => setIsSelected(true), [props.selected]); + return (

    Suspicion Ranks

      {hubItems}
    +
    ); } diff --git a/maps-frontend/src/components/InvestorInfo.js b/maps-frontend/src/components/InvestorInfo.js new file mode 100644 index 0000000..24994d0 --- /dev/null +++ b/maps-frontend/src/components/InvestorInfo.js @@ -0,0 +1,65 @@ +// React import +import { useEffect, useState } from "react"; + +// CSS import +import '../css/UserCheckin.css'; + +/** + * Componenet for checkins. Has a toggle to show more info. + * @param {Object} props The props of the component. + * @returns {import('react').HtmlHTMLAttributes} A list element holding a checkin's info. + */ +function InvestorInfo(props) { + const [info, setInfo] = useState({}); + + const toEpochMilli = date => Date.parse(date); + const getInfo = () => { + if (props.name === "") { + return; + } + + console.log({ + person: props.name, + start: toEpochMilli(props.dates.start), + end: toEpochMilli(props.dates.end) + }); + fetch("http://localhost:4567/profit", { + method: "POST", + body: JSON.stringify({ + person: props.name, + start: toEpochMilli(props.dates.start), + end: toEpochMilli(props.dates.end) + }), + headers: { + "Content-Type": "application/json", + }, + credentials: "same-origin" + }) + .then(res => { + console.log(res); + res.json(); + }) + .then(data => { + console.log(data); + setInfo(data); + }) + .catch(err => console.log(err)); + } + /* + + const coords = userCoords.map((coord, index) => +
  • + {'('+coord[0].toFixed(6)}, {coord[1].toFixed(6)+')'} +
  • + );*/ + + useEffect(() => getInfo(), [props.name]) + +return ( +
    + hi +
    +); +} + +export default InvestorInfo; \ No newline at end of file diff --git a/maps-frontend/src/components/Loading.js b/maps-frontend/src/components/Loading.js index ed95bb1..6fdf5ba 100644 --- a/maps-frontend/src/components/Loading.js +++ b/maps-frontend/src/components/Loading.js @@ -10,7 +10,7 @@ function Loading() {
    logo -

    Loading Maps

    +

    Loading WatchDogs

    It takes a minute to connect to the servers and database :)

    diff --git a/maps-frontend/src/components/Visualization.js b/maps-frontend/src/components/Visualization.js index c33339b..c0e5811 100644 --- a/maps-frontend/src/components/Visualization.js +++ b/maps-frontend/src/components/Visualization.js @@ -15,33 +15,28 @@ function Visualization(props) { const options = { edges: { color: "#ffffff" - } + }, + autoResize: true }; - const events = { - select: event => { - console.log(event); - } + select: () => event => props.setSelected(event.nodes[0]) }; - const [graphState, setGraphState] = useState({ nodes: [], edges: [] }); - const getNodes = () => { let nodes = []; props.data.forEach(hub => { nodes.push({ id: hub.id, label: hub.name, - size: hub.suspicionScore * 50 + size: hub.suspicionScore * 10 }); }); return nodes; } - const getEdges = () => { let edges = [] props.data.forEach(hub => { diff --git a/maps-frontend/src/css/UserCheckin.css b/maps-frontend/src/css/UserCheckin.css index 3e16ffd..141cc01 100644 --- a/maps-frontend/src/css/UserCheckin.css +++ b/maps-frontend/src/css/UserCheckin.css @@ -60,7 +60,7 @@ ul { .Checkin { - padding-bottom: 20px; + padding-top: 10px; border-bottom: 1px solid #e6ecf0; } -- cgit v1.2.3-70-g09d2