From 1d10683a9ff3dda46f6294f3787bf2434ee5e228 Mon Sep 17 00:00:00 2001
From: Marcin Kasprowicz <kasprowicz23@gmail.com>
Date: Fri, 26 Oct 2018 17:29:27 +0200
Subject: [PATCH 1/3] Backend controls which lines are displayed

---
 .../priv/src/actions/CollectingActions.js     |  5 +++
 apps/xprof_gui/priv/src/actions/index.js      |  1 +
 .../src/components/monitoring/Graph/Graph.jsx | 12 +++----
 .../monitoring/GraphPanel/GraphPanel.jsx      |  4 +++
 .../monitoring/LineGraph/LineGraph.jsx        |  5 +--
 .../monitoring/Monitoring/Monitoring.jsx      |  4 +++
 .../priv/src/constants/ActionTypes.js         |  1 +
 .../priv/src/constants/GraphConstants.js      | 31 ++++++++++---------
 .../MonitoringContainer.jsx                   |  2 ++
 .../xprof_gui/priv/src/reducers/monitoring.js |  9 ++++++
 .../xprof_gui/priv/src/selectors/Selectors.js |  1 +
 apps/xprof_gui/priv/src/utils/ActionsUtils.js | 15 +++++++--
 12 files changed, 64 insertions(+), 26 deletions(-)

diff --git a/apps/xprof_gui/priv/src/actions/CollectingActions.js b/apps/xprof_gui/priv/src/actions/CollectingActions.js
index eef75156..61bc4c8b 100644
--- a/apps/xprof_gui/priv/src/actions/CollectingActions.js
+++ b/apps/xprof_gui/priv/src/actions/CollectingActions.js
@@ -28,6 +28,11 @@ const updateData = data => ({
   data,
 });
 
