Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6f79f7b
added router for routes
emoltz-carnegie Jun 27, 2024
366e219
larger arrows for visibility
emoltz-carnegie Jun 27, 2024
433c3f1
quick bug fixes
emoltz-carnegie Jun 27, 2024
282c625
added routes to separate file for organization purposes
emoltz-carnegie Jun 27, 2024
2acb595
fixed error where .tsv files were not accepted
emoltz-carnegie Jun 27, 2024
fb7ed07
graph viz prep for Tali
emoltz-carnegie Aug 14, 2024
469a1d0
Graphviz implementation in PAT!
talizacks Aug 15, 2024
c2b471f
Graphviz implementation in PAT!
talizacks Aug 15, 2024
016751f
Added dropdown to pick sequence to color by
talizacks Aug 21, 2024
0a3b474
Sequence coloring isn't working but everything (i think) is close to …
talizacks Aug 23, 2024
c67061b
Still trying to get color to work
talizacks Aug 26, 2024
1aab228
Color working but graph not reloading upon new upload
talizacks Aug 29, 2024
6cc64f4
Everything working again except node color still won't update with se…
talizacks Aug 30, 2024
4241d12
Everything working again except node color still won't update with se…
talizacks Sep 3, 2024
81f764a
added router for routes
emoltz-carnegie Jun 27, 2024
c0d9da8
added routes to separate file for organization purposes
emoltz-carnegie Jun 27, 2024
6e15eb5
fixed error where .tsv files were not accepted
emoltz-carnegie Jun 27, 2024
e482fbc
graph viz prep for Tali
emoltz-carnegie Aug 14, 2024
62e2ad2
Graphviz implementation in PAT!
talizacks Aug 15, 2024
2493037
Added dropdown to pick sequence to color by
talizacks Aug 21, 2024
8b84d3d
Sequence coloring isn't working but everything (i think) is close to …
talizacks Aug 23, 2024
d4e1c18
Still trying to get color to work
talizacks Aug 26, 2024
da216ed
Color working but graph not reloading upon new upload
talizacks Aug 29, 2024
5e1198f
Everything working again except node color still won't update with se…
talizacks Aug 30, 2024
e069532
Everything working again except node color still won't update with se…
talizacks Sep 3, 2024
4500816
Merge remote-tracking branch 'github-desktop-talizacks/GraphVizUpdate…
emoltz-carnegie Sep 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"danfojs-node": "^1.1.2",
"express": "^4.19.2",
"html2canvas": "^1.4.1",
"graphviz-react": "^1.2.5",
"joi": "^17.13.1",
"lodash": "^4.17.21",
"lucide-react": "^0.378.0",
Expand All @@ -44,6 +45,7 @@
"react-dropzone": "^14.2.3",
"react-force-graph": "^1.44.3",
"react-hot-toast": "^2.4.1",
"react-router-dom": "^6.24.0",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
"timsort": "^0.3.0",
Expand Down
175 changes: 55 additions & 120 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,121 +1,56 @@
import './App.css';
import {useContext, useEffect, useState} from 'react';
import { GlobalDataType, GraphData } from './lib/types';
import DirectedGraph from './components/DirectedGraph';
import DropZone from './components/DropZone';
import { Button } from './components/ui/button';
import { Context } from './Context';
import { processDataShopData } from './lib/dataProcessingUtils';
import {filterPromGrad} from "@/lib/GradPromUtils";

import './Switch.css';


