@@ -21,8 +21,9 @@ define([
2121 'vp_base/data/m_ml/mlLibrary' ,
2222 'vp_base/js/com/component/PopupComponent' ,
2323 '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 ) {
2627
2728 /**
2829 * DataPrep
@@ -47,6 +48,12 @@ define([
4748 ...this . state
4849 }
4950
51+ this . popup = {
52+ type : '' ,
53+ targetSelector : '' ,
54+ colSelector : undefined // multi column selector
55+ }
56+
5057 this . modelConfig = ML_LIBRARIES ;
5158
5259 this . modelTypeList = {
@@ -55,6 +62,10 @@ define([
5562 'ETC' : [ 'make-column-transformer' ]
5663 }
5764
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+ }
5869
5970 }
6071
@@ -82,6 +93,12 @@ define([
8293 } else {
8394 $ ( that . wrapSelector ( '#vp_installLibrary' ) ) . hide ( ) ;
8495 }
96+
97+ if ( modelType == 'make-column-transformer' ) {
98+ // load mct-targetData
99+ that . loadVariableList ( ) ;
100+ that . bindMCT ( ) ;
101+ }
85102 } ) ;
86103
87104 // install library
@@ -99,6 +116,47 @@ define([
99116 } ) ;
100117 }
101118
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+
102160 templateForBody ( ) {
103161 let page = $ ( msHtml ) ;
104162
@@ -215,8 +273,63 @@ define([
215273 let state = this . state ;
216274 let optBox = new com_String ( ) ;
217275 if ( modelType == 'make-column-transformer' ) {
276+ let that = this ;
218277 // 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+
220333 } else {
221334 // render tag
222335 config . options . forEach ( opt => {
@@ -236,9 +349,58 @@ define([
236349 return optBox . toString ( ) ;
237350 }
238351
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+
239398 render ( ) {
240399 super . render ( ) ;
241400
401+ this . loadVariableList ( ) ;
402+ this . bindMCT ( ) ;
403+
242404 // Instance Editor
243405 this . modelEditor = new ModelEditor ( this , "model" , "instanceEditor" ) ;
244406 }
@@ -255,11 +417,29 @@ define([
255417 */
256418 let config = this . modelConfig [ modelType ] ;
257419 code . appendLine ( config . import ) ;
258- code . appendLine ( ) ;
259-
420+
260421 // model code
261422 let modelCode = config . code ;
262423 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 ( ) ;
263443 code . appendFormat ( '{0} = {1}' , allocateToCreation , modelCode ) ;
264444 } else {
265445 /**
0 commit comments