@@ -46,18 +46,36 @@ const COLORS = [
4646] ;
4747
4848let data = null ;
49+ let currentMetric = "trajectory_length" ; // Default metric
50+
51+ // Available metrics with their display names
52+ const METRICS = [
53+ { key : "trajectory_length" , label : "Trajectory Length" } ,
54+ { key : "steps_since_led_to_something_new" , label : "Steps Since New Cell" } ,
55+ { key : "steps_since_led_to_something_new_reset_count" , label : "Reset Count" } ,
56+ { key : "sampled_count" , label : "Sample Count" } ,
57+ { key : "visit_count" , label : "Visit Count" } ,
58+ ] ;
4959
5060// Function to update plots with new data
5161function updatePlots ( ) {
52- const n = document . getElementById ( "n-states" ) . value || 10 ;
62+ const nInput = document . getElementById ( "n-states" ) ;
63+ const metricSelector = document . getElementById ( "metric-selector" ) ;
64+
65+ if ( ! nInput || ! metricSelector ) {
66+ console . error ( "Required DOM elements not found" ) ;
67+ return ;
68+ }
69+
70+ const n = nInput . value || 10 ;
71+ currentMetric = metricSelector . value ;
5372
5473 // Show loading indicator
5574 document . getElementById ( "loading" ) . classList . remove ( "hidden" ) ;
75+ document . getElementById ( "load-error" ) . classList . add ( "hidden" ) ;
5676
5777 // Fetch data from endpoint
58- fetch (
59- `${ _ROOT_URL } n_fewest_steps_since_led_to_something_new_go_explore?n=${ n } `
60- )
78+ fetch ( `${ _ROOT_URL } go_explore?n=${ n } ` )
6179 . then ( ( response ) => response . json ( ) )
6280 . then ( ( responseData ) => {
6381 data = responseData ;
@@ -87,71 +105,45 @@ function renderPlots() {
87105 // Clear existing plots
88106 container . innerHTML = "" ;
89107
90- // Create plots for each metric
91- const metrics = [
92- { key : "trajectory_length" , label : "Trajectory Length" } ,
93- { key : "steps_since_led_to_something_new" , label : "Steps Since New Cell" } ,
94- {
95- key : "steps_since_led_to_something_new_reset_count" ,
96- label : "Reset Count" ,
97- } ,
98- { key : "sample_count" , label : "Sample Count" } ,
99- { key : "visit_count" , label : "Visit Count" } ,
100- ] ;
101-
102- metrics . forEach ( ( metric , index ) => {
103- const plotDiv = document . createElement ( "div" ) ;
104- plotDiv . className = "plot-container" ;
105- container . appendChild ( plotDiv ) ;
106-
108+ // Get the current metric data
109+ const metricData = data [ currentMetric ] ;
110+ if ( ! metricData || ! metricData . states || ! metricData . values ) return ;
111+
112+ // Find the metric label
113+ const metricLabel =
114+ METRICS . find ( ( m ) => m . key === currentMetric ) ?. label || currentMetric ;
115+
116+ // Create a title for the current metric
117+ const metricTitle = document . createElement ( "h2" ) ;
118+ metricTitle . style . color = "#FFFFFF" ;
119+ metricTitle . style . textAlign = "center" ;
120+ metricTitle . style . marginBottom = "20px" ;
121+ metricTitle . textContent = metricLabel ;
122+ container . appendChild ( metricTitle ) ;
123+
124+ // Create state grid container
125+ const gridContainer = document . createElement ( "div" ) ;
126+ gridContainer . className = "state-grid" ;
127+ container . appendChild ( gridContainer ) ;
128+
129+ // Create state visualizations
130+ metricData . states . forEach ( ( state , stateIndex ) => {
131+ const stateContainer = document . createElement ( "div" ) ;
132+ stateContainer . className = "state-container" ;
133+
134+ // Create title with metric value
135+ const title = document . createElement ( "h3" ) ;
136+ title . textContent = `Value: ${ metricData . values [ stateIndex ] } ` ;
137+ stateContainer . appendChild ( title ) ;
138+
139+ // Create canvas for state visualization
107140 const canvas = document . createElement ( "canvas" ) ;
108- canvas . id = `plot-${ metric . key } ` ;
109- plotDiv . appendChild ( canvas ) ;
110-
111- const chartOptions = structuredClone ( CHART_OPTIONS_TEMPLATE ) ;
112- chartOptions . plugins . title . text = metric . label ;
113-
114- new Chart ( canvas , {
115- type : "bar" ,
116- data : {
117- labels : Array . from (
118- { length : data [ metric . key ] . length } ,
119- ( _ , i ) => `State ${ i + 1 } `
120- ) ,
121- datasets : [
122- {
123- label : metric . label ,
124- data : data [ metric . key ] ,
125- backgroundColor : COLORS [ index % COLORS . length ] ,
126- borderColor : COLORS [ index % COLORS . length ] ,
127- } ,
128- ] ,
129- } ,
130- options : chartOptions ,
131- } ) ;
132- } ) ;
133-
134- // Create state visualization grid
135- const stateGrid = document . createElement ( "div" ) ;
136- stateGrid . id = "state-grid" ;
137- container . appendChild ( stateGrid ) ;
138-
139- // Add state visualizations
140- data . states . forEach ( ( state , index ) => {
141- const stateDiv = document . createElement ( "div" ) ;
142- stateDiv . className = "state-container" ;
143- stateGrid . appendChild ( stateDiv ) ;
144-
145- const stateTitle = document . createElement ( "h3" ) ;
146- stateTitle . textContent = `State ${ index + 1 } ` ;
147- stateDiv . appendChild ( stateTitle ) ;
141+ stateContainer . appendChild ( canvas ) ;
148142
149- const stateCanvas = document . createElement ( "canvas" ) ;
150- stateCanvas . id = `state-${ index } ` ;
151- stateDiv . appendChild ( stateCanvas ) ;
143+ // Render state grid
144+ renderStateGrid ( state , canvas ) ;
152145
153- // Render 2D state array
154- renderStateGrid ( state , stateCanvas ) ;
146+ gridContainer . appendChild ( stateContainer ) ;
155147 } ) ;
156148}
157149
@@ -171,31 +163,91 @@ function renderStateGrid(state, canvas) {
171163 // Draw state grid
172164 state . forEach ( ( row , y ) => {
173165 row . forEach ( ( value , x ) => {
174- ctx . fillStyle = value ? "#FFFFFF" : "#000000" ;
166+ // Use different colors for different values
167+ let color ;
168+ if ( value === 0 ) {
169+ color = "#000000" ; // Black for empty
170+ } else if ( value === 1 ) {
171+ color = "#FFFFFF" ; // White for walls/obstacles
172+ } else if ( value === 2 ) {
173+ color = "#FF0000" ; // Red for player/agent
174+ } else if ( value === 3 ) {
175+ color = "#00FF00" ; // Green for goals
176+ } else {
177+ color = "#888888" ; // Gray for other values
178+ }
179+
180+ ctx . fillStyle = color ;
175181 ctx . fillRect (
176182 x * ( cellSize + padding ) ,
177183 y * ( cellSize + padding ) ,
178184 cellSize ,
179185 cellSize
180186 ) ;
187+
188+ // Add a subtle border around each cell
189+ ctx . strokeStyle = "#333" ;
190+ ctx . strokeRect (
191+ x * ( cellSize + padding ) ,
192+ y * ( cellSize + padding ) ,
193+ cellSize ,
194+ cellSize
195+ ) ;
181196 } ) ;
182197 } ) ;
183198}
184199
185200// Initialize when document is ready
186201document . addEventListener ( "DOMContentLoaded" , ( ) => {
187- // Add controls if they don't exist
188- const controls = document . createElement ( "div" ) ;
189- controls . className = "controls" ;
190- controls . innerHTML = `
191- <div class="control">
192- <label for="n-states">Number of States:</label>
193- <input type="number" id="n-states" value="10" min="1" max="50">
194- </div>
195- <button onclick="updatePlots()">Update Plots</button>
202+ // Create controls if they don't exist
203+ let controls = document . querySelector ( ".controls" ) ;
204+ if ( ! controls ) {
205+ controls = document . createElement ( "div" ) ;
206+ controls . className = "controls" ;
207+ document . body . insertBefore ( controls , document . body . firstChild ) ;
208+ }
209+
210+ // Create metric selector
211+ const metricSelector = document . createElement ( "select" ) ;
212+ metricSelector . id = "metric-selector" ;
213+ metricSelector . className = "control" ;
214+
215+ // Add metric options
216+ METRICS . forEach ( ( metric ) => {
217+ const option = document . createElement ( "option" ) ;
218+ option . value = metric . key ;
219+ option . textContent = metric . label ;
220+ metricSelector . appendChild ( option ) ;
221+ } ) ;
222+
223+ // Add metric selector to controls
224+ const metricControl = document . createElement ( "div" ) ;
225+ metricControl . className = "control" ;
226+ metricControl . innerHTML = `
227+ <label for="metric-selector">Metric:</label>
228+ ${ metricSelector . outerHTML }
229+ ` ;
230+ controls . insertBefore ( metricControl , controls . firstChild ) ;
231+
232+ // Add number of states input if it doesn't exist
233+ if ( ! document . getElementById ( "n-states" ) ) {
234+ const nStatesControl = document . createElement ( "div" ) ;
235+ nStatesControl . className = "control" ;
236+ nStatesControl . innerHTML = `
237+ <label for="n-states">Number of States:</label>
238+ <input type="number" id="n-states" value="10" min="1" max="50">
196239 ` ;
197- document . body . insertBefore ( controls , document . body . firstChild ) ;
240+ controls . appendChild ( nStatesControl ) ;
241+ }
242+
243+ // Add update button if it doesn't exist
244+ if ( ! document . querySelector ( ".controls button" ) ) {
245+ const updateButton = document . createElement ( "button" ) ;
246+ updateButton . textContent = "Update Plots" ;
247+ updateButton . onclick = updatePlots ;
248+ controls . appendChild ( updateButton ) ;
249+ }
198250
199- // Initial plot update
200- updatePlots ( ) ;
251+ // Wait a short moment for DOM to be fully updated before initial plot update
252+ setTimeout ( updatePlots , 100 ) ;
201253} ) ;
0 commit comments