function App() {

const { resetData, setGraphData, setLoading,
data, setData, graphData, loading } = useContext(Context)
const [showDropZone, setShowDropZone] = useState<boolean>(true)

const handleData = (data: GlobalDataType[]) => {
setData(data)
setShowDropZone(false)
}

const handleLoading = (loading: boolean) => {
setLoading(loading)
}

const filterData = (data: GlobalDataType[], filter:"PROMOTED"|"GRADUATED"|null|string) => {
if (data){
const f = filterPromGrad(data, filter)
// setFilteredData(f)
return f
}
else {

}

}

useEffect(() => {
if (data) {
const graphData: GraphData = processDataShopData(data)
setGraphData(graphData)
}}, [data])



return (
<>
<div className="">
{/* <NavBar /> */}
<Button
className="m-2"
variant={"ghost"}
onClick={() => {
resetData()
setShowDropZone(true)
}}
>
Reset
</Button>

<div className=" flex items-center justify-center pt-20">

{
loading ?
<div
className="absolute top-0 left-0 w-full h-full bg-gray-900 bg-opacity-50 flex items-center justify-center">
<div className="bg-white p-4 rounded-lg">
<p>Loading...</p>
</div>
</div>
:
(
showDropZone && (
<div className="">
<DropZone afterDrop={handleData} onLoadingChange={handleLoading}/>
</div>
)

)

}


{
graphData && (
<>
{/* Add suspense, lazy? */}
<DirectedGraph graphData={graphData}/>
</>
)
}


{/*<div className="checkbox">*/}
{/* <label>*/}

{/* <input type="checkbox" checked={isSwitchEnabled} onChange={handleCheckboxChange}/>*/}
{/* <span class="tab"></span>Filter by Section Completion Status?*/}
{/* </label>*/}
{/* <Switch isOn={isOn} handleToggle={handleToggle} filter={filter}*/}
{/* isDisabled={!isSwitchEnabled}*/}
{/* // onChange={handleFilterChange}*/}
{/* />*/}
{/* <br></br>*/}
{/* <br></br>*/}
{/* <br></br>*/}

{/* <label>Status: {getValueBasedOnSwitch()}</label>*/}
{/*</div>*/}

</div>
</div>

</>
)
}

export default App
import React, {useContext, useState} from 'react';
import Upload from "@/components/Upload.tsx";
import GraphvizParent from "@/components/GraphvizParent.tsx";
import FilterComponent from './components/FilterComponent.tsx';
import SelfLoopSwitch from './components/selfLoopSwitch.tsx';
import Slider from './components/slider.tsx';
import SequenceSelector from "@/components/SequenceSelector.tsx";
import {Context, SequenceCount} from "@/Context.tsx";

const App: React.FC = () => {
const [csvData, setCsvData] = useState<string>('');
const [filter, setFilter] = useState<string>('');
const [selfLoops, setSelfLoops] = useState<boolean>(true);
const [minVisits, setMinVisits] = useState<number>(0);
const {top5Sequences} = useContext(Context);
const [selectedSequence, setSelectedSequence] = useState<SequenceCount["sequence"] | null>(null);

const handleSelectSequence = (selectedSequence: SequenceCount["sequence"]) => {
if (top5Sequences) {
setSelectedSequence(selectedSequence); // Fix: Use the correct parameter to update the state
console.log(`Selected sequence: ${selectedSequence}`);
//Selected sequence gets this far but doesn't update in GraphvizProcessing
}
};

const handleToggle = () => setSelfLoops(!selfLoops);
const handleSlider = (value: number) => setMinVisits(value);
const handleDataProcessed = (uploadedCsvData: string) => setCsvData(uploadedCsvData);


return (
<div>
<h1>Path Analysis Tool</h1>
<Upload onDataProcessed={handleDataProcessed}/>
<FilterComponent onFilterChange={setFilter}/>
<h2>{selectedSequence}</h2>
<SequenceSelector onSequenceSelect={handleSelectSequence} sequences={top5Sequences!}
selectedSequence={selectedSequence}/>
<SelfLoopSwitch isOn={selfLoops} handleToggle={handleToggle}/>
<Slider step={5} min={0} max={500}
value={minVisits}
onChange={handleSlider}/>

<GraphvizParent
csvData={csvData}
filter={filter}
selfLoops={selfLoops}
minVisits={minVisits}
selectedSequence={selectedSequence}
/>
</div>
);
};

export default App;
41 changes: 29 additions & 12 deletions src/Context.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,70 @@
import { createContext, useState } from 'react';
import { GlobalDataType, GraphData } from './lib/types';
import {createContext, useState} from 'react';
import {GlobalDataType, GraphData} from './lib/types';

