Skip to content

Commit 8490097

Browse files
authored
Merge pull request #1 from ajlee12/master
Merging in "time-stamp" feature to org's staging
2 parents 9908349 + fbcd90e commit 8490097

File tree

5 files changed

+206
-33
lines changed

5 files changed

+206
-33
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
node_modules
22
.eslintrc.js
33
package-lock.json
4-
settings.json
5-
.DS_Store
4+
.DS_Store
5+
user/settings.json

app/charts/route-trace.jsx

Lines changed: 165 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,205 @@
11
/* eslint-disable react/jsx-one-expression-per-line */
22
import React, { useContext } from 'react';
3-
import { Bar } from 'react-chartjs-2';
3+
// import { Bar } from 'react-chartjs-2';
44
import CommunicationsContext from '../context/OverviewContext';
55

66
const RouteLocations = (props) => {
77
const communicationsData = useContext(CommunicationsContext).overviewData;
8-
9-
// 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.
8+
// console.log('commData (from overviewContxt):', communicationsData);
9+
10+
// initialize an empty object resObj.
11+
// This object will store the microservice names as values and its corresponding correlatingId or correlatingid as keys.
12+
// The microservice names will be stored in array within the order it was to the database.
1013
const resObj = {};
1114

1215
if (communicationsData.length > 0 && communicationsData[0]._id) {
13-
// Sort the communication array from latest to earliest document
16+
// Sort the communication array from OLDEST to NEWEST documents.
1417
communicationsData.sort((a, b) => {
18+
// Note that a newer date obj IS GREATER THAN an older date obj.
1519
if (new Date(a.timeSent) > new Date(b.timeSent)) return 1;
1620
if (new Date(a.timeSent) < new Date(b.timeSent)) return -1;
1721
return 0;
1822
});
23+
// console.log('commData (AFTER sorting):', communicationsData);
1924

20-
// Iterate over sorted communicationsData array from the end to the beginning
25+
// Iterate over sorted array to build up resObj.
2126
for (let i = 0; i < communicationsData.length; i += 1) {
2227
// declare a constant element and initialize it as the object at index i of the communicationsData array
2328
const element = communicationsData[i];
24-
// Pushes the microservice name into the object
29+
// Pushes the microservice name & timeSent into the resObj.
30+
// Data objects w/ same corrId will be grouped in a same array.
2531
if (resObj[element.correlatingId]) {
26-
resObj[element.correlatingId].push(element.currentMicroservice);
27-
} else resObj[element.correlatingId] = [element.currentMicroservice];
32+
resObj[element.correlatingId].push({
33+
microservice_name: element.currentMicroservice,
34+
timeSent: element.timeSent
35+
});
36+
} else {
37+
// The value that corresp. to the correlationId key is an array of obj containing name and time data.
38+
// Each obj is a data point.
39+
resObj[element.correlatingId] = [{
40+
microservice_name: element.currentMicroservice,
41+
timeSent: element.timeSent
42+
}];
43+
}
2844
}
2945
} else {
3046
for (let i = communicationsData.length - 1; i >= 0; i--) {
3147
const element = communicationsData[i];
32-
if (resObj[element.correlatingid]) resObj[element.correlatingid].push(element.currentmicroservice);
33-
else resObj[element.correlatingid] = [element.currentmicroservice];
48+
if (resObj[element.correlatingId]) {
49+
resObj[element.correlatingId].push({
50+
microservice_name: element.currentMicroservice,
51+
timeSent: element.timeSent
52+
});
53+
} else {
54+
// The value that corresp. to the correlationId key is an array of obj containing name and time data.
55+
// Each obj is a data point.
56+
resObj[element.correlatingId] = [{
57+
microservice_name: element.currentMicroservice,
58+
timeSent: element.timeSent
59+
}];
60+
}
3461
// initializing the object with the first microservice
3562
}
3663
}
3764

