@@ -67,30 +67,90 @@ function createNodeInfo(node) {
6767 addInfoRow ( dl , "Fill Value" , formatFillValue ( meta . fill_value ) ) ;
6868 }
6969
70- if ( node . chunks ) addInfoRow ( dl , "Chunks" , formatChunks ( node . chunks ) ) ;
71-
72- // Computed: chunk count, chunk size, uncompressed size
73- if ( node . shape ) {
70+ // Chunk and shard info
71+ {
72+ const shardingCodec =
73+ meta ?. zarr_format === 3 &&
74+ meta ?. codecs ?. find ( ( c ) => c . name === "sharding_indexed" ) ;
75+ const innerChunkShape = shardingCodec ?. configuration ?. chunk_shape ;
76+ // Use chunk_grid from raw metadata for the shard (outer) shape, since
77+ // node.chunks may come from zarrita which resolves to inner chunk shape.
78+ const shardShape = shardingCodec
79+ ? meta ?. chunk_grid ?. configuration ?. chunk_shape
80+ : null ;
7481 const chunkShape = getChunkShape ( node ) ;
7582 const byteSize = dtypeByteSize ( node . dtype ) ;
7683
77- if ( chunkShape ) {
78- const numChunks = node . shape . map ( ( s , i ) => Math . ceil ( s / chunkShape [ i ] ) ) ;
79- const totalChunks = numChunks . reduce ( ( a , b ) => a * b , 1 ) ;
84+ if ( shardingCodec && innerChunkShape && shardShape && node . shape ) {
85+ // --- Sharded array: chunks then shards ---
86+ addInfoRow ( dl , "Chunk Shape" , `[${ innerChunkShape . join ( ", " ) } ]` ) ;
87+
88+ const chunkCount = node . shape . map ( ( s , i ) =>
89+ Math . ceil ( s / innerChunkShape [ i ] ) ,
90+ ) ;
91+ const totalChunks = chunkCount . reduce ( ( a , b ) => a * b , 1 ) ;
8092 addInfoRow (
8193 dl ,
8294 "Chunk Count" ,
83- `${ totalChunks . toLocaleString ( ) } ` +
84- ( numChunks . length > 1 ? ` [${ numChunks . join ( " \u00d7 " ) } ]` : "" ) ,
95+ `${ totalChunks . toLocaleString ( ) } [${ chunkCount . join ( " \u00d7 " ) } ]` ,
8596 ) ;
8697
8798 if ( byteSize ) {
88- const chunkElements = chunkShape . reduce ( ( a , b ) => a * b , 1 ) ;
99+ const chunkElements = innerChunkShape . reduce ( ( a , b ) => a * b , 1 ) ;
89100 addInfoRow ( dl , "Chunk Size" , formatBytes ( chunkElements * byteSize ) ) ;
90101 }
102+
103+ const chunksPerShard = shardShape . map ( ( s , i ) =>
104+ Math . ceil ( s / innerChunkShape [ i ] ) ,
105+ ) ;
106+ addInfoRow (
107+ dl ,
108+ "Chunks per Shard" ,
109+ `[${ chunksPerShard . join ( ", " ) } ]` ,
110+ ) ;
111+
112+ addInfoRow ( dl , "Shard Shape" , `[${ shardShape . join ( ", " ) } ]` ) ;
113+
114+ const shardCount = node . shape . map ( ( s , i ) =>
115+ Math . ceil ( s / shardShape [ i ] ) ,
116+ ) ;
117+ const totalShards = shardCount . reduce ( ( a , b ) => a * b , 1 ) ;
118+ addInfoRow (
119+ dl ,
120+ "Shard Count" ,
121+ `${ totalShards . toLocaleString ( ) } [${ shardCount . join ( " \u00d7 " ) } ]` ,
122+ ) ;
123+
124+ if ( byteSize ) {
125+ const shardElements = shardShape . reduce ( ( a , b ) => a * b , 1 ) ;
126+ addInfoRow ( dl , "Shard Size" , formatBytes ( shardElements * byteSize ) ) ;
127+ }
128+ } else {
129+ // --- Non-sharded array ---
130+ if ( node . chunks ) addInfoRow ( dl , "Chunks" , formatChunks ( node . chunks ) ) ;
131+
132+ if ( node . shape && chunkShape ) {
133+ const numChunks = node . shape . map ( ( s , i ) =>
134+ Math . ceil ( s / chunkShape [ i ] ) ,
135+ ) ;
136+ const totalChunks = numChunks . reduce ( ( a , b ) => a * b , 1 ) ;
137+ addInfoRow (
138+ dl ,
139+ "Chunk Count" ,
140+ `${ totalChunks . toLocaleString ( ) } ` +
141+ ( numChunks . length > 1
142+ ? ` [${ numChunks . join ( " \u00d7 " ) } ]`
143+ : "" ) ,
144+ ) ;
145+
146+ if ( byteSize ) {
147+ const chunkElements = chunkShape . reduce ( ( a , b ) => a * b , 1 ) ;
148+ addInfoRow ( dl , "Chunk Size" , formatBytes ( chunkElements * byteSize ) ) ;
149+ }
150+ }
91151 }
92152
93- if ( byteSize ) {
153+ if ( node . shape && byteSize ) {
94154 const totalElements = node . shape . reduce ( ( a , b ) => a * b , 1 ) ;
95155 addInfoRow ( dl , "Uncompressed" , formatBytes ( totalElements * byteSize ) ) ;
96156 }
@@ -99,21 +159,6 @@ function createNodeInfo(node) {
99159 // Codecs (v3) or Compressor + Filters (v2)
100160 if ( meta ?. zarr_format === 3 && meta ?. codecs ) {
101161 addInfoRow ( dl , "Codecs" , formatCodecs ( meta . codecs ) ) ;
102-
103- // Sharding detection
104- const shardingCodec = meta . codecs . find (
105- ( c ) => c . name === "sharding_indexed" ,
106- ) ;
107- if ( shardingCodec ?. configuration ?. chunk_shape ) {
108- const subShape = shardingCodec . configuration . chunk_shape ;
109- const subByteSize = dtypeByteSize ( node . dtype ) ;
110- let shardLabel = `Sub-chunks: [${ subShape . join ( ", " ) } ]` ;
111- if ( subByteSize ) {
112- const subElements = subShape . reduce ( ( a , b ) => a * b , 1 ) ;
113- shardLabel += ` (${ formatBytes ( subElements * subByteSize ) } )` ;
114- }
115- addInfoRow ( dl , "Sharding" , shardLabel ) ;
116- }
117162 } else if ( meta ?. zarr_format === 2 ) {
118163 if ( meta . compressor ) {
119164 addInfoRow ( dl , "Compressor" , formatV2Codec ( meta . compressor ) ) ;
0 commit comments