@@ -21,8 +21,9 @@ define([
2121'vp_base/js/com/component/PopupComponent' ,
2222'vp_base/js/com/component/SuggestInput' ,
2323'vp_base/js/com/component/DataSelector' ,
24+ 'vp_base/js/com/component/MultiSelector' ,
2425'vp_base/js/m_apps/Subset'
25- ] , function ( frameHtml , frameCss , com_Const , com_String , com_util , PopupComponent , SuggestInput , DataSelector , Subset ) {
26+ ] , function ( frameHtml , frameCss , com_Const , com_String , com_util , PopupComponent , SuggestInput , DataSelector , MultiSelector , Subset ) {
2627
2728/**
2829 * Frame
@@ -1427,6 +1428,7 @@ define([
14271428content . appendLine ( '<tr><th><label>Add type</label></th>' ) ;
14281429content . appendFormatLine ( '<td><select class="{0}">' , 'vp-inner-popup-addtype' ) ;
14291430content . appendFormatLine ( '<option value="{0}">{1}</option>' , 'calculate' , 'Calculate' ) ;
1431+ content . appendFormatLine ( '<option value="{0}">{1}</option>' , 'statistics' , 'Statistics' ) ;
14301432content . appendFormatLine ( '<option value="{0}">{1}</option>' , 'replace' , 'Replace' ) ;
14311433content . appendFormatLine ( '<option value="{0}">{1}</option>' , 'condition' , 'Condition' ) ;
14321434content . appendFormatLine ( '<option value="{0}">{1}</option>' , 'apply' , 'Apply' ) ;
@@ -1461,7 +1463,26 @@ define([
14611463content . appendLine ( '</table>' ) ;
14621464content . appendLine ( '</div>' ) ; // end of vp-inner-popup-tab value
14631465
1464- // tab 2. replace
1466+ // tab 2. statistics
1467+ content . appendFormatLine ( '<div class="{0} {1}" style="display:none;">' , 'vp-inner-popup-tab' , 'statistics' ) ;
1468+ content . appendFormatLine ( '<div class="{0}">' , 'vp-grid-col-120' ) ;
1469+ content . appendLine ( '<label class="vp-orange-text">Columns</label>' ) ;
1470+ content . appendFormatLine ( '<div class="{0}" style="height: 150px;"></div>' , 'vp-inner-popup-stats-col-list' ) ;
1471+ content . appendLine ( '<label>Method</label>' ) ;
1472+ content . appendFormatLine ( '<select class="vp-select {0}">' , 'vp-inner-popup-stats-method' ) ;
1473+ let methodList = [
1474+ 'sum' , 'mean' , 'median' , 'max' , 'min' , 'std' , 'var'
1475+ ] ;
1476+ methodList . forEach ( method => {
1477+ content . appendFormatLine ( '<option data-code="{0}" value="{1}">{2}</option>' ,
1478+ method , method , method ) ;
1479+ } ) ;
1480+ content . appendLine ( '</select>' ) ;
1481+
1482+ content . appendLine ( '</div>' ) ;
1483+ content . appendLine ( '</div>' ) ;
1484+
1485+ // tab 3. replace
14651486content . appendFormatLine ( '<div class="{0} {1}" style="display:none;">' , 'vp-inner-popup-tab' , 'replace' ) ;
14661487content . appendFormatLine ( '<div class="{0}">' , 'vp-grid-col-120' ) ;
14671488content . appendLine ( '<label class="vp-orange-text">Target column</label>' ) ;
@@ -1486,7 +1507,7 @@ define([
14861507content . appendLine ( '</div>' ) ;
14871508content . appendLine ( '</div>' ) ;
14881509
1489- // tab3 . condition
1510+ // tab4 . condition
14901511// replace page - 2. condition
14911512content . appendFormatLine ( '<div class="{0} {1}" style="display:none;">' , 'vp-inner-popup-tab' , 'condition' ) ;
14921513// value
@@ -1505,7 +1526,7 @@ define([
15051526content . appendLine ( '</table>' ) ;
15061527content . appendLine ( '</div>' ) ;
15071528
1508- // tab4 . apply
1529+ // tab5 . apply
15091530content . appendFormatLine ( '<div class="{0} {1}" style="display: none;">' , 'vp-inner-popup-tab' , 'apply' ) ;
15101531content . appendLine ( '<div class="vp-grid-box">' ) ;
15111532content . appendLine ( '<div class="vp-grid-col-120">' ) ;
@@ -2263,6 +2284,11 @@ define([
22632284} ) ;
22642285} ) ;
22652286
2287+ // bind multiselector
2288+ this . statsSelector = new MultiSelector ( this . wrapSelector ( '.vp-inner-popup-stats-col-list' ) ,
2289+ { mode :'columns' , parent :this . state . tempObj , showDescription :false }
2290+ ) ;
2291+
22662292// bind codemirror for apply textarea
22672293this . applyCm = this . initCodemirror ( {
22682294key :'vp-inner-popup-apply-lambda' ,
@@ -2547,6 +2573,10 @@ define([
25472573} ) ;
25482574content [ 'values' ] = values ;
25492575content [ 'opers' ] = opers ;
2576+ } else if ( tab == 'statistics' ) {
2577+ var colList = this . statsSelector . getDataList ( ) ;
2578+ content [ 'columns' ] = colList . map ( x => x . code ) ;
2579+ content [ 'method' ] = $ ( this . wrapSelector ( '.vp-inner-popup-stats-method' ) ) . val ( ) ;
25502580} else if ( tab == 'replace' ) {
25512581content [ 'target' ] = $ ( this . wrapSelector ( '.vp-inner-popup-value-col-list option:selected' ) ) . data ( 'code' ) ;
25522582var useregex = $ ( this . wrapSelector ( '.vp-inner-popup-use-regex' ) ) . prop ( 'checked' ) ;
@@ -3102,6 +3132,14 @@ define([
31023132} else {
31033133code . appendFormat ( "{0}[{1}] = {2}" , tempObj , content . name , valueStr ) ;
31043134}
3135+ } else if ( tab == 'statistics' ) {
3136+ code . appendFormat ( "{0}[{1}] = " , tempObj , content . name ) ;
3137+ code . append ( tempObj ) ;
3138+ if ( content [ 'columns' ] . length > 0 ) {
3139+ code . appendFormat ( "[[{0}]]" , content [ 'columns' ] . join ( ',' ) ) ;
3140+ }
3141+ code . appendFormat ( ".apply(lambda x: x.{0}(), axis=1)" , content . method ) ;
3142+ // code.appendFormat(".{0}(axis=1)", content.method); // FIXME: for pandas version upper 2.0.0
31053143} else if ( tab == 'replace' ) {
31063144var replaceStr = new com_String ( ) ;
31073145var targetName = content [ 'target' ] ;