@@ -38,7 +38,8 @@ define([
3838 pivot : {
3939 index : [ ] ,
4040 columns : [ ] ,
41- values : [ ]
41+ values : [ ] ,
42+ aggfunc : [ ]
4243 } ,
4344 melt : {
4445 idVars : [ ] ,
@@ -98,7 +99,7 @@ define([
9899 that . _resetColumnSelector ( that . wrapSelector ( '#vp_rsValueVars' ) ) ;
99100
100101 that . state . pivot = {
101- index : [ ] , columns : [ ] , values : [ ]
102+ index : [ ] , columns : [ ] , values : [ ] , aggfunc : [ ]
102103 } ;
103104 that . state . melt = {
104105 idVars : [ ] , valueVars : [ ]
@@ -116,13 +117,8 @@ define([
116117 var type = $ ( this ) . val ( ) ;
117118 that . state . type = type ;
118119 // change visibility
119- if ( type == 'pivot' ) {
120- $ ( that . wrapSelector ( '.vp-rs-type-box.melt' ) ) . hide ( ) ;
121- $ ( that . wrapSelector ( '.vp-rs-type-box.pivot' ) ) . show ( ) ;
122- } else {
123- $ ( that . wrapSelector ( '.vp-rs-type-box.pivot' ) ) . hide ( ) ;
124- $ ( that . wrapSelector ( '.vp-rs-type-box.melt' ) ) . show ( ) ;
125- }
120+ $ ( that . wrapSelector ( '.vp-rs-type-box' ) ) . hide ( ) ;
121+ $ ( that . wrapSelector ( '.vp-rs-type-box.' + type ) ) . show ( ) ;
126122
127123 // clear user option
128124 $ ( that . wrapSelector ( '#vp_rsUserOption' ) ) . val ( '' ) ;
@@ -168,6 +164,19 @@ define([
168164 that . openColumnSelector ( targetVariable , $ ( that . wrapSelector ( '#vp_rsValues' ) ) , 'Select columns' , excludeList ) ;
169165 } ) ;
170166
167+ // aggfunc change event
168+ $ ( document ) . on ( 'change' , this . wrapSelector ( '#vp_rsAggfunc' ) , function ( event ) {
169+ var colList = event . dataList ;
170+ that . state . pivot . aggfunc = colList ;
171+ } ) ;
172+
173+ // aggfunc select button event
174+ $ ( document ) . on ( 'click' , this . wrapSelector ( '#vp_rsAggfunc' ) , function ( ) {
175+ var targetVariable = [ that . state . variable ] ;
176+ var excludeList = that . state . pivot . aggfunc . map ( obj => obj . code ) ;
177+ that . openMethodSelector ( targetVariable , $ ( that . wrapSelector ( '#vp_rsAggfunc' ) ) , 'Select columns' , excludeList ) ;
178+ } ) ;
179+
171180 // id vars change event
172181 $ ( document ) . on ( 'change' , this . wrapSelector ( '#vp_rsIdVars' ) , function ( event ) {
173182 var colList = event . dataList ;
@@ -344,13 +353,39 @@ define([
344353 * @param {Array<string> } previousList previous selected columns
345354 * @param {Array<string> } excludeList columns to exclude
346355 */
347- renderColumnSelector ( targetVariable , previousList , excludeList ) {
356+ renderColumnSelector ( targetVariable , previousList , excludeList ) {
348357 this . popup . ColSelector = new MultiSelector (
349358 this . wrapSelector ( '.vp-inner-popup-body' ) ,
350359 { mode : 'columns' , parent : targetVariable , selectedList : previousList , excludeList : excludeList }
351360 ) ;
352361 }
353362
363+ /**
364+ * Render method selector using MultiSelector module
365+ * @param {Array<string> } previousList previous selected methods
366+ * @param {Array<string> } excludeList methods to exclude
367+ */
368+ renderMethodSelector ( targetVariable , previousList , excludeList ) {
369+ let methodList = [
370+ { value : 'count' , code : "'count'" } ,
371+ { value : 'first' , code : "'first'" } ,
372+ { value : 'last' , code : "'last'" } ,
373+ { value : 'size' , code : "'size'" } ,
374+ { value : 'std' , code : "'std'" } ,
375+ { value : 'sum' , code : "'sum'" } ,
376+ { value : 'max' , code : "'max'" } ,
377+ { value : 'mean' , code : "'mean'" } ,
378+ { value : 'median' , code : "'median'" } ,
379+ { value : 'min' , code : "'min'" } ,
380+ { value : 'quantile' , code : "'quantile'" } ,
381+ ] ;
382+
383+ this . popup . ColSelector = new MultiSelector (
384+ this . wrapSelector ( '.vp-inner-popup-body' ) ,
385+ { mode : 'data' , parent : targetVariable , dataList : methodList , selectedList : previousList , excludeList : excludeList }
386+ ) ;
387+ }
388+
354389 /**
355390 * Load variable list (dataframe)
356391 */
@@ -422,6 +457,45 @@ define([
422457 }
423458 }
424459
460+ } else if ( type == 'pivot_table' ) {
461+ //================================================================
462+ // pivot_table
463+ //================================================================
464+ // index (optional)
465+ if ( pivot . index && pivot . index . length > 0 ) {
466+ if ( pivot . index . length == 1 ) {
467+ options . push ( com_util . formatString ( "index={0}" , pivot . index [ 0 ] . code ) ) ;
468+ } else {
469+ options . push ( com_util . formatString ( "index=[{0}]" , pivot . index . map ( col => col . code ) . join ( ',' ) ) ) ;
470+ }
471+ }
472+
473+ // columns
474+ if ( pivot . columns && pivot . columns . length > 0 ) {
475+ if ( pivot . columns . length == 1 ) {
476+ options . push ( com_util . formatString ( "columns={0}" , pivot . columns [ 0 ] . code ) ) ;
477+ } else {
478+ options . push ( com_util . formatString ( "columns=[{0}]" , pivot . columns . map ( col => col . code ) . join ( ',' ) ) ) ;
479+ }
480+ }
481+
482+ // values (optional)
483+ if ( pivot . values && pivot . values . length > 0 ) {
484+ if ( pivot . values . length == 1 ) {
485+ options . push ( com_util . formatString ( "values={0}" , pivot . values [ 0 ] . code ) ) ;
486+ } else {
487+ options . push ( com_util . formatString ( "values=[{0}]" , pivot . values . map ( col => col . code ) . join ( ',' ) ) ) ;
488+ }
489+ }
490+
491+ // aggfunc
492+ if ( pivot . aggfunc && pivot . aggfunc . length > 0 ) {
493+ if ( pivot . aggfunc . length == 1 ) {
494+ options . push ( com_util . formatString ( "aggfunc={0}" , pivot . aggfunc [ 0 ] . code ) ) ;
495+ } else {
496+ options . push ( com_util . formatString ( "aggfunc=[{0}]" , pivot . aggfunc . map ( col => col . code ) . join ( ',' ) ) ) ;
497+ }
498+ }
425499 } else {
426500 //================================================================
427501 // melt
@@ -511,6 +585,19 @@ define([
511585 this . openInnerPopup ( title ) ;
512586 }
513587
588+ openMethodSelector ( targetVariable , targetSelector , title = 'Select methods' , excludeList = [ ] ) {
589+ this . popup . targetVariable = targetVariable ;
590+ this . popup . targetSelector = targetSelector ;
591+ var previousList = this . popup . targetSelector . data ( 'list' ) ;
592+ if ( previousList ) {
593+ previousList = previousList . map ( col => col . code )
594+ }
595+ this . renderMethodSelector ( targetVariable , previousList , excludeList ) ;
596+
597+ // set title
598+ this . openInnerPopup ( title ) ;
599+ }
600+
514601 handleInnerOk ( ) {
515602 // ok input popup
516603 var dataList = this . popup . ColSelector . getDataList ( ) ;
0 commit comments