Skip to content

Commit

Permalink
Post merge
Browse files Browse the repository at this point in the history
  • Loading branch information
talizacks committed Dec 9, 2024
1 parent 632e226 commit 25fa119
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 154 deletions.
310 changes: 160 additions & 150 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import './App.css';
import {useContext, useEffect, useState} from 'react';
import React, {useContext, useEffect, useState} from 'react';
import {GlobalDataType, GraphData} from './lib/types';
import DropZone from './components/DropZone';

import {Button} from './components/ui/button';
import {Context} from './Context';
import {processDataShopData} from './lib/dataProcessingUtils';
import Loading from './components/Loading';
import React, {useContext, useState} from 'react';
import Upload from "@/components/Upload.tsx";
import GraphvizParent from "@/components/GraphvizParent.tsx";
import FilterComponent from './components/FilterComponent.tsx';
Expand All @@ -23,153 +20,166 @@ function App() {
// TODO: Dropdown of students
// TODO: Most common sequence displayed without extra

const App: React.FC = () => {
// State to hold the uploaded CSV data as a string
const [csvData, setCsvData] = useState<string>('');
// State to manage the filter value for filtering the graph data
const [filter, setFilter] = useState<string>('');
// State to toggle whether self-loops (transitions back to the same node) should be included
const [selfLoops, setSelfLoops] = useState<boolean>(true);
// State to manage the minimum number of visits for displaying edges in the graph
const [minVisits, setMinVisits] = useState<number>(0);
const {resetData, setGraphData, setLoading, data, setData, loading, error, setError} = useContext(Context);
const [showDropZone, setShowDropZone] = useState<boolean>(true);
const handleData = (data: GlobalDataType[]) => {
setData(data)
setShowDropZone(false)
}

// Extracting context values from the `Context` provider
const {top5Sequences, selectedSequence, setSelectedSequence, setLoading} = useContext(Context);

/**
* Handles the selection of a sequence from the top 5 sequences.
* Updates the selected sequence in the context.
*
* @param {SequenceCount["sequence"]} selectedSequence - The selected sequence from the top 5.
*/
const handleSelectSequence = (selectedSequence: SequenceCount["sequence"]) => {
console.log("SS: ", top5Sequences);
const handleError = (errorMessage: string) => {
setError(errorMessage);
}

useEffect(() => {
if (data) {
const graphData: GraphData = processDataShopData(data)
setGraphData(graphData)

if (top5Sequences) {
// Update the selected sequence in the context
setSelectedSequence(selectedSequence);
console.log(`Selected sequence: ${selectedSequence}`);
function App() {
// State to hold the uploaded CSV data as a string
const [csvData, setCsvData] = useState<string>('');
// State to manage the filter value for filtering the graph data
const [filter, setFilter] = useState<string>('');
// State to toggle whether self-loops (transitions back to the same node) should be included
const [selfLoops, setSelfLoops] = useState<boolean>(true);
// State to manage the minimum number of visits for displaying edges in the graph
const [minVisits, setMinVisits] = useState<number>(0);
const {resetData, setGraphData, data, setData, loading, error, setError} = useContext(Context);
const [showDropZone, setShowDropZone] = useState<boolean>(true);
const handleData = (data: GlobalDataType[]) => {
setData(data)
setShowDropZone(false)
}
};

/**
* Toggles the self-loops inclusion in the graph by switching the state.
*/
const handleToggle = () => setSelfLoops(!selfLoops);

/**
* Updates the minimum visits for edges in the graph when the slider is moved.
*
* @param {number} value - The new value for minimum visits.
*/
const handleSlider = (value: number) => setMinVisits(value);

/**
* Updates the `csvData` state with the uploaded CSV data when the file is processed.
*
* @param {string} uploadedCsvData - The CSV data from the uploaded file.
*/
const handleDataProcessed = (uploadedCsvData: string) => setCsvData(uploadedCsvData);

/**
* Updates the loading state when the file upload or processing begins or ends.
*
* @param {boolean} loading - Whether the data is currently loading/processing.
*/
const handleLoadingChange = (loading: boolean) => {
setLoading(loading);
};

// Rendering the components that allow user interaction and display the graph
return (
<div>
<h1>Path Analysis Tool</h1>

{/* Upload component allows uploading and processing of CSV data */}
<Upload onDataProcessed={handleDataProcessed} onLoadingChange={handleLoadingChange}/>
<>
<div className="">
{/* <NavBar /> */}
<Button
className="m-2"
variant={"ghost"}
onClick={() => {
resetData()
setShowDropZone(true)
}}
>
Reset
</Button>
{error && (
<div className="text-red-500 p-4 m-4 bg-red-50 rounded-md">
{error.split('\n').map((errorLine, index) => (
<p key={index} className="mb-1">{errorLine}</p>
))}
</div>
)}
<div className=" flex items-center justify-center pt-20">
{
loading ?
<Loading/>
:
(

// Extracting context values from the `Context` provider
const {top5Sequences, setSelectedSequence, setLoading} = useContext(Context); //selectedSequence

/**
* Handles the selection of a sequence from the top 5 sequences.
* Updates the selected sequence in the context.
*
* @param {SequenceCount["sequence"]} selectedSequence - The selected sequence from the top 5.
*/
const handleSelectSequence = (selectedSequence: SequenceCount["sequence"]) => {
console.log("SS: ", top5Sequences);
const handleError = (errorMessage: string) => {
setError(errorMessage);
}

useEffect(() => {
if (data) {
const graphData: GraphData = processDataShopData(data)
setGraphData(graphData)

if (top5Sequences) {
// Update the selected sequence in the context
setSelectedSequence(selectedSequence);
console.log(`Selected sequence: ${selectedSequence}`);
}
}
})
;
/**
* Toggles the self-loops inclusion in the graph by switching the state.
*/
const handleToggle = () => setSelfLoops(!selfLoops);

/**
* Updates the minimum visits for edges in the graph when the slider is moved.
*
* @param {number} value - The new value for minimum visits.
*/
const handleSlider = (value: number) => setMinVisits(value);

/**
* Updates the `csvData` state with the uploaded CSV data when the file is processed.
*
* @param {string} uploadedCsvData - The CSV data from the uploaded file.
*/
const handleDataProcessed = (uploadedCsvData: string) => setCsvData(uploadedCsvData);

/**
* Updates the loading state when the file upload or processing begins or ends.
*
* @param {boolean} loading - Whether the data is currently loading/processing.
*/
const handleLoadingChange = (loading: boolean) => {
setLoading(loading);
};

// Rendering the components that allow user interaction and display the graph
return (
<div>
<h1>Path Analysis Tool</h1>

{/* Upload component allows uploading and processing of CSV data */}
<Upload onDataProcessed={handleDataProcessed} onLoadingChange={handleLoadingChange}/>

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

{/* Display Error Message */}
{error && (
<div className="text-red-500 p-4 m-4 bg-red-50 rounded-md">
{error.split('\n').map((errorLine, index) => (
<p key={index} className="mb-1">{errorLine}</p>
))}
</div>
)}

{/* Main Content */}
<div className="flex items-center justify-center pt-20">
{loading ? (
<Loading/>
) : (
showDropZone && (
<div className="">
<DropZone afterDrop={handleData} onLoadingChange={handleLoading}
onError={handleError}/>
<div>
<DropZone
afterDrop={handleData}
onLoadingChange={handleLoadingChange}
onError={handleError}
/>
</div>
)

{/* FilterComponent allows filtering the graph data */}
<FilterComponent onFilterChange={setFilter}/>

{/* Display the currently selected sequence */}
{selectedSequence && (
<h2>{selectedSequence.toString().split('->').join(' -> ')}</h2>
)}

{/* SequenceSelector allows choosing one of the top 5 sequences */}
<SequenceSelector
onSequenceSelect={handleSelectSequence}
sequences={top5Sequences!}
selectedSequence={selectedSequence}
/>

{/* SelfLoopSwitch toggles whether self-loops should be included in the graph */}
<SelfLoopSwitch isOn={selfLoops} handleToggle={handleToggle}/>

{/* Slider adjusts the minimum visits for displaying edges in the graph */}
<Slider
step={5}
min={0}
max={5000}
value={minVisits}
onChange={handleSlider}
/>

{/* GraphvizParent component generates and displays the graph based on the CSV data */}
<GraphvizParent
csvData={csvData}
filter={filter}
selfLoops={selfLoops}
minVisits={minVisits}
/>
</div>
);
};

export default App;
)}
</div>

{!loading && csvData && (
<div>
{/* FilterComponent allows filtering the graph data */}
<FilterComponent onFilterChange={setFilter}/>

{/* Display the currently selected sequence */}
{selectedSequence && (
<h2>{selectedSequence.toString().split('->').join(' -> ')}</h2>
)}

{/* SequenceSelector allows choosing one of the top 5 sequences */}
<SequenceSelector
onSequenceSelect={handleSelectSequence}
sequences={top5Sequences!}
selectedSequence={selectedSequence}
/>

{/* SelfLoopSwitch toggles whether self-loops should be included in the graph */}
<SelfLoopSwitch isOn={selfLoops} handleToggle={handleToggle}/>

{/* Slider adjusts the minimum visits for displaying edges in the graph */}
<Slider
step={5}
min={0}
max={5000}
value={minVisits}
onChange={handleSlider}
/>

{/* GraphvizParent component generates and displays the graph based on the CSV data */}
<GraphvizParent
csvData={csvData}
filter={filter}
selfLoops={selfLoops}
minVisits={minVisits}
/>
</div>
)}
</div>
</div>
);
};
}}
export default App
2 changes: 1 addition & 1 deletion src/lib/dataProcessingUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IncomingData, Node, Link, GraphData, LinkObject, NodeObject, IncomingDataRaw, GlobalDataType } from "@/lib/types";
import _ from 'lodash';
import * as Comlink from 'comlink';
// import * as Comlink from 'comlink';

// ----------------- DATA PROCESSING UTILS DataShop Data -----------------

Expand Down
4 changes: 2 additions & 2 deletions src/lib/fileWorker.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Import Comlink from CDN or local source
import {GlobalDataType} from "@/lib/types.ts";

// import * as Comlink from 'comlink';
importScripts('https://unpkg.com/comlink/dist/umd/comlink.js');

// Define the data processing logic
function parseData(text: string, delimiter: string): GlobalDataType[] | null {
function parseData(text: string, delimiter: string): string[][] | null {
// Example parsing logic
// Split the text into lines, then split each line into columns based on the delimiter
const lines = text.split('\n');
Expand Down
2 changes: 1 addition & 1 deletion src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const validation = Joi.array().items(
'Outcome': Joi.string().valid('OK', 'JIT', 'ERROR', 'INITIAL_HINT', 'HINT_LEVEL_CHANGE', 'FREEBIE_JIT').required(),

// 'Outcome': Joi.string().valid('OK', 'BUG', 'INITIAL_HINT', 'HINT_LEVEL_CHANGE', 'ERROR').required(),
}).unknown()
}).unknown());
const dataSchema = Joi.array().items(
Joi.object({
'Time': Joi.alternatives().try(
Expand Down

0 comments on commit 25fa119

Please sign in to comment.