<repo_name>mjclements/BrainEx-UI<file_sep>/BrainEx/brainex/server.js
//Add packages
var express = require('express');
var app = express();
var multer = require('multer');
var cors = require('cors');

//cors configuration
app.use(cors({
    origin: ['http://localhost:3000'],
    credentials: true
}));
//app.use(express.static(__dirname + "/public"));

//add files uploaded to the UI into a folder named PreprocessedDataFiles with original file name
var storage = multer.diskStorage({
      destination: function (req, file, cb) {
      cb(null, 'PreprocessedDataFiles')
    },
    filename: function (req, file, cb) {
      cb(null, Date.now() + '-' +file.originalname )
    }
});

//upload multiple files at once
var upload = multer({ storage: storage }).array('file');

app.get('/',function(req,res){

    res.render(__dirname + '/public/index.html')

});

app.post('/upload',function(req, res) {
    console.log(req.body);

    //upload files and send error messages to console if any
    upload(req, res, function (err) {
           if (err instanceof multer.MulterError) {
               return res.status(500).json(err)
           } else if (err) {
               return res.status(500).json(err)
           }
      return res.status(200).send(req.file) //file must be the same name as the
        // "name" property in App.js for choosing a file
    })
});

//Run on specific port
app.listen(8000, function() {
    console.log('App running on port 8000');
});

<file_sep>/README.md
# BrainEx-UI
This project aims to develop a user-interface for BrainEx using HCI practices to enable fNIRS researchers to explore and analyze large datasets. The target users were identified through interviews with lab staff and developing user personas. Through iterative design, prototypes of increasing complexity and detail were designed, evaluated, and refined to satisfy user needs while fulfilling system requirements. The final user-interface developed from these design specifications and initial implementation will reflect all user feedback while accomplishing the tool’s main goal.

# Demo
Here is a demo video of the initial framework and functionality of BrainEx:
![](BrainEx-DemoVideo.gif)

# Tutorial

1. Clone or download the project 
2. Open the project in the Pycharm IDE
3. Open the terminal and run the command: **npm install** to install all the project modules and dependencies
   * To run the application in Pycharm, open two terminals. One for running the frontend and one for running the backend. Make sure you are in the “brainex” folder (the command is: cd brainex)
     * Starting frontend command: **npm start**
       * After running the frontend, the message in the terminal will say “Compiled successfully. Server is now running on localhost:3000”
     * Starting backend command: **node server.js**
       * After running the backend, the message in the terminal will say “App is running on port 8000”
4. Once the application automatically opens up on the website (“localhost:3000”), you will see the homepage of BrainEx
5. To upload an already preprocessed dataset, click on “Choose File” and select multiple CSV files. You can also choose a single CSV file. Note that if you try to choose any other file type, it will not work and you will encounter an error. 
   * You will see that the “No file chosen” will change to the name of the file you chose
6. After choosing the file, click on “Add”
7. Once you do this, go to the project directory and under the folder named “PreprocessedDataFiles”, you will see that the files that you chose from your local directory will be added to the server of the website
8. To start preprocessing a new dataset, click on the button named “Preprocess a new dataset”
9. You can then click on the navigation buttons in the rest of the screens labeled as “back”, “next”, etc to get from one screen to another


