diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 4f54e519..d19af006 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,10 +1,12 @@ -import React, { FC, useEffect, useState, Component } from 'react'; +import React, { FC, useEffect, useState } from 'react'; import Store from './Interfaces/Store' import { inject, observer } from 'mobx-react'; import Dashboard from './Dashboard'; -import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom' +import { BrowserRouter, Switch, Route } from 'react-router-dom' +import { timeFormat } from 'd3'; import Login from './LogIn' +import Preview from './Preview'; interface OwnProps { store?: Store; @@ -13,19 +15,99 @@ interface OwnProps { type Props = OwnProps; const App: FC = ({ store }: Props) => { - const { isLoggedIn } = store! + const { isLoggedIn, previewMode } = store! + const [hemoData, setHemoData] = useState([]) + + + async function cacheHemoData() { + const resHemo = await fetch("http://localhost:8000/api/hemoglobin"); + const dataHemo = await resHemo.json(); + const resultHemo = dataHemo.result; + const resTrans = await fetch(`http://localhost:8000/api/request_transfused_units?transfusion_type=ALL_UNITS&date_range=${[timeFormat("%d-%b-%Y")(new Date(2014, 0, 1)), timeFormat("%d-%b-%Y")(new Date(2019, 11, 31))]}`) + const dataTrans = await resTrans.json(); + let transfused_dict = {} as any; + + let result: { + CASE_ID: number, + VISIT_ID: number, + PATIENT_ID: number, + ANESTHOLOGIST_ID: number, + SURGEON_ID: number, + YEAR: number, + QUARTER: string, + MONTH: string, + DATE: Date | null, + PRBC_UNITS: number, + FFP_UNITS: number, + PLT_UNITS: number, + CRYO_UNITS: number, + CELL_SAVER_ML: number, + HEMO: number[] + }[] = []; + + + dataTrans.forEach((element: any) => { + transfused_dict[element.case_id] = { + PRBC_UNITS: element.transfused_units[0] || 0, + FFP_UNITS: element.transfused_units[1] || 0, + PLT_UNITS: element.transfused_units[2] || 0, + CRYO_UNITS: element.transfused_units[3] || 0, + CELL_SAVER_ML: element.transfused_units[4] || 0 + }; + }); + + resultHemo.map((ob: any, index: number) => { + if (transfused_dict[ob.CASE_ID]) { + const transfusedResult = transfused_dict[ob.CASE_ID]; + result.push({ + CASE_ID: ob.CASE_ID, + VISIT_ID: ob.VISIT_ID, + PATIENT_ID: ob.PATIENT_ID, + ANESTHOLOGIST_ID: ob.ANESTHOLOGIST_ID, + SURGEON_ID: ob.SURGEON_ID, + YEAR: ob.YEAR, + PRBC_UNITS: transfusedResult.PRBC_UNITS, + FFP_UNITS: transfusedResult.FFP_UNITS, + PLT_UNITS: transfusedResult.PLT_UNITS, + CRYO_UNITS: transfusedResult.CRYO_UNITS, + CELL_SAVER_ML: transfusedResult.CELL_SAVER_ML, + HEMO: ob.HEMO, + QUARTER: ob.QUARTER, + MONTH: ob.MONTH, + DATE: ob.DATE + }) + } + }) + + result = result.filter((d: any) => d); + console.log("hemo data done") + setHemoData(result) + store!.loadingModalOpen = false; + + } + + useEffect(() => { + cacheHemoData(); + }, []); return ( {/* */} - + { // if (isLoggedIn) return // else return - return + if (previewMode) { + return + } + else { + return + } }} /> + + // diff --git a/frontend/src/Components/Utilities/SideBar.tsx b/frontend/src/Components/Utilities/SideBar.tsx index 1de71fe0..3a8fdbef 100644 --- a/frontend/src/Components/Utilities/SideBar.tsx +++ b/frontend/src/Components/Utilities/SideBar.tsx @@ -23,7 +23,6 @@ const SideBar: FC = ({ store }: Props) => { currentSelectSet, currentOutputFilterSet, currentSelectPatientGroup, - currentSelectPatient, filterSelection } = store!; const [procedureList, setProcedureList] = useState([]); const [maxCaseCount, setMaxCaseCount] = useState(0); @@ -37,7 +36,6 @@ const SideBar: FC = ({ store }: Props) => { const data = await res.json(); const result = data.result - //TODO this needs to check if the filterSelection is not empty let tempMaxCaseCount = 0; let tempItemUnselected: any[] = []; diff --git a/frontend/src/Components/Utilities/UserControl.tsx b/frontend/src/Components/Utilities/UserControl.tsx index 8fb67c6b..3868ad28 100644 --- a/frontend/src/Components/Utilities/UserControl.tsx +++ b/frontend/src/Components/Utilities/UserControl.tsx @@ -13,7 +13,7 @@ import { interventionChartType, presetOptions, stateUpdateWrapperUseJSON, dumbbellValueOptions, scatterYOptions, typeDiction } from "../../PresetsProfile"; import ClipboardJS from 'clipboard'; -import { NavLink } from 'react-router-dom' +import { NavLink, Redirect } from 'react-router-dom' import { getCookie } from "../../Interfaces/UserManagement"; interface OwnProps { store?: Store; @@ -140,7 +140,7 @@ const UserControl: FC = ({ store }: Props) => { const regularMenu = ( - + ); diff --git a/frontend/src/Dashboard.tsx b/frontend/src/Dashboard.tsx index bef6a7b3..1957fdf1 100644 --- a/frontend/src/Dashboard.tsx +++ b/frontend/src/Dashboard.tsx @@ -1,272 +1,99 @@ import React, { FC, useState, useEffect } from 'react'; import { inject, observer } from 'mobx-react'; import Store from './Interfaces/Store'; -import { LayoutElement } from './Interfaces/ApplicationState'; -import { Button, Tab, Grid, GridColumn, Container, Modal, Message, Icon } from 'semantic-ui-react'; -import { actions } from '.'; -import DumbbellChartVisualization from './Components/DumbbellChart/DumbbellChartVisualization'; -import BarChartVisualization from './Components/BarChart/BarChartVisualization'; -import ScatterPlotVisualization from './Components/Scatterplot/ScatterPlotVisualization'; -import HeatMapVisualization from './Components/HeatMapChart/HeatMapVisualization'; -import InterventionPlotVisualization from './Components/InterventionPlot/InterventionPlotVisualization'; -import DetailView from './Components/Utilities/DetailView'; -import LineUpWrapper from './Components/LineUpWrapper'; -import PatientComparisonWrapper from './Components/PatientComparisonWrapper'; +import { Grid, Container, Modal, Message, Icon } from 'semantic-ui-react'; import UserControl from './Components/Utilities/UserControl'; import SideBar from './Components/Utilities/SideBar'; import styled from 'styled-components'; -import { Responsive, WidthProvider } from "react-grid-layout"; import './App.css' -import 'react-grid-layout/css/styles.css' +//import 'react-grid-layout/css/styles.css' +import LayoutGenerator from './LayoutGenerator'; + interface OwnProps { store?: Store + hemoData: any } type Props = OwnProps; -const Dashboard: FC = ({ store }: Props) => { - - const { layoutArray, dateRange } = store!; - - const [hemoData, setHemoData] = useState([]) - - const [loadingModalOpen, setloadingModalOpen] = useState(true) - - async function cacheHemoData() { - const resHemo = await fetch("http://localhost:8000/api/hemoglobin"); - const dataHemo = await resHemo.json(); - const resultHemo = dataHemo.result; - const resTrans = await fetch(`http://localhost:8000/api/request_transfused_units?transfusion_type=ALL_UNITS&date_range=${dateRange}`) - const dataTrans = await resTrans.json(); - let transfused_dict = {} as any; - - let result: { - CASE_ID: number, - VISIT_ID: number, - PATIENT_ID: number, - ANESTHOLOGIST_ID: number, - SURGEON_ID: number, - YEAR: number, - QUARTER: string, - MONTH: string, - DATE: Date | null, - PRBC_UNITS: number, - FFP_UNITS: number, - PLT_UNITS: number, - CRYO_UNITS: number, - CELL_SAVER_ML: number, - HEMO: number[] - }[] = []; - - - dataTrans.forEach((element: any) => { - transfused_dict[element.case_id] = { - PRBC_UNITS: element.transfused_units[0] || 0, - FFP_UNITS: element.transfused_units[1] || 0, - PLT_UNITS: element.transfused_units[2] || 0, - CRYO_UNITS: element.transfused_units[3] || 0, - CELL_SAVER_ML: element.transfused_units[4] || 0 - }; - }); - - resultHemo.map((ob: any, index: number) => { - if (transfused_dict[ob.CASE_ID]) { - const transfusedResult = transfused_dict[ob.CASE_ID]; - result.push({ - CASE_ID: ob.CASE_ID, - VISIT_ID: ob.VISIT_ID, - PATIENT_ID: ob.PATIENT_ID, - ANESTHOLOGIST_ID: ob.ANESTHOLOGIST_ID, - SURGEON_ID: ob.SURGEON_ID, - YEAR: ob.YEAR, - PRBC_UNITS: transfusedResult.PRBC_UNITS, - FFP_UNITS: transfusedResult.FFP_UNITS, - PLT_UNITS: transfusedResult.PLT_UNITS, - CRYO_UNITS: transfusedResult.CRYO_UNITS, - CELL_SAVER_ML: transfusedResult.CELL_SAVER_ML, - HEMO: ob.HEMO, - QUARTER: ob.QUARTER, - MONTH: ob.MONTH, - DATE: ob.DATE - }) - } - }) - - result = result.filter((d: any) => d); - console.log("hemo data done") - setHemoData(result) - setloadingModalOpen(false) - - } - - useEffect(() => { - cacheHemoData(); - }, []); - - - const createElement = (layout: LayoutElement, index: number) => { - switch (layout.plot_type) { - case "DUMBBELL": - return ( -
- -
- ); - case "VIOLIN": - return ( -
- -
- ); - case "SCATTER": - return (
- -
); - - case "HEATMAP": - return (
- -
); - - case "INTERVENTION": - return (
-
); - - } - - } - - const colData = { - lg: 2, - md: 2, - sm: 2, - xs: 2, - xxs: 2 - }; - - const generateGrid = () => { - let output = layoutArray.map(d => ({ w: d.w, h: d.h, x: d.x, y: d.y, i: d.i })) - const newStuff = output.map(d => ({ ...d })) - return newStuff - } - - const panes = [{ - menuItem: 'Main', pane: - - - - {layoutArray.map((layoutE, i) => { - return createElement(layoutE, i); - })} - - - - - - - - }, - { - menuItem: 'LineUp', pane: - -
-
- }, { - menuItem: 'Selected Patients', - pane: - - +const Dashboard: FC = ({ hemoData, store }: Props) => { + + const { loadingModalOpen } = store!; + // const [hemoData, setHemoData] = useState([]) + + // const [loadingModalOpen, setloadingModalOpen] = useState(true) + + // async function cacheHemoData() { + // const resHemo = await fetch("http://localhost:8000/api/hemoglobin"); + // const dataHemo = await resHemo.json(); + // const resultHemo = dataHemo.result; + // const resTrans = await fetch(`http://localhost:8000/api/request_transfused_units?transfusion_type=ALL_UNITS&date_range=${[timeFormat("%d-%b-%Y")(new Date(2014, 0, 1)), timeFormat("%d-%b-%Y")(new Date(2019, 11, 31))]}`) + // const dataTrans = await resTrans.json(); + // let transfused_dict = {} as any; + + // let result: { + // CASE_ID: number, + // VISIT_ID: number, + // PATIENT_ID: number, + // ANESTHOLOGIST_ID: number, + // SURGEON_ID: number, + // YEAR: number, + // QUARTER: string, + // MONTH: string, + // DATE: Date | null, + // PRBC_UNITS: number, + // FFP_UNITS: number, + // PLT_UNITS: number, + // CRYO_UNITS: number, + // CELL_SAVER_ML: number, + // HEMO: number[] + // }[] = []; + + + // dataTrans.forEach((element: any) => { + // transfused_dict[element.case_id] = { + // PRBC_UNITS: element.transfused_units[0] || 0, + // FFP_UNITS: element.transfused_units[1] || 0, + // PLT_UNITS: element.transfused_units[2] || 0, + // CRYO_UNITS: element.transfused_units[3] || 0, + // CELL_SAVER_ML: element.transfused_units[4] || 0 + // }; + // }); + + // resultHemo.map((ob: any, index: number) => { + // if (transfused_dict[ob.CASE_ID]) { + // const transfusedResult = transfused_dict[ob.CASE_ID]; + // result.push({ + // CASE_ID: ob.CASE_ID, + // VISIT_ID: ob.VISIT_ID, + // PATIENT_ID: ob.PATIENT_ID, + // ANESTHOLOGIST_ID: ob.ANESTHOLOGIST_ID, + // SURGEON_ID: ob.SURGEON_ID, + // YEAR: ob.YEAR, + // PRBC_UNITS: transfusedResult.PRBC_UNITS, + // FFP_UNITS: transfusedResult.FFP_UNITS, + // PLT_UNITS: transfusedResult.PLT_UNITS, + // CRYO_UNITS: transfusedResult.CRYO_UNITS, + // CELL_SAVER_ML: transfusedResult.CELL_SAVER_ML, + // HEMO: ob.HEMO, + // QUARTER: ob.QUARTER, + // MONTH: ob.MONTH, + // DATE: ob.DATE + // }) + // } + // }) + + // result = result.filter((d: any) => d); + // console.log("hemo data done") + // setHemoData(result) + // setloadingModalOpen(false) + + // } + + // useEffect(() => { + // cacheHemoData(); + // }, []); - - }] return ( @@ -278,9 +105,7 @@ const Dashboard: FC = ({ store }: Props) => { - + diff --git a/frontend/src/Interfaces/Store.ts b/frontend/src/Interfaces/Store.ts index 07c593f9..db4403b4 100644 --- a/frontend/src/Interfaces/Store.ts +++ b/frontend/src/Interfaces/Store.ts @@ -44,6 +44,8 @@ export default class Store { @observable currentSelectPatientGroup: number[] = defaultState.currentSelectPatientGroup; @observable isLoggedIn: boolean = false; + @observable previewMode: boolean = false; + @observable loadingModalOpen: boolean = true; // @observable csrftoken: string | null = "" } diff --git a/frontend/src/LayoutGenerator.tsx b/frontend/src/LayoutGenerator.tsx new file mode 100644 index 00000000..1e851f5c --- /dev/null +++ b/frontend/src/LayoutGenerator.tsx @@ -0,0 +1,201 @@ +import React, { + FC +} from "react"; +import { inject, observer } from "mobx-react"; +import { Tab, Grid, GridColumn, Button } from "semantic-ui-react"; +import { actions } from "."; +import DetailView from "./Components/Utilities/DetailView"; +import LineUpWrapper from "./Components/LineUpWrapper"; +import PatientComparisonWrapper from "./Components/PatientComparisonWrapper"; +import Store from "./Interfaces/Store"; +import { LayoutElement } from "./Interfaces/ApplicationState"; +import DumbbellChartVisualization from "./Components/DumbbellChart/DumbbellChartVisualization"; +import BarChartVisualization from "./Components/BarChart/BarChartVisualization"; +import ScatterPlotVisualization from "./Components/Scatterplot/ScatterPlotVisualization"; +import HeatMapVisualization from "./Components/HeatMapChart/HeatMapVisualization"; +import InterventionPlotVisualization from "./Components/InterventionPlot/InterventionPlotVisualization"; +import { Responsive, WidthProvider } from "react-grid-layout"; +import 'react-grid-layout/css/styles.css' +interface OwnProps { + hemoData: any; + store?: Store +} + + + +export type Props = OwnProps; + + + +const LayoutGenerator: FC = ({ hemoData, store }: Props) => { + const { layoutArray } = store! + + const createElement = (layout: LayoutElement, index: number) => { + console.log(layout) + switch (layout.plot_type) { + case "DUMBBELL": + return ( +
+ +
+ ); + case "VIOLIN": + return ( +
+ +
+ ); + case "SCATTER": + return (
+ +
); + + case "HEATMAP": + return (
+ +
); + + case "INTERVENTION": + return (
+
); + + } + + } + + const colData = { + lg: 2, + md: 2, + sm: 2, + xs: 2, + xxs: 2 + }; + const generateGrid = () => { + let output = layoutArray.map(d => ({ w: d.w, h: d.h, x: d.x, y: d.y, i: d.i })) + const newStuff = output.map(d => ({ ...d })) + return newStuff + } + const panes = [{ + menuItem: 'Main', pane: + + + + {layoutArray.map((layoutE, i) => { + return createElement(layoutE, i); + })} + + + + + + + + }, + { + menuItem: 'LineUp', pane: + +
+
+ }, { + menuItem: 'Selected Patients', + pane: + + + + + }] + return +} + + +export default inject("store")(observer(LayoutGenerator)); \ No newline at end of file diff --git a/frontend/src/Preview.tsx b/frontend/src/Preview.tsx new file mode 100644 index 00000000..88033f52 --- /dev/null +++ b/frontend/src/Preview.tsx @@ -0,0 +1,161 @@ +import React, { FC, useState, useEffect } from 'react'; +import { inject, observer } from 'mobx-react'; +import Store from './Interfaces/Store'; +import { Button, Grid, Container, Modal, Message, Icon, Menu, Checkbox } from 'semantic-ui-react'; +import { actions, provenance } from '.'; + +import SideBar from './Components/Utilities/SideBar'; +import styled from 'styled-components'; + +import './App.css' +//import 'react-grid-layout/css/styles.css' +import { NavLink } from 'react-router-dom'; +import LayoutGenerator from './LayoutGenerator'; +import { timeFormat } from 'd3'; + +interface OwnProps { + store?: Store + hemoData: any + +} +type Props = OwnProps; + +const Preview: FC = ({ store, hemoData }: Props) => { + + const { showZero, loadingModalOpen } = store!; + + // const [hemoData, setHemoData] = useState([]) + + // const [loadingModalOpen, setloadingModalOpen] = useState(true) + + + + // async function cacheHemoData() { + // const resHemo = await fetch("http://localhost:8000/api/hemoglobin"); + // const dataHemo = await resHemo.json(); + // const resultHemo = dataHemo.result; + // const resTrans = await fetch(`http://localhost:8000/api/request_transfused_units?transfusion_type=ALL_UNITS&date_range=${[timeFormat("%d-%b-%Y")(new Date(2014, 0, 1)), timeFormat("%d-%b-%Y")(new Date(2019, 11, 31))]}`) + // const dataTrans = await resTrans.json(); + // let transfused_dict = {} as any; + + // let result: { + // CASE_ID: number, + // VISIT_ID: number, + // PATIENT_ID: number, + // ANESTHOLOGIST_ID: number, + // SURGEON_ID: number, + // YEAR: number, + // QUARTER: string, + // MONTH: string, + // DATE: Date | null, + // PRBC_UNITS: number, + // FFP_UNITS: number, + // PLT_UNITS: number, + // CRYO_UNITS: number, + // CELL_SAVER_ML: number, + // HEMO: number[] + // }[] = []; + + + // dataTrans.forEach((element: any) => { + // transfused_dict[element.case_id] = { + // PRBC_UNITS: element.transfused_units[0] || 0, + // FFP_UNITS: element.transfused_units[1] || 0, + // PLT_UNITS: element.transfused_units[2] || 0, + // CRYO_UNITS: element.transfused_units[3] || 0, + // CELL_SAVER_ML: element.transfused_units[4] || 0 + // }; + // }); + + // resultHemo.map((ob: any, index: number) => { + // if (transfused_dict[ob.CASE_ID]) { + // const transfusedResult = transfused_dict[ob.CASE_ID]; + // result.push({ + // CASE_ID: ob.CASE_ID, + // VISIT_ID: ob.VISIT_ID, + // PATIENT_ID: ob.PATIENT_ID, + // ANESTHOLOGIST_ID: ob.ANESTHOLOGIST_ID, + // SURGEON_ID: ob.SURGEON_ID, + // YEAR: ob.YEAR, + // PRBC_UNITS: transfusedResult.PRBC_UNITS, + // FFP_UNITS: transfusedResult.FFP_UNITS, + // PLT_UNITS: transfusedResult.PLT_UNITS, + // CRYO_UNITS: transfusedResult.CRYO_UNITS, + // CELL_SAVER_ML: transfusedResult.CELL_SAVER_ML, + // HEMO: ob.HEMO, + // QUARTER: ob.QUARTER, + // MONTH: ob.MONTH, + // DATE: ob.DATE + // }) + // } + // }) + + // result = result.filter((d: any) => d); + // console.log("hemo data done") + // setHemoData(result) + // setloadingModalOpen(false) + // } + + // useEffect(() => { + // cacheHemoData(); + // }, []); + + return ( + + + + + Show Zero Transfused } + /> + + + {/* + Customize Mode + */} + + + + + + + + + + + + + + + + Just one second + We are fetching required data. + + + + + + + ); + +} + +export default inject('store')(observer(Preview)) +const LayoutDiv = styled.div` + width: 100vw; + height: 100vh; +`; + +const SpecialPaddingColumn = styled(Grid.Column)` + &&&&&{padding-left:5px;} +`; \ No newline at end of file