@@ -36,6 +36,8 @@ export type PreloadedData = {
3636 statements : { statement_id : string ; txt : string ; moderated : number } [ ] ;
3737 votesRows : { participant_id : string ; comment_id : string ; vote : number } [ ] ;
3838 pipelineData ?: Record < string , [ string , [ number , number ] ] [ ] > ;
39+ /** Full-dimension embeddings (>2D, e.g. PCA) for metrics layer */
40+ fullDimensionEmbeddings ?: Record < string , [ string , number [ ] ] [ ] > ;
3941} ;
4042
4143type AppProps = {
@@ -405,33 +407,69 @@ export const App: React.FC<AppProps> = ({ testAnimation = false, kedroBaseUrl, i
405407
406408 setPointMetrics ( newPointMetrics ) ;
407409 } else if ( metricConfig . type === "principal-components" ) {
408- // Load principal component metrics (new logic)
410+ // Load principal component metrics
409411 const componentIndex = metricConfig . component - 1 ; // Convert 1-based to 0-based index
410412
411- // Extract the imputer from the current pipeline ID and construct the PCA pipeline ID
412- // e.g., "mean_localmap_bestkmeans" -> "mean_pca_bestkmeans"
413- // e.g., "median_umap_bestkmeans" -> "median_pca_bestkmeans"
414- const pipelineParts = currentPipelineId . split ( '_' ) ;
415- let pcaPipelineId = 'mean_pca_bestkmeans' ; // fallback default
413+ if ( preloadedData ?. fullDimensionEmbeddings ) {
414+ // Preloaded mode: extract components from full-dimension embeddings
415+ const embKeys = Object . keys ( preloadedData . fullDimensionEmbeddings ) ;
416+ // Prefer pca_masked_unscaled, then any key containing 'pca', then first available
417+ const pcaKey = embKeys . find ( k => k === 'pca_masked_unscaled' )
418+ || embKeys . find ( k => k . includes ( 'pca' ) )
419+ || embKeys [ 0 ] ;
420+
421+ if ( pcaKey ) {
422+ const fullData = preloadedData . fullDimensionEmbeddings [ pcaKey ] ;
423+ console . log ( `Using preloaded PCA embedding "${ pcaKey } " (${ fullData [ 0 ] ?. [ 1 ] ?. length || 0 } dimensions)` ) ;
424+
425+ // Build a map and normalize
426+ const rawValues = new Map < string , number > ( ) ;
427+ let minValue = Infinity ;
428+ let maxValue = - Infinity ;
429+
430+ for ( const [ pid , coords ] of fullData ) {
431+ if ( coords . length > componentIndex ) {
432+ const value = coords [ componentIndex ] ;
433+ rawValues . set ( pid , value ) ;
434+ minValue = Math . min ( minValue , value ) ;
435+ maxValue = Math . max ( maxValue , value ) ;
436+ }
437+ }
438+
439+ const range = maxValue - minValue ;
440+ const newPointMetrics = dataset . map ( ( [ participantId ] ) => {
441+ const raw = rawValues . get ( participantId ) ;
442+ if ( raw === undefined ) return null ;
443+ return range > 0 ? ( raw - minValue ) / range : 0.5 ;
444+ } ) ;
445+
446+ console . log ( `Calculated principal component ${ metricConfig . component } for ${ rawValues . size } participants (range: ${ minValue . toFixed ( 3 ) } - ${ maxValue . toFixed ( 3 ) } )` ) ;
447+ setPointMetrics ( newPointMetrics ) ;
448+ }
449+ } else {
450+ // Kedro/static mode: derive PCA pipeline ID from current pipeline
451+ const pipelineParts = currentPipelineId . split ( '_' ) ;
452+ let pcaPipelineId = 'mean_pca_bestkmeans' ; // fallback default
453+
454+ if ( pipelineParts . length >= 3 ) {
455+ const imputer = pipelineParts [ 0 ] ; // e.g., "mean", "median"
456+ const clustering = "bestkmeans" ;
457+ pcaPipelineId = `${ imputer } _pca_${ clustering } ` ;
458+ }
416459
417- if ( pipelineParts . length >= 3 ) {
418- const imputer = pipelineParts [ 0 ] ; // e.g., "mean", "median"
419- const clustering = "bestkmeans" ; // alwasy assume "bestkmeans"
420- pcaPipelineId = `${ imputer } _pca_${ clustering } ` ;
421- }
460+ console . log ( `Using PCA pipeline "${ pcaPipelineId } " derived from current pipeline "${ currentPipelineId } "` ) ;
422461
423- console . log ( `Using PCA pipeline "${ pcaPipelineId } " derived from current pipeline "${ currentPipelineId } "` ) ;
462+ const componentValues = await getPrincipalComponentValues ( componentIndex , {
463+ kedroBaseUrl,
464+ pipelineId : pcaPipelineId
465+ } ) ;
424466
425- const componentValues = await getPrincipalComponentValues ( componentIndex , {
426- kedroBaseUrl,
427- pipelineId : pcaPipelineId
428- } ) ;
467+ const newPointMetrics = dataset . map ( ( [ participantId ] ) => {
468+ return componentValues . get ( participantId ) ?? null ;
469+ } ) ;
429470
430- const newPointMetrics = dataset . map ( ( [ participantId ] ) => {
431- return componentValues . get ( participantId ) ?? null ;
432- } ) ;
433-
434- setPointMetrics ( newPointMetrics ) ;
471+ setPointMetrics ( newPointMetrics ) ;
472+ }
435473 }
436474 } catch ( err ) {
437475 console . error ( 'Error loading metrics:' , err ) ;
0 commit comments