38-
// use object values to destructure locations
39-
const tracePoints = Object.values(resObj);
40-
const position = communicationsData[0].correlatingid ? 0 : tracePoints.length - 1;
65+
// use Object.values to destructure locations
66+
// Each elem in tracePoints is an array of arrays, which contain objects (each of which is a data point).
67+
// Filter the array so that only subarrays w/ len > 1 are kept.
68+
// (len == 1 means there's only one point in the route. There's no meaningful data to be gained from those.)
69+
const tracePoints = Object.values(resObj).filter(subArray => subArray.length > 1);
70+
// console.log('tracePoints arr:', tracePoints);
71+
72+
73+
// Construct an obj that stores data necessary for calculating avg speed of requests btw 2 pts.
74+
const avgDataObj = {};
75+
/****** Build the object here w/ nested loops ************/
76+
/****** WARNING: tracePoints arr can be very long (100+) ************/
77+
for (let i = 0; i < tracePoints.length; i += 1) {
78+
let subArr = tracePoints[i];
79+
for (let j = 0; j < subArr.length; j += 1) {
80+
let currDataObj = subArr[j];
81+
if (j < subArr.length - 1) {
82+
let nextDataObj = subArr[j + 1];
83+
let routeName = `${currDataObj.microservice_name}-${nextDataObj.microservice_name}`;
84+
// Key/value pair that keeps COUNT of two-point routes
85+
if (!avgDataObj[`${routeName}Count`]) avgDataObj[`${routeName}Count`] = 1;
86+
else avgDataObj[`${routeName}Count`] += 1;
87+
88+
// Key/value that accumulates TOTAL TIME a req travels btw 2 certain points
89+
let timeDiff = new Date(nextDataObj.timeSent) - new Date(currDataObj.timeSent);
90+
if (!avgDataObj[`${routeName}TotalTime`]) {
91+
avgDataObj[`${routeName}TotalTime`] = timeDiff;
92+
}
93+
else avgDataObj[`${routeName}TotalTime`] += timeDiff;
94+
95+
// Key/value that calculates AVG TIME of travel (dividing the 2 values above)
96+
let avgTime = avgDataObj[`${routeName}TotalTime`] / avgDataObj[`${routeName}Count`];
97+
avgDataObj[`${routeName}AvgTime`] = avgTime;
98+
}
99+
}
100+
}
101+
/** End of nested loops */
102+
console.log('avgDataObj:', avgDataObj);
103+
/****************************************/
41104

105+
// Array of <divs> to be rendered. Each <div> contains route name and time difference.
42106
const resArray = [];
43107

44-
// iterate over Trace Points
108+
const position = communicationsData[0].correlatingid ? 0 : tracePoints.length - 1;
109+
console.log('position for tracePoints:', position);
110+
111+
// iterate over ONE elem in tracePoints, creating a <div> for every data obj.
45112
for (let i = 0; i < tracePoints[position].length; i += 1) {
46-
// push into resulting array current tracepoint as div
47-
resArray.push(
48-
<div className="RouteCircle" key={i}>
49-
<p id="routeText">Point {i + 1}: {tracePoints[position][i]}</p>
50-
</div>,
51-
);
113+
if (i !== tracePoints[position].length - 1) {
114+
// Calc time difference (when not at the end of array):
115+
// Convert time str to Date obj w/ new Date(), then get the time difference.
116+
const timeDiff = new Date(tracePoints[position][i + 1].timeSent) - new Date(tracePoints[position][i].timeSent);
117+
resArray.push(
118+
<div className="RouteCircle" key={i}>
119+
{/* Altering this <p> so it displays only microsvc_name */}
120+
<p id="routeText">
121+
Point {i + 1}: {tracePoints[position][i].microservice_name}
122+
</p>
123+
{/* Adding another <p> that displays time difference btw curr obj and next obj */}
124+
<p id="routeTimeDiff">
125+
{/* Time: {tracePoints[position][i].timeSent} */}
126+
Time elapsed: {timeDiff} ms
127+
</p>
128+
</div>,
129+
);
130+
} else {
131+
// If at the end of array, don't push the timeDiff <p> to resArray (only push a <p> w/ name).
132+
resArray.push(
133+
<div className="RouteCircle" key={i}>
134+
<p id="routeText">
135+
Point {i + 1}: {tracePoints[position][i].microservice_name}
136+
</p>
137+
</div>,
138+
);
139+
}
52140
}
141+
// console.log('resArray: ', resArray);
142+
143+
/**** Making a list of avg speed-related data. ********/
144+
// const avgData = [];
145+
// Object.entries(avgDataObj).forEach((el, i) => {
146+
// avgData.push(
147+
// <span className="avgDataDetails" key={`${i}+${el[0]}`}>
148+
// {el[0]}: {el[1]}
149+
// </span>
150+
// )
151+
// })
152+
// console.log('avgData (array):', avgData);
53153

54-
console.log('resArray: ', resArray);
154+
/**** Making CATEGORIZED lists of avg speed-related data. ********/
155+
const avgTime = [], totalTime = [], count = [];
156+
let i = 0; // For unique keys for each <span> //
55157

