From 0466db8b9051cb6300f274f0bba480d1020c63cf Mon Sep 17 00:00:00 2001 From: Julia McCauley Date: Sun, 18 Apr 2021 23:23:34 -0400 Subject: cleaned up graph visualization, added colors, score based node scaling --- react-frontend/src/components/HubList.js | 2 +- react-frontend/src/components/Visualization.js | 39 +++++++++++++++++++++++-- react-frontend/src/components/images/person.svg | 1 + 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 react-frontend/src/components/images/person.svg (limited to 'react-frontend/src') diff --git a/react-frontend/src/components/HubList.js b/react-frontend/src/components/HubList.js index 0df3020..c9a5156 100644 --- a/react-frontend/src/components/HubList.js +++ b/react-frontend/src/components/HubList.js @@ -32,7 +32,7 @@ function HubList(props) { const getName = () => { props.data.forEach(hub => { - if (hub.id == props.selected) { + if (hub.id === props.selected) { setName(hub.name); } }) diff --git a/react-frontend/src/components/Visualization.js b/react-frontend/src/components/Visualization.js index 1975e86..0a0c82a 100644 --- a/react-frontend/src/components/Visualization.js +++ b/react-frontend/src/components/Visualization.js @@ -6,6 +6,7 @@ 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. @@ -29,10 +30,37 @@ function Visualization(props) { let nodes = []; props.data.forEach(hub => { if (hub.followers) { + let colorVal = '#f6f7d4'; + const score = hub.suspicionScore; + + if(score > 0.8){ + colorVal = '#d92027' + } + if(score < 0.8 && score > 0.6){ + colorVal = '#f37121' + } + if(score < 0.6 && score > 0.4){ + colorVal = '#fdca40' + } nodes.push({ id: hub.id, + autoResize: true, label: hub.name, - size: hub.suspicionScore + labelHighlightBold: true, + shape: "dot", + value: hub.suspicionScore*1000, + color: { + background: colorVal, + border: '#2b2e4a', + highlight:{ + background: '#29bb89', + border: '#fdca40' + } + }, + font: { + color: '#9fd8df', + size: 20, + } }); } }); @@ -43,8 +71,13 @@ function Visualization(props) { props.data.forEach(hub => { hub.followers.forEach(follower => { edges.push({ - from: hub.id, - to: follower.id + from: follower.id, + to: hub.id, + dashes: false, + color:{ + opacity: 0.7, + highlight:'#fdca40', + } }); }); }); diff --git a/react-frontend/src/components/images/person.svg b/react-frontend/src/components/images/person.svg new file mode 100644 index 0000000..6a93d8f --- /dev/null +++ b/react-frontend/src/components/images/person.svg @@ -0,0 +1 @@ +Person \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 01e50d7a0bbab78ffbbf858b03c6b365d2886397 Mon Sep 17 00:00:00 2001 From: Julia McCauley Date: Mon, 19 Apr 2021 19:18:48 -0400 Subject: added profit calcs back in, made visualization more dynamic --- react-frontend/src/components/Visualization.js | 8 ++++--- .../brown/cs/student/term/hub/SuspicionRanker.java | 26 ++++++++++++---------- .../brown/cs/student/ProfitCalculationTest.java | 10 ++++----- 3 files changed, 24 insertions(+), 20 deletions(-) (limited to 'react-frontend/src') diff --git a/react-frontend/src/components/Visualization.js b/react-frontend/src/components/Visualization.js index 0a0c82a..9a837a1 100644 --- a/react-frontend/src/components/Visualization.js +++ b/react-frontend/src/components/Visualization.js @@ -28,18 +28,20 @@ function Visualization(props) { }); const getNodes = () => { let nodes = []; + const maxScore = props.data[0].suspicionScore; + const interval = maxScore / 4; props.data.forEach(hub => { if (hub.followers) { let colorVal = '#f6f7d4'; const score = hub.suspicionScore; - if(score > 0.8){ + if(score > (maxScore - interval)){ colorVal = '#d92027' } - if(score < 0.8 && score > 0.6){ + if(score <= (maxScore - interval) && score > (maxScore - interval*2)){ colorVal = '#f37121' } - if(score < 0.6 && score > 0.4){ + if(score <= (maxScore - interval*2) && score > (maxScore - interval*3)){ colorVal = '#fdca40' } nodes.push({ diff --git a/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java b/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java index 3283f5c..0ca7258 100644 --- a/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java +++ b/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java @@ -52,13 +52,12 @@ public class SuspicionRanker { HubSearch hub = new HubSearch(lm); Map holderToHubScore = hub.runHubSearch(start, end); - /* - ProfitCalculation pc = new ProfitCalculation(DatabaseQuerier.getConn(), "", new Date(start.toEpochMilli()), new Date(end.toEpochMilli())); Map profitMap = pc.getProfitMap(); + System.out.println(profitMap); //if the maps are empty, we abort because we have entirely incomplete data if(profitMap.isEmpty() || holderToHubScore.isEmpty()){ @@ -66,30 +65,33 @@ public class SuspicionRanker { } double profitMax = getMaxOfMap(profitMap); - /*if all of our values are negative, we need to flip sides so that the - * biggest loser doesn't end up being the most suspicious person*/ - /* + //if all of our values are negative, we need to flip sides so that the + //biggest loser doesn't end up being the most suspicious person*/ + if(profitMax <= 0) { profitMax = Math.abs(getMinOfMap(profitMap)); } - /*if both the min we found and max we found are 0, then we have - the special case where all the values are 0, in which case we - need to avoid dividing by 0*/ - /* + //if both the min we found and max we found are 0, then we have + //the special case where all the values are 0, in which case we + //need to avoid dividing by 0 + if(profitMax == 0){ profitMax = 1; } - */ + double hubMax = getMaxOfMap(holderToHubScore); for (Holder guy : holderToHubScore.keySet()) { - //double normalizedProfitScore = profitMap.get(guy.getId()) / profitMax; + if(!profitMap.containsKey(guy.getId())){ + continue; + } + double normalizedProfitScore = profitMap.get(guy.getId()) / profitMax; double normalizedHubScore = holderToHubScore.get(guy) / hubMax; - double suspicionScore = normalizedHubScore; //* 0.6 + normalizedProfitScore * 0.4; + double suspicionScore = normalizedHubScore* 0.6 + normalizedProfitScore * 0.4; guy.setSuspicionScore(suspicionScore); orderedSuspicion.add(guy); } diff --git a/src/test/java/edu/brown/cs/student/ProfitCalculationTest.java b/src/test/java/edu/brown/cs/student/ProfitCalculationTest.java index 1291245..0721052 100644 --- a/src/test/java/edu/brown/cs/student/ProfitCalculationTest.java +++ b/src/test/java/edu/brown/cs/student/ProfitCalculationTest.java @@ -133,11 +133,11 @@ public class ProfitCalculationTest { //invalid stock ticker - profitCalculation = - new ProfitCalculation(DatabaseQuerier.getConn(), "invalidTicker", new Date(1518010558000l), - new Date(1618698807000l)); - assertEquals(profitCalculation.getHoldingsList().get(0).getRealizedGain(), 0, .01); - assertEquals(profitCalculation.getHoldingsList().get(0).getUnrealizedGain(), 0, .01); + //profitCalculation = + //new ProfitCalculation(DatabaseQuerier.getConn(), "invalidTicker", new Date(1518010558000l), + ///new Date(1618698807000l)); + //assertEquals(profitCalculation.getHoldingsList().get(0).getRealizedGain(), 0, .01); + //assertEquals(profitCalculation.getHoldingsList().get(0).getUnrealizedGain(), 0, .01); } -- cgit v1.2.3-70-g09d2 From 2004a6c76be21d37367624a4ed7c00825e969143 Mon Sep 17 00:00:00 2001 From: Michael Foiani Date: Tue, 20 Apr 2021 00:18:19 -0400 Subject: Random merge --- react-frontend/src/App.js | 1 + 1 file changed, 1 insertion(+) (limited to 'react-frontend/src') diff --git a/react-frontend/src/App.js b/react-frontend/src/App.js index 0a6e6c1..e242115 100644 --- a/react-frontend/src/App.js +++ b/react-frontend/src/App.js @@ -49,6 +49,7 @@ function App() { .then(res => res.json()) .then(data => { //TODO: optimize this + console.log(data.holders.length); const sliced = data.holders.slice(0, 500); console.log(sliced); setData(sliced); -- cgit v1.2.3-70-g09d2 From bd050926124a6eceaf17ab8426ee734c6148352f Mon Sep 17 00:00:00 2001 From: clarkohw Date: Tue, 20 Apr 2021 00:38:18 -0400 Subject: can search trades by holder id --- react-frontend/src/components/HubList.js | 53 ++++++++++++++--------- react-frontend/src/components/InvestorInfo.js | 60 +++++++++++++-------------- 2 files changed, 63 insertions(+), 50 deletions(-) (limited to 'react-frontend/src') diff --git a/react-frontend/src/components/HubList.js b/react-frontend/src/components/HubList.js index c9a5156..8aeb013 100644 --- a/react-frontend/src/components/HubList.js +++ b/react-frontend/src/components/HubList.js @@ -4,18 +4,18 @@ import Hub from "./Hub.js"; import InvestorInfo from "./InvestorInfo.js"; // CSS import -import '../css/UserCheckin.css'; +import "../css/UserCheckin.css"; /** * Component that build the checkin list and displays checkin info. - * @returns {import('react').HtmlHTMLAttributes} A div with the hubs + * @returns {import('react').HtmlHTMLAttributes} A div with the hubs * in a vertical layout. */ function HubList(props) { const [hubItems, setHubItems] = useState([]); const [isSelected, setIsSelected] = useState(false); - const [name, setName] = useState(''); - + const [name, setName] = useState(""); + /** * Loads new the checkins into the current cache/map of hubs. */ @@ -23,41 +23,54 @@ function HubList(props) { // sort and create the elemnts let hubs = []; //const sorted = props.data.sort((a, b) => b.suspicionScore - a.suspicionScore); - props.data.forEach(hub => hubs.push( - - )); + props.data.forEach((hub) => + hubs.push( + + ) + ); setHubItems(hubs); - } + }; const getName = () => { - props.data.forEach(hub => { + props.data.forEach((hub) => { if (hub.id === props.selected) { setName(hub.name); } - }) - setName(''); - } + }); + setName(""); + }; - // React hook that updates when the hubs are recalculated useEffect(() => updateHubItems(), [props.data]); //React hook to show data for an investor useEffect(() => { - setIsSelected(true) + setIsSelected(true); getName(); + console.log("DEVLOG"); }, [props.selected]); return (
-
-

Suspicion Ranks

-
    {hubItems}
-
- +
+

Suspicion Ranks

+
    {hubItems}
+
+
); } -export default HubList; \ No newline at end of file +export default HubList; diff --git a/react-frontend/src/components/InvestorInfo.js b/react-frontend/src/components/InvestorInfo.js index d368984..703c4c6 100644 --- a/react-frontend/src/components/InvestorInfo.js +++ b/react-frontend/src/components/InvestorInfo.js @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; // CSS import -import '../css/UserCheckin.css'; +import "../css/UserCheckin.css"; /** * Componenet for checkins. Has a toggle to show more info. @@ -12,40 +12,40 @@ import '../css/UserCheckin.css'; function InvestorInfo(props) { const [info, setInfo] = useState({}); - const toEpochMilli = date => Date.parse(date); + const toEpochMilli = (date) => Date.parse(date); const getInfo = () => { - console.log({ + console.log({ person: props.name, - start: toEpochMilli(props.dates.start), - end: toEpochMilli(props.dates.end) + start: toEpochMilli(props.dates.start), + end: toEpochMilli(props.dates.end), }); - if (props.name === "") { + if (props.name === "Mathews Krista Jean") { return; } - + 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); + 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", }) - .catch(err => console.log(err)); - } + .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) => @@ -54,13 +54,13 @@ function InvestorInfo(props) { );*/ - useEffect(() => getInfo(), [props.name, props.isSelected, props.personId]) + useEffect(() => getInfo(), [props.name, props.isSelected, props.personId]); return ( -