# Project Directory
* BrainEx-V1 
  * The “test_db” folder is the database for BrainEx built from [this project](https://github.com/ApocalyVec/Genex)
  * “ItalyPower.csv” contains an example of the fNIRS time series sequences 
  * “Test.py” is the file to run through BrainEx as the command line tool. Use this script to copy and paste sections of the code into the python console and go through the database functionalities 

  * brainex - folder where all the frontend code is stored and the directory to be in in order to run the BrainEx application
    * “Node_modules” are the node modules and project dependencies that are used by the project. This is added by typing the command: npm install in the terminal
    * “PreprocessedDataFiles” is the folder that contains all the user file uploads from the homepage
    * The “public” folder contains index.html. Index.html links to index.js (and it’s stylesheet called index.css) which is linked to App.js
    * “Server.js” contains the express server code and the logic to do the file uploading functionality
    * “Src” is the main folder with all the ReactJs code
      * App.js is the main file of the application that executes the homepage as well as all the routers and navigation pages in the site. App.css is this file’s stylesheet
      * The BrainEx image logo is located here
      * The “components” folder has the rendering of all the other pages in the application. If a new page needs to be created, create and name the page in this folder, go to App.js, and create a Router link to the page you are creating. 
<file_sep>/BrainEx/brainex/src/Components/BuildOptions.js
import React from "react";
import './BuildOptions.css';
import {Link} from "react-router-dom";
import 'bootstrap/dist/css/bootstrap.min.css';
import Button from 'react-bootstrap/Button';
import Container from 'react-bootstrap/Container';
import logo from "../brain.png";


const buildOptions = () => (
        <Container className="container" style={{flex: 1, flexDirection: 'row', justifyContent: 'flex-start', width: '100%' }}>
            <div style={{backgroundColor: '#3C99DC', width: '100%', height: '17%', position: 'absolute', left:'0.01%', top:'0%'}}>
                <img src={logo} className="App-logo" alt="logo"/>
                <h1 className="App-title">BrainEx</h1>
                <h3 className="App-Version">Version 1.0.0</h3>
                <h4 className="options">Preprocessing Options</h4>
            </div>

            <label htmlFor="dropdown" style={{position:'absolute', left:'45%', top:'22%'}}>Distance Type</label>
            <div className="dropdown" style={{position:'absolute', left:'41.5%', top:'27%'}}>
                <button className="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton"
                        data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    Choose a Distance
                </button>
                <div className="dropdown-menu" aria-labelledby="dropdownMenuButton">
                    <a className="dropdown-item" href=" ">Warped Euclidean</a>
                    <a className="dropdown-item" href=" ">Warped Manhattan</a>
                    <a className="dropdown-item" href=" ">Warped Minkowski</a>
                    <a className="dropdown-item" href=" ">Warped Chebyshev</a>
                </div>
            </div>

            <Button className="distHelp" style={{position:'absolute', left:'75%', top:'28%', borderColor: 'black', backgroundColor:'#0F5298'}}>?</Button>

            <form>
                <div className="form-group" style={{width: '40%', position:'absolute', left:'30%', top:'42%'}}>
                    <label htmlFor="formControlRange">Similarity Threshold</label>
                    <input type="range" className="form-control-range" id="formControlRange"/>
                </div>
            </form>

            <Button className="simHelp" style={{position:'absolute', left:'75%', top:'43%', borderColor: 'black', backgroundColor:'#0F5298'}}>?</Button>

            <form>
                <div className="form-group" style={{width: '40%', position:'absolute', left:'30%', top:'60%'}}>
                    <label htmlFor="formControlRange">Length of Interest</label>
                    <input type="range" className="form-control-range" id="formControlRange"/>
                </div>
            </form>

            <Button className="lenHelp" style={{position:'absolute', left:'75%', top:'61%', borderColor: 'black', backgroundColor:'#0F5298'}}>?</Button>


            <Link to="/Components/BuildProgressMenu">
                <Button className="startprocess btn-primary" style={{width: '20%', borderColor: 'black', backgroundColor:'#0F5298'}}>Start Preprocessing</Button>
            </Link>

            <Container className="Box"> </Container>

            <Link to="/Components/csvViewer">
                <Button className="back btn-primary" style={{width: '12%', borderColor: 'black', backgroundColor:'#0F5298'}}>Back</Button>
            </Link>

        </Container>
    );


export default buildOptions;<file_sep>/BrainEx/brainex/src/App.js
import React, { Component } from 'react';
import logo from './brain.png';
import './App.css';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import axios from 'axios';

import 'bootstrap/dist/css/bootstrap.min.css';
import Button from 'react-bootstrap/Button';
import Container from 'react-bootstrap/Container';
import Card from 'react-bootstrap/Card';

import csvViewer from './Components/csvViewer';
import BuildOptions from "./Components/BuildOptions";
import buildProgressMenu from "./Components/BuildProgressMenu";
import explorerPage from "./Components/ExplorerPages";
import queryFinder from "./Components/QueryFinder";

// function App() {
//   return (
//     <div className="App">
//       <header className="App-header">
//         <img src={logo} className="App-logo" alt="logo" />
//         <p>
//           Edit <code>src/App.js</code> and save to reload.
//         </p>
//         <a
//           className="App-link"
//           href="https://reactjs.org"
//           target="_blank"
//           rel="noopener noreferrer"
//         >
//           Learn React
//         </a>
//       </header>
//     </div>
//   );
// }

// const MainMenu = () => {
//   return (
//     <div>
//       <Link to="/">
//         <button>home</button>
//       </Link>
//       <Link to="/about">
//         <button>About</button>
//       </Link>
//       <Link to="/code">
//         <button>code</button>
//       </Link>
//       <Link to="/contact">
//         <button>contact</button>
//       </Link>
//       <Link to="/info">
//         <button>info</button>
//       </Link>
//     </div>
//   );
// };

    //rendering the Homepage
    const Home = () => (


        <Container className="container">

            {/*top navbar with BrainEx logo*/}
            <div style={{backgroundColor: '#3C99DC', width: '100%', height: '17%', position: 'absolute', left:'0.01%', top:'0%'}}>
                <img src={logo} className="App-logo" alt="logo"/>
                {/*<MainMenu/>*/}
                <h1 className="App-title">BrainEx</h1>
                <h3 className="App-Version">Version 1.0.0</h3>
                <h4 className="homepage">Homepage</h4>
                <Button className="Help" style={{backgroundColor: '#3C99DC', color:'#000000', borderColor: '#3C99DC'}}><u>Need Help?</u></Button>
            </div>

            <div style={{width: '40%', position: 'absolute', left:'47%', top:'30%'}}>
                <h5 align="center">The tool that helps find the top similar matches in fNIRS time series sequences</h5>
            </div>


            <Link to="/Components/csvViewer">
                <Button className="preprocess" style={{borderColor:'#000000', backgroundColor:'#0F5298'}}>Preprocess a new dataset</Button>
            </Link>

            {/* Container for files that have been uploaded to the server*/}
            <Container className="csvFileInfo" style={{ flex: 1, flexDirection: 'row', justifyContent: 'flex-start', width: '31%'}}>

                <div className="col-sm-4">
                    <div className="well">
                        <Card style={{backgroundColor: '#3C99DC', width: '328%', position: 'absolute', left:'-14%'}}>
                            <div className="card-body">
                                <h5 className="card-title">Start with an existing preprocessed dataset:</h5>
                                <div className="scrollable" style={{overflowY: 'auto', maxHeight: '210px'}}>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>SART1</Button>
                                    <p> </p>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>SART2</Button>
                                    <p> </p>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>SART3</Button>
                                    <p> </p>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>SART4</Button>
                                    <p> </p>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>SART5</Button>
                                    <p> </p>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>SART6</Button>
                                </div>
                            </div>
                        </Card>
                    </div>
                </div>
            </Container>

        </Container>


    );

    //handles the choose file button functionailty to select a file
    class App extends Component {
        onChangeHandler=event=>{
            var files = event.target.files;
            if(this.checkMimeType(event)) {
                this.setState({
                    selectedFile: files
                })
            }
        };

        //handles the "Add" button functionality to add selected file to the server
        onClickHandler = () => {
            const data = new FormData();
            for(var i=0; i<this.state.selectedFile.length; i++) {
                data.append('file', this.state.selectedFile[i]);
            }
            console.log(data);
            axios.post("http://localhost:8000/upload", data, {//parameter endpoint url, form data
            }).then(res => { //print response status
                console.log(res.statusText)
            })
        };

        checkMimeType=(event)=>{
          //get the file object
          let files = event.target.files;

            //define message container
          let err = '';

         const types = ['text/csv']; //file types allowed

          for(var i = 0; i<files.length; i++) {
                // compare file types and see if it matches
               if (types.every(type => files[i].type !== type)) {

                   err += files[i].type+' is not a supported format\n'; // error message if file types don't match

               }
           }

         if (err !== '') {
              event.target.value = null; // remove selected file
              console.log(err);
               return false;
          }
         return true;

        };

        constructor(props) {
            super(props);
            this.state = {
            selectedFile: null
            }
        }


      render() {
        return (

            /* Router to start homepage*/
          <Router>
            <div className="App">
              <div>
                <Route exact path="/" component={Home} />

                {/* Functionality for choosing files to upload to the server*/}
                <div className="form-group files front" style={{ width: '30%', position: 'absolute', top:'320pt', left:'1%'}}>
                    <h5 align="center">Load another </h5>
                    <h5 align="center">preprocessed dataset:</h5>
                    <input type="file" name="file" className="form-control" multiple onChange={this.onChangeHandler} style={{width:'77%',backgroundColor: '#3C99DC', borderColor:'#3C99DC'}}/>
                    <div className="chooseFile">
                        Choose File
                        <input type="file" className="hide_file"/>
                    </div>
                    <Button className="addfile btn-primary" style={{ width: '18%', position: 'absolute', top:'48pt', left:'75%', borderColor:'#000000', backgroundColor:'#0F5298'}} onClick={this.onClickHandler}>Add</Button>
                </div>

                {/* Routers for page navigation*/}
                <Route exact path="/Components/csvViewer" component={csvViewer} />
                <Route exact path="/Components/BuildOptions" component={BuildOptions} />
                <Route exact path="/Components/BuildProgressMenu" component={buildProgressMenu} />
                <Route exact path="/Components/ExplorerPages" component={explorerPage} />
                <Route exact path="/Components/QueryFinder" component={queryFinder} />

              </div>
            </div>
          </Router>
        )

      }
    }



export default App;
<file_sep>/BrainEx/brainex/src/Components/ExplorerPages.js
import React from "react";
import {Link} from "react-router-dom";
import 'bootstrap/dist/css/bootstrap.min.css';
import Button from 'react-bootstrap/Button';
import Container from 'react-bootstrap/Container';
import logo from "../brain.png";


const explorerPage = () => (
        <Container className="container" style={{flex: 1, flexDirection: 'row', justifyContent: 'flex-start', width: '100%' }}>
            <div style={{backgroundColor: '#3C99DC', width: '100%', height: '17%', position: 'absolute', left:'0.01%', top:'0%'}}>
                <img src={logo} className="App-logo" alt="logo"/>
                <h1 className="App-title">BrainEx</h1>
                <h3 className="App-Version">Version 1.0.0</h3>
                <h4 className="options" style={{position:'absolute', top:'39%', left:'52%'}}>Explorer Pages</h4>
            </div>


            <div className="btnContainer btn-group" role="group" style={{position:'absolute', top:'16.6%', left:'0.01%'}}>
                <Link to="/">
                    <Button type="button" className="btn btn-secondary" style={{borderColor: 'black', backgroundColor:'#0F5298'}}>Load Dataset</Button>
                </Link>

                <Link to="/Components/ExplorerPages">
                    <Button type="button" className="btn btn-secondary" style={{borderColor: 'black', backgroundColor:'#0F5298'}}>Explore Data</Button>
                </Link>

                <Link to="/Components/QueryFinder">
                    <Button type="button" className="btn btn-secondary" style={{borderColor: 'black', backgroundColor:'#0F5298'}}>Find Similar Sequences</Button>
                </Link>
            </div>

             <Container className="Box" style={{backgroundColor:'#FFFFFF', width:'18rem', height:'12rem', position:'absolute', left:'1%', top:'65%'}}> </Container>


        </Container>
    );


export default explorerPage;<file_sep>/BrainEx/brainex/src/Components/csvViewer.js
import React from "react";
import './csvViewer.css';
import {Link} from "react-router-dom";
import 'bootstrap/dist/css/bootstrap.min.css';
import Button from 'react-bootstrap/Button';
import Container from 'react-bootstrap/Container';
import logo from "../brain.png";
import Card from 'react-bootstrap/Card';


const csvViewer = () => (


        <Container className="container">
            <div style={{backgroundColor: '#3C99DC', width: '100%', height: '17%', position: 'absolute', left:'0.01%', top:'0%'}}>
                <img src={logo} className="App-logo" alt="logo"/>
                <h1 className="App-title">BrainEx</h1>
                <h3 className="App-Version">Version 1.0.0</h3>
                <h4 className="viewer">CSV Viewer</h4>
            </div>


            <Container className="csvFile" style={{ flex: 1, flexDirection: 'row', justifyContent: 'flex-start', width: '31%'}}>

                <div className="col-sm-4">
                    <div className="well">
                        <Card style={{backgroundColor: '#3C99DC', width: '328%', position: 'absolute', left:'-14%'}}>
                            <div className="card-body">
                                <h5 className="card-title">Previously imported unpreprocessed CSV Files</h5>
                                <div className="scrollable" style={{overflowY: 'auto', maxHeight: '210px'}}>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>Dataset1</Button>
                                    <p> </p>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>Dataset2</Button>
                                    <p> </p>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>Dataset3</Button>
                                    <p> </p>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>Dataset4</Button>
                                    <p> </p>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>Dataset5</Button>
                                    <p> </p>
                                    <Button style={{ borderColor: 'black', width: '100%', backgroundColor:'#0F5298'}}>Dataset6</Button>
                                </div>
                            </div>
                        </Card>
                    </div>
                </div>
            </Container>

            <Link to="/">
                <Button className="back btn-primary" style={{width: '10%', position: 'absolute', top: '90%', left: '33%', backgroundColor:'#0F5298', borderColor: 'black'}}>Back</Button>
            </Link>


            <Link to="/Components/BuildOptions">
                <Button className="nextbtn btn-primary" style={{width: '10%', position: 'absolute', top: '90%', left: '88%', backgroundColor:'#0F5298', borderColor: 'black'}}>Next</Button>
            </Link>



        </Container>
    );


export default csvViewer;