158+
for (const key in avgDataObj) {
159+
i += 1;
160+
161+
if (key.endsWith('AvgTime')) {
162+
avgTime.push(
163+
<span className="avgDataDetails" key={i}>
164+
{key.slice(0, -7)}: {avgDataObj[key]} ms
165+
</span>
166+
)
167+
}
168+
if (key.endsWith('TotalTime')) {
169+
totalTime.push(
170+
<span className="avgDataDetails" key={i}>
171+
{key.slice(0, -9)}: {avgDataObj[key]} ms
172+
</span>
173+
)
174+
}
175+
if (key.endsWith('Count')) {
176+
count.push(
177+
<span className="avgDataDetails" key={i}>
178+
{key.slice(0, -5)}: {avgDataObj[key]}
179+
</span>
180+
)
181+
}
182+
}
183+
// console.log('avgTime:', avgTime);
184+
// console.log('totalTime:', totalTime);
185+
// console.log('count:', count);
186+
/****************/
56187

57-
// return div with Trace Points data
58188
return (
59-
<div>
189+
<div id="routeDataArea">
190+
{/* Data on the lastest route */}
60191
{resArray}
192+
193+
{/* Rendering avg-speed related data */}
194+
<div id="avgData">
195+
{/* {avgData} */}
196+
<span className="avgData-titles">Average time between points:</span>
197+
{avgTime}
198+
<span className="avgData-titles">Total time between points:</span>
199+
{totalTime}
200+
<span className="avgData-titles">Number of trips between points:</span>
201+
{count}
202+
</div>
61203
</div>
62204
);
63205
};

app/components/ServiceOverview.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ const ServiceOverview = (props) => {
2626
// IPC listener responsible for retrieving infomation from asynchronous main process message.
2727
ipcRenderer.on('overviewResponse', (event, data) => {
2828
// Adds to state and context.
29-
console.log(JSON.parse(data));
29+
// console.log(JSON.parse(data));
3030
setOverviewState(Object.values(JSON.parse(data)));
3131
serviceComponents.overviewData = JSON.parse(data);
3232
});
3333
}, []);
3434

35-
console.log('overviewstate: ', overviewState);
35+
// console.log('overviewstate: ', overviewState);
3636
// Add routes to the display
3737
// Hook used to toggle whether or not the Modal component renders
3838
const [modalDisplay, toggleModalDisplay] = useState(false);

app/index.css

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,32 @@ select {
423423
margin-right: 10px;
424424
}
425425

426+
/*** 3.0 changes ****/
427+
#routeDataArea {
428+
display: flex;
429+
flex-direction: column;
430+
align-items: center;
431+
}
432+
#avgData {
433+
display: flex;
434+
flex-direction: column;
435+
height: 25em;
436+
width: 30em;
437+
overflow: scroll;
438+
overflow-x: hidden;
439+
}
440+
.avgData-titles {
441+
font-size: 1.5em;
442+
}
443+
.avgDataDetails {
444+
color: rgb(97, 97, 97);
445+
width: 29em;
446+
}
447+
.avgDataDetails:hover {
448+
color: white;
449+
text-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
450+
}
451+
/*********************/
426452

427453
.RouteCircle {
428454
font-family: Arial, Helvetica, sans-serif;
@@ -431,26 +457,31 @@ select {
431457
height: 4em;
432458
text-align: center;
433459
border-radius: 50%;
434-
display: block;
460+
/* display: block; */
461+
/*** 3.0 changes ****/
462+
display: flex;
463+
/* flex-direction: column; */
464+
/********************/
435465
margin-left: auto;
436466
margin-right: auto;
437-
margin-top: 30px;
467+
margin-top: 5px;
438468
background: rgb(244, 222, 62);
439469
background: linear-gradient(315deg, rgb(237, 225, 62) 57%, rgb(253, 229, 45) 100%);
440470
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
441471
}
442472

443-
#routeText {
473+
/*** 3.0 changes: applying same styles to time diff text ****/
474+
#routeText, #routeTimeDiff {
444475
color: rgb(97, 97, 97);
445476
width: 11.3em;
446477
margin-left: 6.8em;
447-
padding-top: 1.8em;
448478
}
449479

450-
#routeText:hover {
480+
#routeText:hover, #routeTimeDiff:hover {
451481
color: white;
452482
text-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
453483
}
484+
/**********************************/
454485

455486
form {
456487
width: 100%;

user/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"setupRequired":true,"services":["hard","coded","in"],"splash":true}
1+
{"setupRequired":false,"services":[["testing microsvcs","MongoDB","mongodb+srv://alon:[email protected]/test?retryWrites=true&w=majority"]],"splash":true}

0 commit comments

Comments
 (0)