+export const addY = y => ({
+  type: types.ADD_Y,
+  y,
+});
+
 const updateCalls = calls => ({
   type: types.UPDATE_CALLS,
   calls,
diff --git a/apps/xprof_gui/priv/src/actions/index.js b/apps/xprof_gui/priv/src/actions/index.js
index bf707166..55e1f83c 100644
--- a/apps/xprof_gui/priv/src/actions/index.js
+++ b/apps/xprof_gui/priv/src/actions/index.js
@@ -5,6 +5,7 @@ export {
   getFunctionsCalls,
   setIDs,
   setSize,
+  addY,
 } from './CollectingActions';
 export {
   stopMonitoringFunction,
diff --git a/apps/xprof_gui/priv/src/components/monitoring/Graph/Graph.jsx b/apps/xprof_gui/priv/src/components/monitoring/Graph/Graph.jsx
index 1ff1a8ac..a832d2af 100644
--- a/apps/xprof_gui/priv/src/components/monitoring/Graph/Graph.jsx
+++ b/apps/xprof_gui/priv/src/components/monitoring/Graph/Graph.jsx
@@ -10,6 +10,7 @@ const defaultProps = {
 
 const propTypes = {
   dps: PropTypes.arrayOf(PropTypes.object).isRequired,
+  y: PropTypes.arrayOf(PropTypes.string).isRequired,
   type: PropTypes.string.isRequired,
   monitoredID: PropTypes.string.isRequired,
   setSize: PropTypes.func.isRequired,
@@ -17,11 +18,7 @@ const propTypes = {
 };
 
 const Graph = ({
-  dps,
-  type,
-  monitoredID,
-  setSize,
-  size,
+  dps, y, type, monitoredID, setSize, size,
 }) => {
   switch (type) {
     case GRAPH_TYPE.GRID:
@@ -31,9 +28,10 @@ const Graph = ({
           monitoredID={monitoredID}
           setSize={setSize}
           size={size}
-        />);
+        />
+      );
     case GRAPH_TYPE.LINE:
-      return <LineGraph dps={dps} />;
+      return <LineGraph dps={dps} y={y} />;
     default:
       return null;
   }
diff --git a/apps/xprof_gui/priv/src/components/monitoring/GraphPanel/GraphPanel.jsx b/apps/xprof_gui/priv/src/components/monitoring/GraphPanel/GraphPanel.jsx
index f4175399..1e8b648c 100644
--- a/apps/xprof_gui/priv/src/components/monitoring/GraphPanel/GraphPanel.jsx
+++ b/apps/xprof_gui/priv/src/components/monitoring/GraphPanel/GraphPanel.jsx
@@ -5,6 +5,7 @@ import { GRAPH_INITIAL_SIZE } from '../../../constants';
 
 const defaultProps = {
   dps: [],
+  y: [],
   callees: [],
   calleesVisibility: false,
   panelVisibility: true,
@@ -18,6 +19,7 @@ const propTypes = {
     query: PropTypes.string,
   }).isRequired,
   dps: PropTypes.arrayOf(PropTypes.object),
+  y: PropTypes.arrayOf(PropTypes.string),
   stopMonitoringFunction: PropTypes.func.isRequired,
   callees: PropTypes.arrayOf(PropTypes.string),
   calleesVisibility: PropTypes.bool,
@@ -36,6 +38,7 @@ const propTypes = {
 const GraphPanel = ({
   monitored,
   dps,
+  y,
   stopMonitoringFunction,
   callees,
   calleesVisibility,
@@ -70,6 +73,7 @@ const GraphPanel = ({
         <div className="panel-body">
           <Graph
             dps={dps}
+            y={y}
             type={monitored.graph_type}
             query={monitored.query}
             monitoredID={monitoredID}
diff --git a/apps/xprof_gui/priv/src/components/monitoring/LineGraph/LineGraph.jsx b/apps/xprof_gui/priv/src/components/monitoring/LineGraph/LineGraph.jsx
index 5bdb3429..5879218d 100644
--- a/apps/xprof_gui/priv/src/components/monitoring/LineGraph/LineGraph.jsx
+++ b/apps/xprof_gui/priv/src/components/monitoring/LineGraph/LineGraph.jsx
@@ -6,12 +6,13 @@ import { AXIS, DATA, GRID, POINT, TRANSITION } from '../../../constants';
 
 const propTypes = {
   dps: PropTypes.arrayOf(PropTypes.object).isRequired,
+  y: PropTypes.arrayOf(PropTypes.string).isRequired,
 };
 
-const LineGraph = ({ dps }) => (
+const LineGraph = ({ dps, y }) => (
   <div>
     <C3Chart
-      data={{ ...DATA, json: dps }}
+      data={{ ...DATA, json: dps, keys: { ...DATA.keys, value: y } }}
       point={POINT}
       grid={GRID}
       axis={AXIS}
diff --git a/apps/xprof_gui/priv/src/components/monitoring/Monitoring/Monitoring.jsx b/apps/xprof_gui/priv/src/components/monitoring/Monitoring/Monitoring.jsx
index e00d8da8..3b3f3367 100644
--- a/apps/xprof_gui/priv/src/components/monitoring/Monitoring/Monitoring.jsx
+++ b/apps/xprof_gui/priv/src/components/monitoring/Monitoring/Monitoring.jsx
@@ -6,6 +6,7 @@ import { DATA_INTERVAL, GRAPH_INITIAL_SIZE } from '../../../constants';
 const defaultProps = {
   panelVisibility: true,
   data: [],
+  y: [],
   callees: [],
   calleesVisibility: false,
   size: GRAPH_INITIAL_SIZE,
@@ -19,6 +20,7 @@ const propTypes = {
   }).isRequired,
   getFunctionsData: PropTypes.func.isRequired,
   data: PropTypes.arrayOf(PropTypes.object),
+  y: PropTypes.arrayOf(PropTypes.string),
   stopMonitoringFunction: PropTypes.func.isRequired,
   callees: PropTypes.arrayOf(PropTypes.string),
   calleesVisibility: PropTypes.bool,
@@ -50,6 +52,7 @@ class Monitoring extends React.Component {
     const {
       monitored,
       data,
+      y,
       stopMonitoringFunction,
       callees,
       calleesVisibility,
@@ -70,6 +73,7 @@ class Monitoring extends React.Component {
           key={monitored.query}
           monitored={monitored}
           dps={data}
+          y={y}
           stopMonitoringFunction={stopMonitoringFunction}
           callees={callees}
           calleesVisibility={calleesVisibility}
diff --git a/apps/xprof_gui/priv/src/constants/ActionTypes.js b/apps/xprof_gui/priv/src/constants/ActionTypes.js
index 4c80ae50..922036ff 100644
--- a/apps/xprof_gui/priv/src/constants/ActionTypes.js
+++ b/apps/xprof_gui/priv/src/constants/ActionTypes.js
@@ -19,6 +19,7 @@ export const SAVE_DIRTY_INPUT = 'SAVE_DIRTY_INPUT';
 // monitoring
 export const UPDATE_MONITORED_FUNCTIONS = 'UPDATE_MONITORED_FUNCTIONS';
 export const UPDATE_DATA = 'UPDATE_DATA';
+export const ADD_Y = 'ADD_Y';
 export const STOP_MONITORING_FUNCTION = 'STOP_MONITORING_FUNCTION';
 export const STOP_MONITORING_FUNCTION_ERROR = 'STOP_MONITORING_FUNCTION_ERROR';
 export const EXPAND_GRAPH_PANEL = 'EXPAND_GRAPH_PANEL';
diff --git a/apps/xprof_gui/priv/src/constants/GraphConstants.js b/apps/xprof_gui/priv/src/constants/GraphConstants.js
index dd3b6d25..5e42655d 100644
--- a/apps/xprof_gui/priv/src/constants/GraphConstants.js
+++ b/apps/xprof_gui/priv/src/constants/GraphConstants.js
@@ -19,24 +19,25 @@ export const DATA = {
   json: [],
   keys: {
     x: COLUMNS.time,
-    value: [
-      COLUMNS.min,
-      COLUMNS.mean,
-      // COLUMNS.median,
-      COLUMNS.max,
-      // COLUMNS.stddev,
-      // COLUMNS.p25,
-      COLUMNS.p50,
-      COLUMNS.p75,
-      COLUMNS.p90,
-      COLUMNS.p99,
-      // COLUMNS.memsize,
-      COLUMNS.count,
-    ],
+    // value: [
+    //   COLUMNS.min,
+    //   COLUMNS.mean,
+    //   // COLUMNS.median,
+    //   COLUMNS.max,
+    //   // COLUMNS.stddev,
+    //   // COLUMNS.p25,
+    //   COLUMNS.p50,
+    //   COLUMNS.p75,
+    //   COLUMNS.p90,
+    //   COLUMNS.p99,
+    //   // COLUMNS.memsize,
+    //   COLUMNS.count,
+    // ],
   },
   hide: [COLUMNS.max, COLUMNS.p90, COLUMNS.p75, COLUMNS.p50],
   axes: {
     count: 'y2',
+    memsize: 'y2',
   },
   names: {
     count: 'count',
@@ -102,7 +103,7 @@ export const AXIS = {
     show: true,
     min: 0,
     padding: { bottom: 2 },
-    label: { text: 'Call count', position: 'outer-middle' },
+    label: { position: 'outer-middle' },
     tick: {
       outer: false,
     },
diff --git a/apps/xprof_gui/priv/src/containers/MonitoringContainer/MonitoringContainer.jsx b/apps/xprof_gui/priv/src/containers/MonitoringContainer/MonitoringContainer.jsx
index fca70a32..9720b211 100644
--- a/apps/xprof_gui/priv/src/containers/MonitoringContainer/MonitoringContainer.jsx
+++ b/apps/xprof_gui/priv/src/containers/MonitoringContainer/MonitoringContainer.jsx
@@ -20,6 +20,7 @@ import {
   isConnection,
   getSize,
   getIDs,
+  getFunctionY,
 } from '../../selectors';
 
 const MonitoringContainer = props => <Monitoring {...props} />;
@@ -27,6 +28,7 @@ const MonitoringContainer = props => <Monitoring {...props} />;
 const mapStateToProps = (state, ownProps) => ({
   monitored: ownProps.monitored,
   data: getFunctionData(state, ownProps.monitored.query),
+  y: getFunctionY(state, ownProps.monitored.query),
   callees: getFunctionCallees(state, ownProps.monitored.query),
   calleesVisibility: getFunctionCalleesVisibility(
     state,
diff --git a/apps/xprof_gui/priv/src/reducers/monitoring.js b/apps/xprof_gui/priv/src/reducers/monitoring.js
index e3fb1231..572cb60b 100644
--- a/apps/xprof_gui/priv/src/reducers/monitoring.js
+++ b/apps/xprof_gui/priv/src/reducers/monitoring.js
@@ -3,6 +3,7 @@ import * as types from '../constants/ActionTypes';
 const initialState = {
   monitoredCollection: [],
   data: {},
+  y: {},
   panel: {},
   callees: {},
   ids: {},
@@ -43,6 +44,14 @@ const monitoring = (state = initialState, action) => {
         ...state,
         ids: action.ids,
       };
+    case types.ADD_Y:
+      return {
+        ...state,
+        y: {
+          ...state.y,
+          ...action.y,
+        },
+      };
     default:
       return state;
   }
diff --git a/apps/xprof_gui/priv/src/selectors/Selectors.js b/apps/xprof_gui/priv/src/selectors/Selectors.js
index 55549c88..127e9e34 100644
--- a/apps/xprof_gui/priv/src/selectors/Selectors.js
+++ b/apps/xprof_gui/priv/src/selectors/Selectors.js
@@ -18,6 +18,7 @@ export const getData = state => state.monitoring.data;
 export const getFunctionData = (state, fun) => state.monitoring.data[fun];
 export const getIDs = state => state.monitoring.ids;
 export const getSize = state => state.monitoring.size;
+export const getFunctionY = (state, fun) => state.monitoring.y[fun];
 
 // navigation
 export const getQuery = state => state.navigation.query;
diff --git a/apps/xprof_gui/priv/src/utils/ActionsUtils.js b/apps/xprof_gui/priv/src/utils/ActionsUtils.js
index 54a08a64..78bfa398 100644
--- a/apps/xprof_gui/priv/src/utils/ActionsUtils.js
+++ b/apps/xprof_gui/priv/src/utils/ActionsUtils.js
@@ -8,8 +8,9 @@ import {
   CALLS_COLUMNS,
   SORT,
   NOTIFICATIONS,
+  COLUMNS,
 } from '../constants';
-import { setCallsControl, addNotification } from '../actions';
+import { setCallsControl, addNotification, addY } from '../actions';
 import * as XProf from '../api';
 
 export const determineNextCallsForFun = (json, lastCalls, calls, name) => {
@@ -154,6 +155,8 @@ export const determineIncomingDps = (dps, ts) => {
   }));
 };
 
+const isFirstDps = (dps, ts) => dpsDecision(dps, ts) === DPS_ACTION.FIRST_DPS;
+
 export const determineNextData = async (
   dispatch,
   monitoredCollection,
@@ -180,7 +183,15 @@ export const determineNextData = async (
         NOTIFICATIONS.SAMPLES.MESSAGE(monitored.query),
       ));
     } else if (json.length) {
-      const incomingDpsSorted = sortBy(json, 'time');
+      const incomingDpsSorted = sortBy(json, COLUMNS.time);
+
+      if (isFirstDps(incomingDpsSorted, lastTs)) {
+        // eslint-disable-next-line
+          const y = Object.keys(incomingDpsSorted[0]).filter(
+          f => f !== COLUMNS.time);
+        dispatch(addY({ [completeFunName]: y }));
+      }
+
       const incomingDps = determineIncomingDps(incomingDpsSorted, lastTs);
       const concatenatedDps = currentDps
         ? [...currentDps, ...incomingDps]

From b2551b48265f9a45c4e4c9eed06924d2ace33180 Mon Sep 17 00:00:00 2001
From: Marcin Kasprowicz <kasprowicz23@gmail.com>
Date: Mon, 29 Oct 2018 09:54:32 +0100
Subject: [PATCH 2/3] Update unit tests

---
 .../src/components/navigation/Navbar/Navbar.spec.jsx   |  1 +
 apps/xprof_gui/priv/src/utils/ActionUtils.spec.js      | 10 +++++++---
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/apps/xprof_gui/priv/src/components/navigation/Navbar/Navbar.spec.jsx b/apps/xprof_gui/priv/src/components/navigation/Navbar/Navbar.spec.jsx
index 69c6263e..96526567 100644
--- a/apps/xprof_gui/priv/src/components/navigation/Navbar/Navbar.spec.jsx
+++ b/apps/xprof_gui/priv/src/components/navigation/Navbar/Navbar.spec.jsx
@@ -14,6 +14,7 @@ describe('Navbar component', () => {
     functionClick: jest.fn(),
     setPositionOnFunction: jest.fn(),
     isConnection: true,
+    switchGrid: jest.fn(),
   };
   it('renders', () => {
     const wrapper = shallow(<Navbar {...props} />);
diff --git a/apps/xprof_gui/priv/src/utils/ActionUtils.spec.js b/apps/xprof_gui/priv/src/utils/ActionUtils.spec.js
index ea85396a..6636433a 100644
--- a/apps/xprof_gui/priv/src/utils/ActionUtils.spec.js
+++ b/apps/xprof_gui/priv/src/utils/ActionUtils.spec.js
@@ -423,7 +423,7 @@ describe('Action utils', () => {
       };
       // when
       const result = await ActionUtils.determineNextData(
-        null,
+        dispatch,
         mockMonitoredCollection,
         data,
       );
@@ -436,7 +436,7 @@ describe('Action utils', () => {
       XProf.getFunctionsSamples.mockReturnValue({ json: [{ time: 13 }] });
       // when
       const result = await ActionUtils.determineNextData(
-        null,
+        dispatch,
         mockMonitoredCollection,
         {},
       );
@@ -448,7 +448,11 @@ describe('Action utils', () => {
       // given
       XProf.getFunctionsSamples.mockReturnValue({ json: [{ time: 13 }] });
       // when
-      await ActionUtils.determineNextData(null, mockMonitoredCollection, {});
+      await ActionUtils.determineNextData(
+        dispatch,
+        mockMonitoredCollection,
+        {},
+      );
       // then
       expect(XProf.getFunctionsSamples).toHaveBeenCalledTimes(2);
     });

From 198eec116f2ebdbb65370abf634ff94b1606ea36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A9ter=20G=C3=B6m=C3=B6ri?= <gomoripeti@gmail.com>
Date: Sat, 27 Oct 2018 07:30:35 +0200
Subject: [PATCH 3/3] Remove unused keys from latency line-graph

Also support match_rate/total_count lines (will be sent when retmatch is
implemented in the BE)
---
 apps/xprof_core/src/xprof_core_trace_handler.erl   | 10 +++++-----
 .../xprof_gui/priv/src/constants/GraphConstants.js | 14 ++++++++------
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/apps/xprof_core/src/xprof_core_trace_handler.erl b/apps/xprof_core/src/xprof_core_trace_handler.erl
index 23888a97..83e11751 100644
--- a/apps/xprof_core/src/xprof_core_trace_handler.erl
+++ b/apps/xprof_core/src/xprof_core_trace_handler.erl
@@ -224,16 +224,16 @@ get_current_hist_stats(HistRef, Time) ->
     [{time, Time},
      {min,      hdr_histogram:min(HistRef)},
      {mean,     hdr_histogram:mean(HistRef)},
-     {median,   hdr_histogram:median(HistRef)},
+     %%{median,   hdr_histogram:median(HistRef)},
      {max,      hdr_histogram:max(HistRef)},
-     {stddev,   hdr_histogram:stddev(HistRef)},
-     {p25,      hdr_histogram:percentile(HistRef,25.0)},
+     %%{stddev,   hdr_histogram:stddev(HistRef)},
+     %%{p25,      hdr_histogram:percentile(HistRef,25.0)},
      {p50,      hdr_histogram:percentile(HistRef,50.0)},
      {p75,      hdr_histogram:percentile(HistRef,75.0)},
      {p90,      hdr_histogram:percentile(HistRef,90.0)},
      {p99,      hdr_histogram:percentile(HistRef,99.0)},
-     {p9999999, hdr_histogram:percentile(HistRef,99.9999)},
-     {memsize,  hdr_histogram:get_memory_size(HistRef)},
+     %%{p9999999, hdr_histogram:percentile(HistRef,99.9999)},
+     %%{memsize,  hdr_histogram:get_memory_size(HistRef)},
      {count,    hdr_histogram:get_total_count(HistRef)}].
 
 remove_outdated_snapshots(Name, TS) ->
diff --git a/apps/xprof_gui/priv/src/constants/GraphConstants.js b/apps/xprof_gui/priv/src/constants/GraphConstants.js
index 5e42655d..2d9b0c4a 100644
--- a/apps/xprof_gui/priv/src/constants/GraphConstants.js
+++ b/apps/xprof_gui/priv/src/constants/GraphConstants.js
@@ -3,6 +3,8 @@ import { format } from 'd3';
 export const COLUMNS = {
   time: 'time',
   count: 'count',
+  total_count: 'total_count',
+  match_rate: 'match_rate',
   max: 'max',
   p99: 'p99',
   p90: 'p90',
@@ -34,10 +36,12 @@ export const DATA = {
     //   COLUMNS.count,
     // ],
   },
-  hide: [COLUMNS.max, COLUMNS.p90, COLUMNS.p75, COLUMNS.p50],
+  hide: [COLUMNS.max, COLUMNS.p90, COLUMNS.p75, COLUMNS.p50,
+    COLUMNS.total_count, COLUMNS.match_rate],
   axes: {
     count: 'y2',
-    memsize: 'y2',
+    total_count: 'y2',
+    match_rate: 'y2',
   },
   names: {
     count: 'count',
@@ -49,12 +53,10 @@ export const DATA = {
     p25: '25th perc',
     mean: 'mean',
     min: 'min',
-    median: 'median',
-    memsize: 'memsize',
-    stddev: 'stddev',
   },
   colors: {
     count: '#98FB98',
+    total_count: '44AA44',
     max: '#8C2A04',
     p99: '#E24806',
     p90: '#E24806',
@@ -103,7 +105,7 @@ export const AXIS = {
     show: true,
     min: 0,
     padding: { bottom: 2 },
-    label: { position: 'outer-middle' },
+    label: { text: 'Call count / Match rate %', position: 'outer-middle' },
     tick: {
       outer: false,
     },