@@ -21,8 +21,9 @@ define([
21
21
'vp_base/data/m_ml/mlLibrary' ,
22
22
'vp_base/js/com/component/PopupComponent' ,
23
23
'vp_base/js/com/component/VarSelector2' ,
24
- 'vp_base/js/com/component/ModelEditor'
25
- ] , function ( msHtml , com_util , com_interface , com_String , com_generator , ML_LIBRARIES , PopupComponent , VarSelector2 , ModelEditor ) {
24
+ 'vp_base/js/com/component/ModelEditor' ,
25
+ 'vp_base/js/com/component/MultiSelector'
26
+ ] , function ( msHtml , com_util , com_interface , com_String , com_generator , ML_LIBRARIES , PopupComponent , VarSelector2 , ModelEditor , MultiSelector ) {
26
27
27
28
/**
28
29
* DataPrep
@@ -47,6 +48,12 @@ define([
47
48
...this . state
48
49
}
49
50
51
+ this . popup = {
52
+ type : '' ,
53
+ targetSelector : '' ,
54
+ colSelector : undefined // multi column selector
55
+ }
56
+
50
57
this . modelConfig = ML_LIBRARIES ;
51
58
52
59
this . modelTypeList = {
@@ -55,6 +62,10 @@ define([
55
62
'ETC' : [ 'make-column-transformer' ]
56
63
}
57
64
65
+ this . mctEstimator = {
66
+ 'Encoding' : [ 'prep-onehot' , 'prep-label' , 'prep-ordinal' , 'prep-target' , 'prep-smote' ] ,
67
+ 'Scaling' : [ 'prep-standard' , 'prep-robust' , 'prep-minmax' , 'prep-normalizer' , 'prep-func-trsfrm-log' , 'prep-func-trsfrm-exp' , 'prep-poly-feat' , 'prep-kbins-discretizer' ] ,
68
+ }
58
69
59
70
}
60
71
@@ -82,6 +93,12 @@ define([
82
93
} else {
83
94
$ ( that . wrapSelector ( '#vp_installLibrary' ) ) . hide ( ) ;
84
95
}
96
+
97
+ if ( modelType == 'make-column-transformer' ) {
98
+ // load mct-targetData
99
+ that . loadVariableList ( ) ;
100
+ that . bindMCT ( ) ;
101
+ }
85
102
} ) ;
86
103
87
104
// install library
@@ -99,6 +116,47 @@ define([
99
116
} ) ;
100
117
}
101
118
119
+ bindMCT ( ) {
120
+ let that = this ;
121
+ // mct : click column selector 1
122
+ $ ( this . wrapSelector ( '#mct_columns1btn' ) ) . on ( 'click' , function ( ) {
123
+ that . openColumnSelector ( $ ( that . wrapSelector ( '#mct_columns1' ) ) , 'Select columns to transform' ) ;
124
+ } ) ;
125
+
126
+ // mct : click column selector 2
127
+ $ ( this . wrapSelector ( '#mct_columns2btn' ) ) . on ( 'click' , function ( ) {
128
+ that . openColumnSelector ( $ ( that . wrapSelector ( '#mct_columns2' ) ) , 'Select columns to transform' ) ;
129
+ } ) ;
130
+ }
131
+
132
+ /**
133
+ * Open Inner popup page for column selection
134
+ * @param {Object } targetSelector
135
+ * @param {string } title
136
+ * @param {Array<string> } includeList
137
+ */
138
+ openColumnSelector ( targetSelector , title = 'Select columns' , includeList = [ ] ) {
139
+ this . popup . type = 'column' ;
140
+ this . popup . targetSelector = targetSelector ;
141
+ var previousList = targetSelector . data ( 'list' ) ;
142
+ if ( previousList ) {
143
+ previousList = previousList . map ( col => col . code )
144
+ }
145
+ this . renderMultiSelector ( previousList , includeList ) ;
146
+ this . openInnerPopup ( title ) ;
147
+ }
148
+
149
+ /**
150
+ * Render column selector using MultiSelector module
151
+ * @param {Array<string> } previousList previous selected columns
152
+ * @param {Array<string> } includeList columns to include
153
+ */
154
+ renderMultiSelector ( previousList , includeList ) {
155
+ this . popup . colSelector = new MultiSelector ( this . wrapSelector ( '.vp-inner-popup-body' ) ,
156
+ { mode : 'columns' , parent : [ this . state . mct_targetData ] , selectedList : previousList , includeList : includeList }
157
+ ) ;
158
+ }
159
+
102
160
templateForBody ( ) {
103
161
let page = $ ( msHtml ) ;
104
162
@@ -215,8 +273,63 @@ define([
215
273
let state = this . state ;
216
274
let optBox = new com_String ( ) ;
217
275
if ( modelType == 'make-column-transformer' ) {
276
+ let that = this ;
218
277
// render tag
219
- optBox . append ( 'Test' ) ; // TODO:
278
+ // DataFrame selection
279
+ optBox . appendLine ( '<label for="mct_targetData" class="vp-orange-text">DataFrame</label>' ) ;
280
+ optBox . appendLine ( '<select id="mct_targetData" class="vp-state vp-select"></select>' ) ;
281
+ // Estimator 1 selection
282
+ optBox . appendLine ( '<label for="">Estimator 1</label>' ) ;
283
+ optBox . appendLine ( '<select id="mct_estimator1" class="vp-state vp-select">' ) ;
284
+ optBox . appendFormatLine ( '<option value="{0}">{1}</option>' , '' , 'None' ) ;
285
+ Object . keys ( this . mctEstimator ) . forEach ( modelCategory => {
286
+ let modelOptionTag = new com_String ( ) ;
287
+ that . mctEstimator [ modelCategory ] . forEach ( opt => {
288
+ let optConfig = that . modelConfig [ opt ] ;
289
+ let selectedFlag = '' ;
290
+ if ( opt == that . state . mct_estimator1 ) {
291
+ selectedFlag = 'selected' ;
292
+ }
293
+ modelOptionTag . appendFormatLine ( '<option value="{0}" {1}>{2}</option>' ,
294
+ opt , selectedFlag , optConfig . name ) ;
295
+ } )
296
+ optBox . appendFormatLine ( '<optgroup label="{0}">{1}</optgroup>' ,
297
+ modelCategory , modelOptionTag . toString ( ) ) ;
298
+ } ) ;
299
+ optBox . appendLine ( '</select>' ) ;
300
+ // Estimator 1 column selection
301
+ optBox . appendLine ( '<label for="mct_columns1">Columns 1</label>' ) ;
302
+ optBox . appendLine ( '<div>' ) ;
303
+ optBox . appendLine ( '<input type="text" id="mct_columns1" class="vp-input vp-state" placeholder="Estimator 1 columns" disabled="">' ) ;
304
+ optBox . appendLine ( '<button id="mct_columns1btn" class="vp-button w50">Edit</button>' ) ;
305
+ optBox . appendLine ( '</div>' ) ;
306
+
307
+ // Estimator 2 selection
308
+ optBox . appendLine ( '<label for="">Estimator 2</label>' ) ;
309
+ optBox . appendLine ( '<select id="mct_estimator2" class="vp-state vp-select">' ) ;
310
+ optBox . appendFormatLine ( '<option value="{0}">{1}</option>' , '' , 'None' ) ;
311
+ Object . keys ( this . mctEstimator ) . forEach ( modelCategory => {
312
+ let modelOptionTag = new com_String ( ) ;
313
+ that . mctEstimator [ modelCategory ] . forEach ( opt => {
314
+ let optConfig = that . modelConfig [ opt ] ;
315
+ let selectedFlag = '' ;
316
+ if ( opt == that . state . mct_estimator2 ) {
317
+ selectedFlag = 'selected' ;
318
+ }
319
+ modelOptionTag . appendFormatLine ( '<option value="{0}" {1}>{2}</option>' ,
320
+ opt , selectedFlag , optConfig . name ) ;
321
+ } )
322
+ optBox . appendFormatLine ( '<optgroup label="{0}">{1}</optgroup>' ,
323
+ modelCategory , modelOptionTag . toString ( ) ) ;
324
+ } ) ;
325
+ optBox . appendLine ( '</select>' ) ;
326
+ // Estimator 2 column selection
327
+ optBox . appendLine ( '<label for="mct_columns1">Columns 2</label>' ) ;
328
+ optBox . appendLine ( '<div>' ) ;
329
+ optBox . appendLine ( '<input type="text" id="mct_columns2" class="vp-input vp-state" placeholder="Estimator 2 columns" disabled="">' ) ;
330
+ optBox . appendLine ( '<button id="mct_columns2btn" class="vp-button w50">Edit</button>' ) ;
331
+ optBox . appendLine ( '</div>' ) ;
332
+
220
333
} else {
221
334
// render tag
222
335
config . options . forEach ( opt => {
@@ -236,9 +349,58 @@ define([
236
349
return optBox . toString ( ) ;
237
350
}
238
351
352
+ /**
353
+ * Load variable list (dataframe)
354
+ */
355
+ loadVariableList ( ) {
356
+ var that = this ;
357
+ // load using kernel
358
+ var dataTypes = [ 'DataFrame' ] ;
359
+ vpKernel . getDataList ( dataTypes ) . then ( function ( resultObj ) {
360
+ let { result } = resultObj ;
361
+ try {
362
+ var varList = JSON . parse ( result ) ;
363
+ // render variable list
364
+ // get prevvalue
365
+ var prevValue = that . state . mct_targetData ;
366
+ // replace
367
+ $ ( that . wrapSelector ( '#mct_targetData' ) ) . replaceWith ( function ( ) {
368
+ var tag = new com_String ( ) ;
369
+ tag . appendFormatLine ( '<select id="{0}" class="vp-select vp-state">' , 'mct_targetData' ) ;
370
+ varList . forEach ( vObj => {
371
+ // varName, varType
372
+ var label = vObj . varName ;
373
+ tag . appendFormatLine ( '<option value="{0}" data-type="{1}" {2}>{3}</option>'
374
+ , vObj . varName , vObj . varType
375
+ , prevValue == vObj . varName ?'selected' :''
376
+ , label ) ;
377
+ } ) ;
378
+ tag . appendLine ( '</select>' ) ; // VP_VS_VARIABLES
379
+ return tag . toString ( ) ;
380
+ } ) ;
381
+ $ ( that . wrapSelector ( '#mct_targetData' ) ) . trigger ( 'change' ) ;
382
+ } catch ( ex ) {
383
+ vpLog . display ( VP_LOG_TYPE . ERROR , 'DataPrep:' , result ) ;
384
+ }
385
+ } ) ;
386
+ }
387
+
388
+ handleInnerOk ( ) {
389
+ // ok input popup
390
+ var dataList = this . popup . colSelector . getDataList ( ) ;
391
+
392
+ $ ( this . popup . targetSelector ) . val ( dataList . map ( col => { return col . code } ) . join ( ',' ) ) ;
393
+ $ ( this . popup . targetSelector ) . data ( 'list' , dataList ) ;
394
+ $ ( this . popup . targetSelector ) . trigger ( { type : 'change' , dataList : dataList } ) ;
395
+ this . closeInnerPopup ( ) ;
396
+ }
397
+
239
398
render ( ) {
240
399
super . render ( ) ;
241
400
401
+ this . loadVariableList ( ) ;
402
+ this . bindMCT ( ) ;
403
+
242
404
// Instance Editor
243
405
this . modelEditor = new ModelEditor ( this , "model" , "instanceEditor" ) ;
244
406
}
@@ -255,11 +417,29 @@ define([
255
417
*/
256
418
let config = this . modelConfig [ modelType ] ;
257
419
code . appendLine ( config . import ) ;
258
- code . appendLine ( ) ;
259
-
420
+
260
421
// model code
261
422
let modelCode = config . code ;
262
423
modelCode = com_generator . vp_codeGenerator ( this , config , this . state , ( userOption != '' ? ', ' + userOption : '' ) ) ;
424
+
425
+ // generate mct code
426
+ if ( modelType == 'make-column-transformer' ) {
427
+ let mctCodes = [ ] ;
428
+ let { mct_estimator1, mct_columns1, mct_estimator2, mct_columns2 } = this . state ;
429
+ if ( mct_estimator1 != undefined && mct_estimator1 != '' ) {
430
+ code . appendLine ( this . modelConfig [ mct_estimator1 ] . import ) ;
431
+ let estimator1code = com_generator . vp_codeGenerator ( this , this . modelConfig [ mct_estimator1 ] , this . state , ( userOption != '' ? ', ' + userOption : '' ) ) ;
432
+ mctCodes . push ( com_util . formatString ( '({0}, [{1}])' , estimator1code , mct_columns1 ) ) ;
433
+ }
434
+ if ( mct_estimator2 != undefined && mct_estimator2 != '' ) {
435
+ code . appendLine ( this . modelConfig [ mct_estimator2 ] . import ) ;
436
+ let estimator2code = com_generator . vp_codeGenerator ( this , this . modelConfig [ mct_estimator2 ] , this . state , ( userOption != '' ? ', ' + userOption : '' ) ) ;
437
+ mctCodes . push ( com_util . formatString ( '({0}, [{1}])' , estimator2code , mct_columns2 ) ) ;
438
+ }
439
+ modelCode = modelCode . replace ( '${mct_code}' , mctCodes . join ( ', ' ) ) ;
440
+ }
441
+
442
+ code . appendLine ( ) ;
263
443
code . appendFormat ( '{0} = {1}' , allocateToCreation , modelCode ) ;
264
444
} else {
265
445
/**
0 commit comments