diff --git a/src/App.js b/src/App.js index d246157..df52849 100644 --- a/src/App.js +++ b/src/App.js @@ -4,7 +4,8 @@ import Startup from './pages/loadingScreen.js'; import Grafana from './pages/grafana.js'; import Livepeer from './pages/livepeer.js'; import Stats from './pages/stats.js'; -import Summary from './pages/summary.js' +import Summary from './pages/summary.js'; +import Graphs from './pages/graph.js'; import { BrowserRouter as Router, @@ -22,6 +23,7 @@ export default function App() { } /> } /> } /> + } /> } /> } /> diff --git a/src/components/CommissionGraph.js b/src/components/CommissionGraph.js new file mode 100644 index 0000000..387b811 --- /dev/null +++ b/src/components/CommissionGraph.js @@ -0,0 +1,14 @@ +import React, { useState } from 'react'; +import { useSelector } from 'react-redux'; + +const CommissionGraph = (obj) => { + + + return ( +
+ +
+ ) +} + +export default CommissionGraph; \ No newline at end of file diff --git a/src/components/MonthlyOrchestrators.js b/src/components/MonthlyOrchestrators.js index ac53b5d..1d065a8 100644 --- a/src/components/MonthlyOrchestrators.js +++ b/src/components/MonthlyOrchestrators.js @@ -10,7 +10,6 @@ import { Pagination } from "@mantine/core"; const itemsPerPage = 10; const MonthlyOrchestrators = (obj) => { - const livepeer = useSelector((state) => state.livepeerstate); const [thisScores, setThisScores] = useState(null); const [activePage, setPage] = useState(1); diff --git a/src/components/TotalStakeGraph.js b/src/components/TotalStakeGraph.js new file mode 100644 index 0000000..474a773 --- /dev/null +++ b/src/components/TotalStakeGraph.js @@ -0,0 +1,163 @@ +import React, { useState } from 'react'; +import { useSelector } from 'react-redux'; +import { VictoryLine, VictoryChart, VictoryLegend } from 'victory'; + +const TotalStakeGraph = (obj) => { + const livepeer = useSelector((state) => state.livepeerstate); + + const getName = (address) => { + let thisDomain = null; + // Lookup domain in cache + if (livepeer.ensDomainMapping) { + for (const thisAddr of livepeer.ensDomainMapping) { + if (thisAddr.address === address) { + thisDomain = thisAddr; + break; + } + } + } + // Lookup current info in cache only if this addr has a mapped ENS domain + if (thisDomain && thisDomain.domain) { + for (const thisAddr of livepeer.ensInfoMapping) { + if (thisAddr.domain === thisDomain.domain) { + if (thisAddr.domain.length > 18) { + return (thisAddr.domain.substring(0, 16) + ".."); + } + return thisAddr.domain; + } + } + } + + if (livepeer.threeBoxInfo) { + for (const thisAddr of livepeer.threeBoxInfo) { + if (thisAddr.address === address) { + if (thisAddr.name) { + if (thisAddr.name.length > 18) { + return (thisAddr.name.substring(0, 16) + ".."); + } + return thisAddr.name; + } else { + return (address.substring(0, 16) + ".."); + } + break; + } + } + } + + return (address.substring(0, 16) + ".."); + } + + const colors = [ + "#282678", + "#56256c", + "#872974", + "#b63074", + "#de416d", + "#ff5c5f", + "#ffe085", + "#f0e575", + "#daec69", + "#bef262", + "#97f964", + "#5cff6f", + "#14ff47", + "#00fb94", + "#00f3cd", + "#00e7f3", + "#00d8ff", + "#24c8ff", + "#0a78ff", + "#5864d7", + "#6952b1", + "#69448d", + "#61386c", + "#522f50" + ] + let listOfNames = []; + let listOfLists = []; + let listToParse = [...obj.data]; + + // Turn unprocessed list into a per orchestrator list + while (listToParse.length) { + // Take first orchestrator as the current orchestrator + const currentOrchestrator = listToParse[0].address; + let thisIdx = listToParse.length - 1; + let curData = []; + // Split of all orchestrators + while (thisIdx >= 0) { + const cur = listToParse[thisIdx]; + if (cur.address == currentOrchestrator) { + const thisDate = new Date(cur.timestamp); + curData.push({ + x: thisDate, + y: cur.totalStake.toFixed(0) + }); + listToParse.splice(thisIdx, 1); + } + thisIdx--; + } + if (curData.length) { + listOfNames.push(currentOrchestrator); + listOfLists.push(curData); + } + } + + let legendData = []; + + return ( +
+
+
+

Total stake over time

+ + {listOfLists.map((thisData, thisIndex) => { + if (thisIndex < 100) { + legendData.push({ name: getName(listOfNames[thisIndex]), symbol: { fill: colors[thisIndex % colors.length] } }); + return ( + + ) + } else { + return null; + } + })} + +
+ +
+
+
+
+ ) +} + +export default TotalStakeGraph; \ No newline at end of file diff --git a/src/pages/graph.js b/src/pages/graph.js new file mode 100644 index 0000000..68ba1ae --- /dev/null +++ b/src/pages/graph.js @@ -0,0 +1,164 @@ +import React, { useState } from 'react' +import '../style.css'; +import { Navigate } from "react-router-dom"; +import { useSelector } from 'react-redux'; +import { SegmentedControl } from "@mantine/core"; +import CommissionGraph from '../components/CommissionGraph'; +import TotalStakeGraph from '../components/TotalStakeGraph'; + + +const Graphs = (obj) => { + const livepeer = useSelector((state) => state.livepeerstate); + const [redirectToHome, setRedirectToHome] = useState(false); + const [showOnlyTranscoders, setShowOnlyTranscoders] = useState(true); + const [activePage, setPage] = useState(1); + + let thisColour; + if (activePage == 1) { + thisColour = "teal"; + } else if (activePage == 2) { + thisColour = "indigo"; + } else if (activePage == 3) { + thisColour = "gray"; + } + console.log("Rendering Graphs Viewer"); + + if (redirectToHome) { + return ; + } + + return ( +
+ +
+
+
+
+
+
+
+
+ +
+ { + activePage == 1 ? : null + } + { + activePage == 2 ? : null + } +
+
+
+
+
+
+
+
+
+ ); +} + +export default Graphs; \ No newline at end of file diff --git a/src/pages/home.js b/src/pages/home.js index 111dfb6..29b0c75 100644 --- a/src/pages/home.js +++ b/src/pages/home.js @@ -15,6 +15,7 @@ const Home = (obj) => { const [redirectToGrafana, setRedirectToGrafana] = useState(false); const [redirectToLPT, setRedirectToLPT] = useState(false); const [redirectToStats, setRedirectToStats] = useState(false); + const [redirectToGraphs, setRedirectToGraphs] = useState(false); if (redirectToGrafana) { return ; } @@ -24,6 +25,10 @@ const Home = (obj) => { if (redirectToStats) { return ; } + + if (redirectToGraphs) { + return ; + } // Get amount of unique IP's which have visited this website var totalVisitorCount = 0; if (userstate.visitorStats) { @@ -38,7 +43,7 @@ const Home = (obj) => {
-
+

Home

@@ -71,11 +76,25 @@ const Home = (obj) => {

📈 Statistics 💰

+
+ +
+
+

Status

+
+
+

Currently there is an issue with Events getting duplicated. The website will have inflated statistics and become unavailable from time to time while we are working on a fix

+
+