interface ContextInterface {
data: GlobalDataType[] | null;
graphData: GraphData | null;
filteredData: GlobalDataType[] | null
setFilteredData: (filteredData: GlobalDataType[] | null) => void;
loading: boolean;
top5Sequences: SequenceCount[] | null;
selectedSequence: string[] | undefined; // string[] or SequenceCount[].sequence?
setLoading: (loading: boolean) => void;
setData: (data: GlobalDataType[] | null) => void;
setGraphData: (graphData: GraphData | null) => void;
setTop5Sequences: (top5Sequences: SequenceCount[] | null) => void;
setSelectedSequence: (selectedSequence: string[] | undefined) => void;
resetData: () => void;

}

export interface SequenceCount {
sequence: string[] | undefined;
count: number;//| null;
}

export const Context = createContext({} as ContextInterface);
const initialState = {
data: null,
filteredData: null,
graphData: null,
loading: false
loading: false,
top5Sequences: null,
selectedSequence: undefined,
}

interface ProviderProps {
children: React.ReactNode;
}
export const Provider = ({ children }: ProviderProps) => {


export const Provider = ({children}: ProviderProps) => {
const [data, setData] = useState<GlobalDataType[] | null>(initialState.data)
const [filteredData, setFilteredData] = useState<GlobalDataType[] | null>(initialState.filteredData)
const [graphData, setGraphData] = useState<GraphData | null>(initialState.graphData)
const [loading, setLoading] = useState<boolean>(initialState.loading)
const [top5Sequences, setTop5Sequences] = useState<SequenceCount[] | null>(initialState.top5Sequences)
const [selectedSequence, setSelectedSequence] = useState<SequenceCount["sequence"] | undefined>(initialState.selectedSequence);

const resetData = () => {
setData(null)
setGraphData(null)
setTop5Sequences(null)
setSelectedSequence(undefined)
console.log("Data reset");

}

return (
<Context.Provider
value={{
data,
filteredData,
graphData,
loading,
setFilteredData,
top5Sequences,
selectedSequence,
setLoading,
setData,
setGraphData,
resetData
resetData,
setTop5Sequences,
setSelectedSequence,
}}
>
{children}
Expand Down
23 changes: 23 additions & 0 deletions src/GraphvizContainer.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.graphviz-container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row; /* Change to row to align items horizontally */
width: 100%; /* Ensure the container takes full width */
position: relative;
transform: translateY(-150px);
}

.graphs {
display: flex;
flex-direction: row; /* Ensure the graphs are aligned in a row */
justify-content: space-around;
align-items: center;
/*gap: 10px;*/
width: 100%; /* Ensure the graphs container takes full width */
}

.graphs > div {
flex: 1; /* Allow the graphs to scale according to available space */
max-width: 400px; /* Set a max-width for each graph */
}
37 changes: 11 additions & 26 deletions src/Switch.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,54 +9,39 @@
height: 25px;
border-radius: 25px;
background-color: grey;
position: absolute;
position: relative;
left: 0px;
top: 35px;
top: 0px;
transition: background-color 0.2s;
}

.Promoted {
background-color: lightgreen;
.true {
background-color: #80d580;
}

.Graduated {
background-color: deepskyblue;
.false {
background-color: #b20da7;
}

.switch-handle {
width: 23px;
height: 23px;
border-radius: 50%;
background-color: white;
position: absolute;
position: relative;
top: 1px;
left: 1px;
transition: left 0.2s;
transition: left 0.1s;
}

.Promoted .switch-handle {
.true .switch-handle {
left: 26px;
}

.switch-display{ /*Not working*/
display: none;
}

.switch.disabled.switch-display{ /*Not working*/
opacity: 30;
}

.checkbox{
position: fixed;
left: 93px;
top: 50px;
}

.checkbox.toggler__label{
position: fixed;
}

.tab {
display: inline-block;
margin-left: 10px;
.switch.disabled{ /*Not working*/
visibility: hidden;
}
22 changes: 22 additions & 0 deletions src/components/Debug.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { GlobalDataType } from "@/lib/types";
import { useState } from "react";
import DropZone from "./DropZone";

export default function Debug() {
const [data, setData] = useState<GlobalDataType[]>([])
const handleData = (data: GlobalDataType[]) => {
setData(data)
console.log("Data from file: ", data);

}

const handleLoading = (loading: boolean) => {
}

return (
<>

<DropZone afterDrop={handleData} onLoadingChange={handleLoading} />
</>
)
}
Loading