|
1 | 1 | /* eslint-disable react/jsx-one-expression-per-line */ |
2 | 2 | import React, { useContext } from 'react'; |
3 | | -import { Bar } from 'react-chartjs-2'; |
| 3 | +// import { Bar } from 'react-chartjs-2'; |
4 | 4 | import CommunicationsContext from '../context/OverviewContext'; |
5 | 5 | import '../stylesheets/routes.css'; |
6 | 6 |
|
7 | 7 | const RouteLocations = (props) => { |
8 | 8 | const communicationsData = useContext(CommunicationsContext).overviewData; |
9 | | - |
10 | | - // initialize an empty object resObj. This object will store the microservice names as values and its corresponding correlatingId or correlatingid as keys. The microservice names will be stored in array within the order it was to the database. |
| 9 | + // console.log('commData (from overviewContxt):', communicationsData); |
| 10 | + |
| 11 | + // initialize an empty object resObj. |
| 12 | + // This object will store the microservice names as values and its corresponding correlatingId or correlatingid as keys. |
| 13 | + // The microservice names will be stored in array within the order it was to the database. |
11 | 14 | const resObj = {}; |
12 | 15 |
|
13 | 16 | if (communicationsData.length > 0 && communicationsData[0]._id) { |
14 | | - // Sort the communication array from latest to earliest document |
| 17 | + // Sort the communication array from OLDEST to NEWEST documents. |
15 | 18 | communicationsData.sort((a, b) => { |
| 19 | + // Note that a newer date obj IS GREATER THAN an older date obj. |
16 | 20 | if (new Date(a.timeSent) > new Date(b.timeSent)) return 1; |
17 | 21 | if (new Date(a.timeSent) < new Date(b.timeSent)) return -1; |
18 | 22 | return 0; |
19 | 23 | }); |
| 24 | + // console.log('commData (AFTER sorting):', communicationsData); |
20 | 25 |
|
21 | | - // Iterate over sorted communicationsData array from the end to the beginning |
| 26 | + // Iterate over sorted array to build up resObj. |
22 | 27 | for (let i = 0; i < communicationsData.length; i += 1) { |
23 | 28 | // declare a constant element and initialize it as the object at index i of the communicationsData array |
24 | 29 | const element = communicationsData[i]; |
25 | | - // Pushes the microservice name into the object |
| 30 | + // Pushes the microservice name & timeSent into the resObj. |
| 31 | + // Data objects w/ same corrId will be grouped in a same array. |
26 | 32 | if (resObj[element.correlatingId]) { |
27 | | - resObj[element.correlatingId].push(element.currentMicroservice); |
28 | | - } else resObj[element.correlatingId] = [element.currentMicroservice]; |
| 33 | + resObj[element.correlatingId].push({ |
| 34 | + microservice_name: element.currentMicroservice, |
| 35 | + timeSent: element.timeSent |
| 36 | + }); |
| 37 | + } else { |
| 38 | + // The value that corresp. to the correlationId key is an array of obj containing name and time data. |
| 39 | + // Each obj is a data point. |
| 40 | + resObj[element.correlatingId] = [{ |
| 41 | + microservice_name: element.currentMicroservice, |
| 42 | + timeSent: element.timeSent |
| 43 | + }]; |
| 44 | + } |
29 | 45 | } |
30 | 46 | } else { |
31 | 47 | for (let i = communicationsData.length - 1; i >= 0; i--) { |
32 | 48 | const element = communicationsData[i]; |
33 | | - if (resObj[element.correlatingid]) resObj[element.correlatingid].push(element.currentmicroservice); |
34 | | - else resObj[element.correlatingid] = [element.currentmicroservice]; |
| 49 | + if (resObj[element.correlatingId]) { |
| 50 | + resObj[element.correlatingId].push({ |
| 51 | + microservice_name: element.currentMicroservice, |
| 52 | + timeSent: element.timeSent |
| 53 | + }); |
| 54 | + } else { |
| 55 | + // The value that corresp. to the correlationId key is an array of obj containing name and time data. |
| 56 | + // Each obj is a data point. |
| 57 | + resObj[element.correlatingId] = [{ |
| 58 | + microservice_name: element.currentMicroservice, |
| 59 | + timeSent: element.timeSent |
| 60 | + }]; |
| 61 | + } |
35 | 62 | // initializing the object with the first microservice |
36 | 63 | } |
37 | 64 | } |
38 | 65 |
|
39 | | - // use object values to destructure locations |
40 | | - const tracePoints = Object.values(resObj); |
41 | | - const position = communicationsData[0].correlatingid ? 0 : tracePoints.length - 1; |
| 66 | + // use Object.values to destructure locations |
| 67 | + // Each elem in tracePoints is an array of arrays, which contain objects (each of which is a data point). |
| 68 | + // Filter the array so that only subarrays w/ len > 1 are kept. |
| 69 | + // (len == 1 means there's only one point in the route. There's no meaningful data to be gained from those.) |
| 70 | + const tracePoints = Object.values(resObj).filter(subArray => subArray.length > 1); |
| 71 | + // console.log('tracePoints arr:', tracePoints); |
| 72 | + |
| 73 | + |
| 74 | + // Construct an obj that stores data necessary for calculating avg speed of requests btw 2 pts. |
| 75 | + const avgDataObj = {}; |
| 76 | + /****** Build the object here w/ nested loops ************/ |
| 77 | + /****** WARNING: tracePoints arr can be very long (100+) ************/ |
| 78 | + for (let i = 0; i < tracePoints.length; i += 1) { |
| 79 | + let subArr = tracePoints[i]; |
| 80 | + for (let j = 0; j < subArr.length; j += 1) { |
| 81 | + let currDataObj = subArr[j]; |
| 82 | + if (j < subArr.length - 1) { |
| 83 | + let nextDataObj = subArr[j + 1]; |
| 84 | + let routeName = `${currDataObj.microservice_name}-${nextDataObj.microservice_name}`; |
| 85 | + // Key/value pair that keeps COUNT of two-point routes |
| 86 | + if (!avgDataObj[`${routeName}Count`]) avgDataObj[`${routeName}Count`] = 1; |
| 87 | + else avgDataObj[`${routeName}Count`] += 1; |
| 88 | + |
| 89 | + // Key/value that accumulates TOTAL TIME a req travels btw 2 certain points |
| 90 | + let timeDiff = new Date(nextDataObj.timeSent) - new Date(currDataObj.timeSent); |
| 91 | + if (!avgDataObj[`${routeName}TotalTime`]) { |
| 92 | + avgDataObj[`${routeName}TotalTime`] = timeDiff; |
| 93 | + } |
| 94 | + else avgDataObj[`${routeName}TotalTime`] += timeDiff; |
| 95 | + |
| 96 | + // Key/value that calculates AVG TIME of travel (dividing the 2 values above) |
| 97 | + let avgTime = avgDataObj[`${routeName}TotalTime`] / avgDataObj[`${routeName}Count`]; |
| 98 | + avgDataObj[`${routeName}AvgTime`] = avgTime; |
| 99 | + } |
| 100 | + } |
| 101 | + } |
| 102 | + /** End of nested loops */ |
| 103 | + console.log('avgDataObj:', avgDataObj); |
| 104 | + /****************************************/ |
42 | 105 |
|
| 106 | + // Array of <divs> to be rendered. Each <div> contains route name and time difference. |
43 | 107 | const resArray = []; |
44 | 108 |
|
45 | | - // iterate over Trace Points |
| 109 | + const position = communicationsData[0].correlatingid ? 0 : tracePoints.length - 1; |
| 110 | + console.log('position for tracePoints:', position); |
| 111 | + |
| 112 | + // iterate over ONE elem in tracePoints, creating a <div> for every data obj. |
46 | 113 | for (let i = 0; i < tracePoints[position].length; i += 1) { |
47 | | - // push into resulting array current tracepoint as div |
48 | | - resArray.push( |
49 | | - <div className="RouteCircle" key={i}> |
50 | | - <p id="routeText">Point {i + 1}: {tracePoints[position][i]}</p> |
51 | | - </div>, |
52 | | - ); |
| 114 | + if (i !== tracePoints[position].length - 1) { |
| 115 | + // Calc time difference (when not at the end of array): |
| 116 | + // Convert time str to Date obj w/ new Date(), then get the time difference. |
| 117 | + const timeDiff = new Date(tracePoints[position][i + 1].timeSent) - new Date(tracePoints[position][i].timeSent); |
| 118 | + resArray.push( |
| 119 | + <div className="RouteCircle" key={i}> |
| 120 | + {/* Altering this <p> so it displays only microsvc_name */} |
| 121 | + <p id="routeText"> |
| 122 | + Point {i + 1}: {tracePoints[position][i].microservice_name} |
| 123 | + </p> |
| 124 | + {/* Adding another <p> that displays time difference btw curr obj and next obj */} |
| 125 | + <p id="routeTimeDiff"> |
| 126 | + {/* Time: {tracePoints[position][i].timeSent} */} |
| 127 | + Time elapsed: {timeDiff} ms |
| 128 | + </p> |
| 129 | + </div>, |
| 130 | + ); |
| 131 | + } else { |
| 132 | + // If at the end of array, don't push the timeDiff <p> to resArray (only push a <p> w/ name). |
| 133 | + resArray.push( |
| 134 | + <div className="RouteCircle" key={i}> |
| 135 | + <p id="routeText"> |
| 136 | + Point {i + 1}: {tracePoints[position][i].microservice_name} |
| 137 | + </p> |
| 138 | + </div>, |
| 139 | + ); |
| 140 | + } |
53 | 141 | } |
| 142 | + // console.log('resArray: ', resArray); |
| 143 | + |
| 144 | + /**** Making a list of avg speed-related data. ********/ |
| 145 | + // const avgData = []; |
| 146 | + // Object.entries(avgDataObj).forEach((el, i) => { |
| 147 | + // avgData.push( |
| 148 | + // <span className="avgDataDetails" key={`${i}+${el[0]}`}> |
| 149 | + // {el[0]}: {el[1]} |
| 150 | + // </span> |
| 151 | + // ) |
| 152 | + // }) |
| 153 | + // console.log('avgData (array):', avgData); |
54 | 154 |
|
55 | | - console.log('resArray: ', resArray); |
| 155 | + /**** Making CATEGORIZED lists of avg speed-related data. ********/ |
| 156 | + const avgTime = [], totalTime = [], count = []; |
| 157 | + let i = 0; // For unique keys for each <span> // |
56 | 158 |
|
| 159 | + for (const key in avgDataObj) { |
| 160 | + i += 1; |
| 161 | + |
| 162 | + if (key.endsWith('AvgTime')) { |
| 163 | + avgTime.push( |
| 164 | + <span className="avgDataDetails" key={i}> |
| 165 | + {key.slice(0, -7)}: {avgDataObj[key]} ms |
| 166 | + </span> |
| 167 | + ) |
| 168 | + } |
| 169 | + if (key.endsWith('TotalTime')) { |
| 170 | + totalTime.push( |
| 171 | + <span className="avgDataDetails" key={i}> |
| 172 | + {key.slice(0, -9)}: {avgDataObj[key]} ms |
| 173 | + </span> |
| 174 | + ) |
| 175 | + } |
| 176 | + if (key.endsWith('Count')) { |
| 177 | + count.push( |
| 178 | + <span className="avgDataDetails" key={i}> |
| 179 | + {key.slice(0, -5)}: {avgDataObj[key]} |
| 180 | + </span> |
| 181 | + ) |
| 182 | + } |
| 183 | + } |
| 184 | + // console.log('avgTime:', avgTime); |
| 185 | + // console.log('totalTime:', totalTime); |
| 186 | + // console.log('count:', count); |
| 187 | + /****************/ |
57 | 188 |
|
58 | | - // return div with Trace Points data |
59 | 189 | return ( |
60 | | - <div> |
| 190 | + <div id="routeDataArea"> |
| 191 | + {/* Data on the lastest route */} |
61 | 192 | {resArray} |
| 193 | + |
| 194 | + {/* Rendering avg-speed related data */} |
| 195 | + <div id="avgData"> |
| 196 | + {/* {avgData} */} |
| 197 | + <span className="avgData-titles">Average time between points:</span> |
| 198 | + {avgTime} |
| 199 | + <span className="avgData-titles">Total time between points:</span> |
| 200 | + {totalTime} |
| 201 | + <span className="avgData-titles">Number of trips between points:</span> |
| 202 | + {count} |
| 203 | + </div> |
62 | 204 | </div> |
63 | 205 | ); |
64 | 206 | }; |
|
0 commit comments