11import './App.css' ;
2- import { useContext , useMemo , useState } from 'react' ;
2+ import { useContext , useMemo , useState , useEffect } from 'react' ;
33import { Button } from './components/ui/button' ;
44import Upload from "@/components/Upload.tsx" ;
55import GraphvizParent from "@/components/GraphvizParent.tsx" ;
@@ -13,6 +13,7 @@ import {
1313 PopoverContent ,
1414 PopoverTrigger ,
1515} from "@/components/ui/popover"
16+ import { Input } from "@/components/ui/input"
1617
1718import Loading from './components/Loading.tsx' ;
1819
@@ -24,9 +25,18 @@ function App() {
2425 // State to toggle whether self-loops (transitions back to the same node) should be included
2526 const [ selfLoops , setSelfLoops ] = useState < boolean > ( true ) ;
2627 // State to manage the minimum number of visits for displaying edges in the graph
27- const [ minVisitsPercentage , setMinVisitsPercentage ] = useState < number > ( 10 ) ;
28+ const [ minVisitsPercentage , setMinVisitsPercentage ] = useState < number > ( 0 ) ;
2829 const { resetData, loading, error, top5Sequences, setSelectedSequence, selectedSequence, csvData, setCSVData } = useContext ( Context ) ;
2930 const [ maxEdgeCount , setMaxEdgeCount ] = useState < number > ( 100 ) ; // Default value
31+ const [ maxMinEdgeCount , setMaxMinEdgeCount ] = useState < number > ( 0 ) ;
32+
33+ // Update minVisitsPercentage when maxMinEdgeCount changes
34+ useEffect ( ( ) => {
35+ if ( maxMinEdgeCount > 0 ) {
36+ const percentage = ( ( maxMinEdgeCount - 1 ) / maxEdgeCount ) * 100 ;
37+ setMinVisitsPercentage ( Math . max ( 0 , Math . min ( 100 , percentage ) ) ) ;
38+ }
39+ } , [ maxMinEdgeCount , maxEdgeCount ] ) ;
3040
3141 const showControls = useMemo ( ( ) => {
3242 return ! loading && csvData . length > 0 ;
@@ -62,6 +72,19 @@ function App() {
6272 // Calculate actual min visits from percentage
6373 const minVisits = Math . round ( ( minVisitsPercentage / 100 ) * maxEdgeCount ) ;
6474
75+ /**
76+ * Updates the minimum visits percentage when the input value changes.
77+ *
78+ * @param {string } value - The new value from the input.
79+ */
80+ const handleInputChange = ( value : string ) => {
81+ const numValue = parseInt ( value ) ;
82+ if ( ! isNaN ( numValue ) ) {
83+ const percentage = Math . min ( 100 , Math . max ( 0 , ( numValue / maxEdgeCount ) * 100 ) ) ;
84+ setMinVisitsPercentage ( percentage ) ;
85+ }
86+ } ;
87+
6588 /**
6689 * Updates the loading state when the file upload or processing begins or ends.
6790 *
@@ -137,15 +160,42 @@ function App() {
137160 </ div >
138161
139162 < div className = "space-y-2" >
140- < label className = "text-sm font-medium text-gray-700" > Edge Visits</ label >
141- < Slider
142- step = { 1 }
143- min = { 0 }
144- max = { 100 }
145- value = { minVisitsPercentage }
146- onChange = { handleSlider }
147- maxEdgeCount = { maxEdgeCount }
148- />
163+ < label className = "text-sm font-medium text-gray-700" > Minimum Students</ label >
164+ < div className = "space-y-4" >
165+ < div >
166+ < div className = "flex justify-between mb-1" >
167+ { /* <span className="text-sm text-gray-500">Percentage</span>
168+ <span className="text-sm text-gray-500">{minVisitsPercentage}%</span> */ }
169+ </ div >
170+ < div className = "flex items-center gap-2" >
171+ < Slider
172+ step = { 1 }
173+ min = { 0 }
174+ max = { 100 }
175+ value = { minVisitsPercentage }
176+ onChange = { handleSlider }
177+ maxEdgeCount = { maxEdgeCount }
178+ />
179+ < span className = "text-sm text-gray-500" > %</ span >
180+ </ div >
181+ </ div >
182+ < div >
183+ < div className = "flex justify-between mb-1" >
184+ < span className = "text-sm text-gray-500" > Students</ span >
185+ </ div >
186+ < Input
187+ type = "number"
188+ value = { minVisits }
189+ onChange = { ( e ) => handleInputChange ( e . target . value ) }
190+ className = "w-full"
191+ min = { 0 }
192+ max = { maxEdgeCount }
193+ />
194+ </ div >
195+ </ div >
196+ < p className = "text-xs text-gray-500" >
197+ Maximum threshold before any node becomes disconnected: { maxMinEdgeCount } students
198+ </ p >
149199 </ div >
150200 </ div >
151201 </ div >
@@ -165,6 +215,7 @@ function App() {
165215 selfLoops = { selfLoops }
166216 minVisits = { minVisits }
167217 onMaxEdgeCountChange = { setMaxEdgeCount }
218+ onMaxMinEdgeCountChange = { setMaxMinEdgeCount }
168219 />
169220 </ div >
170221 </ div >
0 commit comments