define([ 'vp_base/js/com/com_String', 'vp_base/js/com/com_util', ], function(com_String, com_util) { const VP_VS_BOX = 'vp-vs-box'; const VP_VS_DATA_TYPE = 'vp-vs-data-type'; const VP_VS_VARIABLES = 'vp-vs-variables'; const VP_VS_TYPING_INPUT = 'vp-vs-typing-input'; const VP_VS_COLUMN_INPUT = 'vp-vs-column-input'; const VP_VS_REFRESH = 'vp-vs-refresh'; /** * @class VarSelector * @param {Array} dataTypes * @param {String} defaultType * @constructor * * using sample: var varSelector = new VarSelector(['DataFrame', 'Series'], 'DataFrame'); $(this.wrapSelector('.vp-vs-tester')).html(varSelector.render()); */ class VarSelector { constructor(dataTypes, defaultType = '', showOthers = true, useTyping = true) { this.uuid = 'u' + com_util.getUUID(); this.label = { 'others': 'Others', 'typing': 'Typing' }; this.boxClass = []; this.id = ''; this.class = []; this.attributes = {}; this.typeClass = []; // type selector class this.varClass = []; // variable selector class this.colClass = []; // column selector class this.dataTypes = dataTypes; if (defaultType == '') { if (dataTypes.length > 0) { defaultType = dataTypes[0]; } else { } } this.state = { selectedType: defaultType, varList: [], column: '' }; this.defaultType = defaultType; this.defaultValue = ''; this.defaultColumn = ''; this.showOthers = showOthers; this.useTyping = useTyping; this.useColumn = false; this.reload(); this.bindEvent(); } setComponentId(id) { this.id = id; } addBoxClass(classname) { this.boxClass.push(classname); } addClass(classname) { this.class.push(classname); } addTypeClass(classname) { this.typeClass.push(classname); } addVarClass(classname) { this.varClass.push(classname); } addColClass(classname) { this.colClass.push(classname); } addAttribute(key, value) { this.attributes.push({ [key]: value }); } setValue(value) { if (value == null || value == undefined) { value = ''; } this.defaultValue = value; if (value.includes('[') && value.includes(']') ) { // divide it to variable / column let startIdx = value.indexOf('['); let endIdx = value.indexOf(']'); this.defaultValue = value.substring(0, startIdx); this.defaultColumn = value.substring(startIdx + 1, endIdx); } } setState(newState) { this.state = { ...this.state, ...newState } } setUseColumn(useColumn) { this.useColumn = useColumn; } wrapSelector(selector = '') { return com_util.formatString('.{0} {1}', this.uuid, selector); } render(defaultType = this.defaultType, defaultValue = this.defaultValue) { var tag = new com_String(); // var selector box tag.appendFormatLine('
', VP_VS_BOX, this.uuid, this.boxClass.join(' ')); // // hidden input value // tag.appendFormatLine('', // this.attributes.id? 'id="' + this.attributes.id + '"': ''); // data type selector tag.appendFormatLine(''); // VP_VS_DATA_TYPE // variable selctor tag.appendLine(this.renderVariableList(this.state.varList)); var attrStr = Object.keys(this.attributes).map(key => key + '="' + this.attributes[key] + '"').join(' '); // typing tag.appendFormatLine('', VP_VS_TYPING_INPUT, 'vp-input m', this.class.join(' '), 'Type your code', this.id ? 'id="' + this.id + '"' : '', defaultValue, defaultType, attrStr); // column for dataframe tag.appendFormatLine('', VP_VS_COLUMN_INPUT, 'vp-select m', this.colClass.join(' '), (this.useColumn == true && defaultType == 'DataFrame'?'':'style="display: none;"')); // reload tag.appendFormatLine('', VP_VS_REFRESH, 'Refresh variables', '/nbextensions/visualpython/img/refresh.svg'); tag.appendLine('
'); // VP_VS_BOX return tag.toString(); } reload() { var that = this; // load using kernel var dataTypes = this.showOthers ? [] : this.dataTypes; vpKernel.getDataList(dataTypes).then(function (resultObj) { try { let { result, type, msg } = resultObj; var varList = JSON.parse(result); that.state.varList = varList; // render variable list that.loadVariableList(varList); } catch (ex) { // console.log(ex); } }); } renderVariableList(varList) { var tag = new com_String(); tag.appendFormatLine(''); // VP_VS_VARIABLES return tag.toString(); } loadVariableList(varList) { var filteredList = varList; var that = this; let dataTypes = this.dataTypes; // Include various index types for Index type var INDEX_TYPES = ['RangeIndex', 'CategoricalIndex', 'MultiIndex', 'IntervalIndex', 'DatetimeIndex', 'TimedeltaIndex', 'PeriodIndex', 'Int64Index', 'UInt64Index', 'Float64Index']; // Include various groupby types for Groupby type var GROUPBY_TYPES = ['DataFrameGroupBy', 'SeriesGroupBy'] if (dataTypes.indexOf('Index') >= 0) { dataTypes = dataTypes.concat(INDEX_TYPES); } if (dataTypes.indexOf('GroupBy') >= 0) { dataTypes = dataTypes.concat(GROUPBY_TYPES); } if (this.state.selectedType == 'others') { filteredList = varList.filter(v => !dataTypes.includes(v.varType)); } else if (this.state.selectedType == 'typing') { filteredList = []; } else { let filterDataTypes = [ this.state.selectedType ]; if (filterDataTypes.indexOf('Index') >= 0) { filterDataTypes = filterDataTypes.concat(INDEX_TYPES); } if (filterDataTypes.indexOf('GroupBy') >= 0) { filterDataTypes = filterDataTypes.concat(GROUPBY_TYPES); } filteredList = varList.filter(v => filterDataTypes.includes(v.varType)); } // replace $(this.wrapSelector('.' + VP_VS_VARIABLES)).replaceWith(function () { return that.renderVariableList(filteredList); }); $(this.wrapSelector('.' + VP_VS_VARIABLES)).trigger('change'); } loadColumnList(varName) { let that = this; // get result and show on detail box vpKernel.getColumnList(varName).then(function(resultObj) { try { let { result, type, msg } = resultObj; var varResult = JSON.parse(result); let newTag = new com_String(); newTag.appendFormatLine(''); // replace $(that.wrapSelector('.' + VP_VS_COLUMN_INPUT)).replaceWith(function() { return newTag.toString(); }); } catch (e) { vpLog.display(VP_LOG_TYPE.ERROR, 'varSelector - bindColumnSource: not supported data type. ', e); } }); } bindEvent() { var that = this; // data type selection $(document).on('change', this.wrapSelector('.' + VP_VS_DATA_TYPE), function (event) { // re-renderVariableList var dataType = $(this).val(); that.state.selectedType = dataType; if (dataType == 'typing') { $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).val(''); $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).attr('data-type', ''); $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).show(); $(that.wrapSelector('.' + VP_VS_VARIABLES)).hide(); $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).trigger({ type: 'var_changed', value: '', dataType: '' }); } else { $(that.wrapSelector('.' + VP_VS_VARIABLES)).show(); $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).hide(); // 1) load variable once that.loadVariableList(that.state.varList); // 2) load on every selection of data types // that.reload(); } if (that.useColumn == true) { if (dataType == 'DataFrame') { $(that.wrapSelector('.' + VP_VS_COLUMN_INPUT)).show(); } else { $(that.wrapSelector('.' + VP_VS_COLUMN_INPUT)).hide(); } } else { $(that.wrapSelector('.' + VP_VS_COLUMN_INPUT)).hide(); } }); // variable selection $(document).on('change', this.wrapSelector('.' + VP_VS_VARIABLES), function (event) { var value = $(this).val(); var dataType = $(this).find('option:selected').attr('data-type'); $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).val(value); $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).attr('data-type', dataType); $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).trigger({ type: 'var_changed', value: value, dataType: dataType }); // if datatype == dataframe, change column list if (that.useColumn == true && dataType == 'DataFrame') { that.loadColumnList(value); } }); // column selection $(document).on('change', this.wrapSelector('.' + VP_VS_COLUMN_INPUT), function(event) { var value = $(that.wrapSelector('.' + VP_VS_VARIABLES)).val(); var colValue = $(this).val(); var newValue = value; if (colValue != '') { newValue += '[' + colValue + ']'; } var dataType = $(this).find('option:selected').attr('data-type'); $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).val(newValue); $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).attr('data-type', dataType); $(that.wrapSelector('.' + VP_VS_TYPING_INPUT)).trigger({ type: 'var_changed', value: newValue, dataType: 'DataFrame' }); }); // refresh $(document).on('click', this.wrapSelector('.' + VP_VS_REFRESH), function() { that.reload(); }); } } return VarSelector; })