Commit ebab9cee authored by Francis Renaud's avatar Francis Renaud
Browse files

Fixed instabilities

parent 06639339
Loading
Loading
Loading
Loading
+39 −90
Original line number Diff line number Diff line
import _ from 'lodash';
import { connect } from 'react-redux';
import React, { Component, useState }  from 'react';
import React, { Component }  from 'react';

import { Grid, GridCell, GridInner } from '@rmwc/grid';
import { Grid, GridCell } from '@rmwc/grid';
import { Elevation } from '@rmwc/elevation';
import { Graph } from 'react-d3-graph';
import ReactDOM from 'react-dom';
// import ReactDOM from 'react-dom';
import { Button } from '@rmwc/button';
import { Checkbox } from '@rmwc/checkbox';
import { TextField, TextFieldHelperText } from '@rmwc/textfield';
import moment from 'moment';
import * as d3 from 'd3';
import axios from 'axios';

// import IDCAreaChart from './idc-area-chart';
import IDCLineChart from './idc-line-chart';
import IDCGraph from './idc-graph';
import IDCAppsView from './idc-apps-view';
import IDSelect from '../components/helper-components/id-select';

import {
  idlog
} from '../util/functional';

import {
  getScenarioNodeChildren,
  isApp
} from '../util/scenario-utils';

import {
  isDataPointOfType,
  valueOfPoint
  isDataPointOfType
} from '../util/metrics';

