@@ -40,7 +40,7 @@ export default function importCSV(file: File, fileContent: string, options: CSVO
4040 const lines : string [ ] = [ ] ;
4141 for ( const row of fileContent . split ( '\n' ) ) {
4242 const trimmed = row . trim ( ) ;
43- if ( trimmed [ 0 ] === '#' ) {
43+ if ( trimmed [ 0 ] === '#' || trimmed . length === 0 ) {
4444 continue ;
4545 }
4646 lines . push ( trimmed ) ;
@@ -94,18 +94,21 @@ export default function importCSV(file: File, fileContent: string, options: CSVO
9494 return asDataGroup ( parseGroup ( file . name , 0 , activeGroup . rows , options , labels ) ) ;
9595 }
9696 const root : IDataGroup = { title : file . name , level : 0 , datasets : [ ] } ;
97+ // shift to have at least under the root
98+ const levelOffset = groups . reduce ( ( acc , g ) => Math . min ( acc , g . level ) , Number . POSITIVE_INFINITY ) - 1 ;
99+
97100 let active = root ;
98101 for ( const group of groups ) {
99- const parsed = parseGroup ( group . label , group . level , group . rows , options , labels ) ;
100- if ( group . level > active . level ) {
102+ const parsed = parseGroup ( group . label , group . level - levelOffset , group . rows , options , labels ) ;
103+ if ( parsed . level > active . level ) {
101104 // child
102105 active . datasets . push ( parsed ) ;
103106 parsed . parent = active ;
104107 active = parsed ;
105108 continue ;
106109 }
107110 // multiple levels up
108- while ( group . level < active . level ) {
111+ while ( parsed . level < active . level ) {
109112 active = active . parent ! ;
110113 }
111114 // sibling
@@ -120,7 +123,7 @@ function parseGroup(title: string, level: number, rows: string[][], options: CSV
120123 const dates = rows . map ( ( row , i ) => parseDate ( row , i , options ) ) ;
121124 const datasets : DataSet [ ] = [ ] ;
122125 labels . forEach ( ( label , i ) => {
123- if ( isDateColumn ( i , options ) ) {
126+ if ( isDateColumn ( i , options ) || ( options . hasGroup && options . groupColumn === i ) ) {
124127 return ;
125128 }
126129 const data = rows . map ( ( row , j ) => {
@@ -132,32 +135,31 @@ function parseGroup(title: string, level: number, rows: string[][], options: CSV
132135 return { title, level, datasets } ;
133136}
134137
135- function splitGroup ( rows : string [ ] [ ] , prefix : string , level : number , groupColumn : number ) {
138+ function splitGroup (
139+ rows : string [ ] [ ] ,
140+ prefix : string ,
141+ level : number ,
142+ groupColumn : number ,
143+ ) : { label : string ; level : number ; rows : string [ ] [ ] } [ ] {
136144 if ( rows . length === 0 ) {
137145 return [ ] ;
138146 }
139- const r : { label : string ; level : number ; rows : string [ ] [ ] } [ ] = [
140- {
141- label : prefix + String ( rows [ 0 ] [ groupColumn ] ) ,
142- level,
143- rows : [ ] ,
144- } ,
145- ] ;
146- let active = r [ 0 ] ;
147+ const groups : Map < string , { label : string ; level : number ; rows : string [ ] [ ] } > = new Map ( ) ;
148+
147149 for ( const row of rows ) {
148150 const group = prefix + String ( row [ groupColumn ] ) ;
149- if ( group != active . label ) {
150- r . push ( {
151+ const g = groups . get ( group ) ;
152+ if ( g ) {
153+ g . rows . push ( row ) ;
154+ } else {
155+ groups . set ( group , {
151156 label : group ,
152157 level,
153158 rows : [ row ] ,
154159 } ) ;
155- active = r [ r . length - 1 ] ;
156- } else {
157- active . rows . push ( row ) ;
158160 }
159161 }
160- return r ;
162+ return Array . from ( groups . values ( ) ) ;
161163}
162164
163165function isDateColumn ( column : number , options : CSVOptions ) {
0 commit comments