@@ -40,7 +40,7 @@ export default function importCSV(file: File, fileContent: string, options: CSVO
40
40
const lines : string [ ] = [ ] ;
41
41
for ( const row of fileContent . split ( '\n' ) ) {
42
42
const trimmed = row . trim ( ) ;
43
- if ( trimmed [ 0 ] === '#' ) {
43
+ if ( trimmed [ 0 ] === '#' || trimmed . length === 0 ) {
44
44
continue ;
45
45
}
46
46
lines . push ( trimmed ) ;
@@ -94,18 +94,21 @@ export default function importCSV(file: File, fileContent: string, options: CSVO
94
94
return asDataGroup ( parseGroup ( file . name , 0 , activeGroup . rows , options , labels ) ) ;
95
95
}
96
96
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
+
97
100
let active = root ;
98
101
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 ) {
101
104
// child
102
105
active . datasets . push ( parsed ) ;
103
106
parsed . parent = active ;
104
107
active = parsed ;
105
108
continue ;
106
109
}
107
110
// multiple levels up
108
- while ( group . level < active . level ) {
111
+ while ( parsed . level < active . level ) {
109
112
active = active . parent ! ;
110
113
}
111
114
// sibling
@@ -120,7 +123,7 @@ function parseGroup(title: string, level: number, rows: string[][], options: CSV
120
123
const dates = rows . map ( ( row , i ) => parseDate ( row , i , options ) ) ;
121
124
const datasets : DataSet [ ] = [ ] ;
122
125
labels . forEach ( ( label , i ) => {
123
- if ( isDateColumn ( i , options ) ) {
126
+ if ( isDateColumn ( i , options ) || ( options . hasGroup && options . groupColumn === i ) ) {
124
127
return ;
125
128
}
126
129
const data = rows . map ( ( row , j ) => {
@@ -132,32 +135,31 @@ function parseGroup(title: string, level: number, rows: string[][], options: CSV
132
135
return { title, level, datasets } ;
133
136
}
134
137
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 [ ] [ ] } [ ] {
136
144
if ( rows . length === 0 ) {
137
145
return [ ] ;
138
146
}
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
+
147
149
for ( const row of rows ) {
148
150
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 , {
151
156
label : group ,
152
157
level,
153
158
rows : [ row ] ,
154
159
} ) ;
155
- active = r [ r . length - 1 ] ;
156
- } else {
157
- active . rows . push ( row ) ;
158
160
}
159
161
}
160
- return r ;
162
+ return Array . from ( groups . values ( ) ) ;
161
163
}
162
164
163
165
function isDateColumn ( column : number , options : CSVOptions ) {
0 commit comments