import {
@@ -42,15 +41,15 @@ import {
} from '../meep-constants';

const VIEW_NAME_NONE = 'none';
const TIME_FORMAT = moment.HTML5_FMT.DATETIME_LOCAL_MS;

function colorArray(dataLength) {
  const colorScale = d3.interpolateInferno;
  // Other possible color scales:
  // const colorScale = d3.interpolateMagma;
  // const colorScale = d3.interpolateCool;
  // const colorScale = d3.interpolateWarm;
  // const colorScale = d3.interpolateCubehelixDefault;
  // interpolateViridis
  // const colorScale = d3.interpolateCubehelixDefault;
  
  let colorArray = [];

@@ -68,34 +67,6 @@ function colorArray(dataLength) {

const metricsBasePath = 'http://10.3.16.73:30008/v1';

// const dataPointFromEpochDataPoints = destinations => sourceNodeId => dataAccessor => epochDataPoints => {
//   if (!epochDataPoints.length) {
//     return null;
//   }
//   let dp = {
//     date: epochDataPoints[0].timestamp
//   };

//   const avgForDest = dataPoints => acc => dest => {
//     const hasSource = src => p => p.src === src;
//     const hasDestination = dest => p => p.dest === dest;
    
//     const dataPointsForDestSource = dataPoints
//       .filter(hasSource(sourceNodeId))
//       .filter(hasDestination(dest));
//     const avg = d3.mean(dataPointsForDestSource, acc);
//     return avg;
//   };
  
//   destinations.forEach(dest => {
//     dp[dest] = avgForDest(epochDataPoints)(dataAccessor)(dest) || 0;
//   });

//   return dp;
// };

const notNull = x => x;

const buildSeriesFromEpoch = (series, epoch) => {
  epoch.data.forEach(p => {
    if (! series[p.dest]) {
@@ -125,7 +96,6 @@ const ConfigurationView = (props) => {
          onChange={(e) => {
            props.changeView1(e.target.value);
          }}
          // disabled={props.disabled}
          value={props.view1}
        />
      </GridCell>
@@ -137,7 +107,6 @@ const ConfigurationView = (props) => {
          onChange={(e) => {
            props.changeView2(e.target.value);
          }}
          // disabled={props.disabled}
          value={props.view1}
        />
      </GridCell>
@@ -149,7 +118,6 @@ const ConfigurationView = (props) => {
          onChange={(e) => {
            props.changeSourceNodeSelected(e.target.value);
          }}
          // disabled={props.disabled}
          value={props.sourceNodeSelected ? props.sourceNodeSelected.data.id : ''}
        />
      </GridCell>
@@ -167,7 +135,6 @@ const ConfigurationView = (props) => {
  );
};

const DATA_CONFIGURATION = 'DATA_CONFIGURATION';
const MAIN_CONFIGURATION = 'MAIN_CONFIGURATION';

const buttonStyles = {
@@ -186,7 +153,6 @@ const ViewForName = (
    apps,
    colorRange,
    width,
    height,
    min,
    max,
    data,
@@ -228,7 +194,6 @@ const ViewForName = (
        selectedSource={selectedSource}
        colorForApp={colorForApp}
        onNodeClicked={(e) => {
          console.log('Node clicked is: ', e.node);
          changeSourceNodeSelected(e.node);
        }}
        displayEdgeLabels={displayEdgeLabels}
@@ -246,8 +211,6 @@ const ViewForName = (
        colorRange={colorRange}
        selectedSource={selectedSource}
        dataType={dataType}
        // Specify units
        // Specify label
        min={min}
        max={max}
        colorForApp={colorForApp}
@@ -265,8 +228,6 @@ const ViewForName = (
        colorRange={colorRange}
        selectedSource={selectedSource}
        dataType={dataType}
        // Specify units
        // Specify label
        min={min}
        max={max}
        colorForApp={colorForApp}
@@ -314,9 +275,10 @@ const DashboardConfiguration = (props) => {
    )
    : null;

  const backgroundColor = 'ffffff'; // props.configurationType ? '#e4e4e4' : 'ffffff';
  return (
    <div style={{border: '1px solid #e4e4e4', padding: 10, marginBottom: 10, backgroundColor: backgroundColor}}>
    <Elevation z={2}
      style={{padding: 10, marginBottom: 10}}
    >
      <Grid>
        <GridCell span={10}>
        </GridCell>
@@ -325,9 +287,9 @@ const DashboardConfiguration = (props) => {
          {buttonClose}
        </GridCell>
      </Grid>

      {configurationView}
    </div>
    </Elevation>
     
  );
};

@@ -383,20 +345,19 @@ class DashboardContainer extends Component {
  }

  fetchMetrics() {
    const startTime = moment().add(-7, 'seconds').format(moment.HTML5_FMT.DATETIME_LOCAL_MS);
    const stopTime = moment().add(-6, 'seconds').format(moment.HTML5_FMT.DATETIME_LOCAL_MS);
    // const now = moment().format(moment.HTML5_FMT.DATETIME_LOCAL_MS);
    const startTime = moment().utc().add(-7, 'seconds').format(TIME_FORMAT);
    const stopTime = moment().utc().add(-6, 'seconds').format(TIME_FORMAT);
    return axios.get(`${metricsBasePath}/metrics?startTime=${startTime}&stopTime=${stopTime}`)
      .then(res => {

        let epoch = {
          data: res.data.logResponse || [], //.sort((a, b) => new Date(a).getTime() - new Date(b).getTime() || []),
          data: res.data.logResponse || [],
          startTime: startTime
        };
  
        this.props.addMetricsEpoch(epoch);
      }).catch((e) => {
        console.log('Error while fetching metrics', e);
        idlog('Error while fetching metrics')(e);
      });
  }

@@ -428,13 +389,9 @@ class DashboardContainer extends Component {
    const appIds = apps.map(a => a.data.id);
    const appMap = apps.reduce((acc, app) => {acc[app.data.id] = app; return acc;}, {});
    const colorRange = colorArray(appIds.length);
    const nbEpochs = 25;

    const selectedSource = this.props.sourceNodeSelected ? this.props.sourceNodeSelected.data.id : null;

    const showApps = this.props.showAppsView;
    const span = showApps ? 6 : 12;

    const colorForApp = apps.reduce((res, val, i) => {
      return {...res, [val.data.id]: colorRange[i]};
    }, {});
@@ -464,7 +421,7 @@ class DashboardContainer extends Component {
 
    // Determine startTime of first epoch and endTime of last epoch
    const startTime = firstEpoch.data.length ? firstEpoch.startTime : null;
    const endTime = lastEpoch.data.length ? new Date(new Date(lastEpoch.startTime).getTime() + 1000).toString() : null;
    const endTime = lastEpoch.data.length ? moment(lastEpoch.startTime).add(1, 'seconds').format(TIME_FORMAT) : null;
    const series = epochsToSeries(this.props.epochs, selectedSource);

    const withTypeAndSource = type => source => point => {
@@ -475,8 +432,6 @@ class DashboardContainer extends Component {
    const view1DataType = dataTypeForView(this.state.view1Name);
    const series1 =  filterSeries(appIds)(withTypeAndSource(view1DataType)(selectedSource))(series);
    const lastEpochData1 = lastEpoch.data.filter(isDataOfType(view1DataType));
    // const max1 = d3.max(data1, p => p.value);
    // const min1 = d3.min(data1, p => p.value);

    // For view2
    const view2DataType = dataTypeForView(this.state.view2Name);
@@ -489,31 +444,25 @@ class DashboardContainer extends Component {
    const mobilityEvents = this.props.epochs.flatMap(extractMobilityEvents);

    if (mobilityEvents.length) {
      console.log('Some mobility events ...');
      // console.log('Some mobility events ...');
    }
  
    // const max2 = d3.max(data2, view2Accessor);
    // const min2 = d3.min(data2, view2Accessor);
    
    const width = 700;
    const height = 600;

    let span1 = 6;
    let width1 = 700;
    let span2 = 6;
    let width2 = 700;

    if (this.state.view1Name === VIEW_NAME_NONE) {
      span1 = 0;
      width1 = 0;
      span2 = 12;
      width2 = 1200;
      width2 = 1400;
    }

    if (this.state.view2Name === VIEW_NAME_NONE) {
      span1 = 12;
      width1 = 1200;
      span2 = 0;
      width1 = 1400;
      width2 = 0;
    }

@@ -528,9 +477,6 @@ class DashboardContainer extends Component {
        startTime={startTime}
        endTime={endTime}
        mobilityEvents={mobilityEvents}
        // min={min1}
        // max={max1}
        // dataAccessor={view1Accessor}
        dataType={view1DataType}
        selectedSource={selectedSource}
        colorForApp={colorForApp}
@@ -551,9 +497,6 @@ class DashboardContainer extends Component {
        startTime={startTime}
        endTime={endTime}
        mobilityEvents={mobilityEvents}
        // min={min2}
        // max={max2}
        // dataAccessor={view2Accessor}
        dataType={view2DataType}
        selectedSource={selectedSource}
        colorForApp={colorForApp}
@@ -566,9 +509,7 @@ class DashboardContainer extends Component {

    return (
      <>
      <Elevation z={4}
        style={{padding: 10}}
      >
      
        <DashboardConfiguration
          configurationType={this.state.configurationType}
          displayConfiguration={
@@ -587,15 +528,23 @@ class DashboardContainer extends Component {
        />
        
        <Grid>
          <GridCell span={span1} style={{marginLeft: -10}}>
          
          <GridCell span={span1} style={{paddingRight: 10}}>
            <Elevation z={2}
              style={{padding: 10}}
            >
              {view1}
            </Elevation>
          </GridCell>
          
          <GridCell span={span2} style={{marginLeft: -10}}>
          <GridCell span={span1} style={{marginLeft: -10, paddingLeft: 10}}>
            <Elevation z={2}
              style={{padding: 10}}
            >
              {view2}
            </Elevation>
          </GridCell>
        </Grid>
      </Elevation>
      
      </>
    );
+17 −19
Original line number Diff line number Diff line
@@ -12,8 +12,6 @@ import React, { Component } from 'react';
import { Grid, GridCell, GridInner } from '@rmwc/grid';
import { Elevation } from '@rmwc/elevation';
import IDCVis from '../idc-vis';
import IDCGraph from '../idc-graph';
import IDCAreaChart from '../idc-area-chart';
import DashboardContainer from '../dashboard-container';
import ExecPageScenarioButtons from './exec-page-scenario-buttons';

@@ -268,7 +266,7 @@ class ExecPageContainer extends Component {
              <Grid style={{width: '100%'}}>
                <GridCell span={spanLeft}>
                  {/* <Elevation className="component-style" z={2}> */}
                      <div style={{padding: 10}}>
                  <div>
                    {this.props.experimental ? (<DashboardContainer showAppsView={true}/>) : (<IDCVis type={TYPE_EXEC} />)}
                        
                  </div>
+3 −85
Original line number Diff line number Diff line
@@ -7,9 +7,8 @@
 * information of InterDigital Communications, Inc.
 */
import _ from 'lodash';
import { connect } from 'react-redux';
import React, { useState }  from 'react';
import ReactDOM from 'react-dom';
import React from 'react';
// import ReactDOM from 'react-dom';
import * as d3 from 'd3';

import IDCNode from './idc-node.js';
@@ -46,79 +45,6 @@ const edgesFromData = (data, colorForApp, selectedSource) => {
    const destinations = Object.keys(m[src]);

    const edgesFromDestinations = (dest) => {
      // To debug
      const dataFromPing = p => {
        if (p.value) {
          console.log('Bad value!');  
        }
        return p.value;
      };

      if (!d3.mean(rowObject[dest].pings, p => p.value)) {
        console.log('Bad value!');
      }
      return  {
        src: src,
        dest: dest,
        count: rowObject[dest].pings.length,
        color: colorForApp[dest],
        avgData: d3.mean(rowObject[dest].pings, p => p.value)
      };
    };
    return _.map(destinations, edgesFromDestinations);
  };

  const outwardEdgesIfSourceSelected = e => {
    if (selectedSource) {
      return e.src === selectedSource;
    } else {
      return true;
    }
  };
  const edges = _.flatMap(apps.map(edgesFromSource)).filter(outwardEdgesIfSourceSelected);

  return edges; 
};

const edgesFromSeries = (series, colorForApp, selectedSource) => {
  const pings = data;
  let m = {};
  _.each(pings, p => {
    if (!m[p.src]) {
      m[p.src] = {};
    }
 
    if (!m[p.src][p.dest]) {
      m[p.src][p.dest] = {
        pings: []
      };
    }
 
    const o = m[p.src][p.dest];
    o.pings.push(p);
  });

  const apps = Object.keys(m);
 
  const edgesFromSource = src => {
    const rowObject = m[src];
    if (!rowObject) {
      return [];
    }
    const destinations = Object.keys(m[src]);

    const edgesFromDestinations = (dest) => {
      // To debug
      const dataFromPing = p => {
        if (p.value) {
          console.log('Bad value!');  
        }
        return p.value;
      };

      if (!d3.mean(rowObject[dest].pings, p => p.value)) {
        console.log('Bad value!');
      }
      return  {
        src: src,
        dest: dest,
@@ -142,7 +68,6 @@ const edgesFromSeries = (series, colorForApp, selectedSource) => {
  return edges; 
};


const positionAppsCircle = ({apps, width, height}) => {
  const cx = width/2.0;
  const cy = height/2.0;
@@ -184,7 +109,6 @@ const IDCAppsView = (
    colorRange,
    selectedSource,
    data,
    series,
    dataType,
    width,
    height,
@@ -194,13 +118,7 @@ const IDCAppsView = (
  }
) => {

  const [positioningNeeded, setPositioningNeeded] = useState(true);

  //if (positioningNeeded) {
  // copyAttributesRecursive(data)(this.root);
  positionAppsCircle({apps: apps, height: height, width: width});
  //setPositioningNeeded(false);
  //}

  const appsMap = {};
  _.each(apps, a => appsMap[a.data.id] = a);
@@ -241,7 +159,7 @@ const IDCAppsView = (
        xlinkHref={`#textPathDef${i}`}
        startOffset={'45%'}
      >
        {displayEdgeLabels ? `${edgeLabel} ${e.avgData.toFixed(2)} ${edgeUnits}` : null}
        {displayEdgeLabels ? `${edgeLabel} ${e.avgData.toFixed(0)} ${edgeUnits}` : null}
      </textPath>
    </text>
  );
+14 −31
Original line number Diff line number Diff line
@@ -7,19 +7,8 @@
 * information of InterDigital Communications, Inc.
 */

import _ from 'lodash';
import { connect } from 'react-redux';
import React, { useRef, useEffect }  from 'react';
import ReactDOM from 'react-dom';
import moment from 'moment';
import * as d3 from 'd3';
import uuid from 'uuid';
import { uiChangeCurrentDialog } from '../state/ui';
import { execFakeChangeSelectedDestination } from '../state/exec';

let colorRange = [];



const IDCAreaChart = props => {
  const d3Container = useRef(null);
@@ -47,11 +36,6 @@ const IDCAreaChart = props => {
        const colorRange = props.colorRange;
        const strokecolor = colorRange[0];

        // Scale functions
        // console.log(`min: ${props.min} max: ${props.max}`);

        const amplitude = colorRange.length * (props.max - props.min);
        // const yRange = [-0.5*amplitude, 0.5*amplitude];
        const yRange = [0, 400];
        const timeRange = d3.extent(data, d => new Date(d.date));
        const x = d3.scaleTime().domain(timeRange).range([0, width]);
@@ -65,7 +49,7 @@ const IDCAreaChart = props => {
        // const yAxisr = d3.axisLeft(y);

        const keys = props.sources;
        const stack = d3.stack().keys(keys);//.offset(d3.stackOffsetSilhouette);//.order(d3.stackOrderInsideOut);
        const stack = d3.stack().keys(keys);

        const area = d3.area()
          .x( (d, i) => x(data[i].date))
@@ -147,7 +131,6 @@ const IDCAreaChart = props => {
              .attr('stroke-width', '0.5px');

            d3.select(node).classed('selected', !selected);
            const newSelectedValue = d3.select(node).classed('selected');
            const newSelection = keys[i];
            onKeySelected(newSelection);
          });
+2 −16
Original line number Diff line number Diff line
@@ -9,17 +9,12 @@
import _ from 'lodash';
import { connect } from 'react-redux';
import React, { Component }  from 'react';
import { Graph } from 'react-d3-graph';
import ReactDOM from 'react-dom';
import * as d3 from 'd3';

import IDCNode from './idc-node.js';

import {
  plusGenerator,
  minusGenerator,
  lineGeneratorNodes,
  lineGeneratorReverse,
  visitNodes,
  blue
} from './graph-utils';
@@ -40,7 +35,7 @@ import { cfgChangeTable, cfgChangeVis, cfgElemEdit } from '../state/cfg';

import {
  FIELD_NAME,
  getElemFieldVal,
  getElemFieldVal
  
} from '../util/elem-utils';

@@ -99,14 +94,6 @@ const createEdgesToChildren = array => node => {

const nodeVisible = n => !n.hidden;





const IDCHierarchy = (props) => {

};

class IDCGraph extends Component {

  constructor(props) {
@@ -136,7 +123,6 @@ class IDCGraph extends Component {
    const newPing = (date, i, bucketCount) => {
      const srcIdx = srcNodeIndex();
      const destIdx = destNodeIndex(srcIdx);
      const delay = Math.random() + 0.2;

      const amplitude = 0.2*(destIdx % 3)*(destIdx%5) + 1;
      const frequency = 0.3*(destIdx % 3)*(destIdx%5) + 1;
@@ -430,7 +416,7 @@ class IDCGraph extends Component {
          xlinkHref={`#textPathDef${i}`}
          startOffset={'45%'}
        >
          {`Avg lat: ${e.avgLatency.toFixed(2)} ms`}
          {`Avg lat: ${e.avgLatency.toFixed(0)} ms`}
          
        </textPath>
      </text>
Loading