diff --git a/visualpython/css/component/instanceEditor.css b/visualpython/css/component/instanceEditor.css index 1e9c2c9b..c697a79a 100644 --- a/visualpython/css/component/instanceEditor.css +++ b/visualpython/css/component/instanceEditor.css @@ -78,8 +78,12 @@ content: '(Empty)'; color: var(--vp-gray-color); } -.vp-ins-parameter { - width: 100% !important; +div.vp-ins-parameter-box input.vp-ins-parameter { + width: calc(100% - 70px); +} +button.vp-ins-opt-button { + width: 65px; + min-width: 65px; } .vp-create-var-box { position: relative; diff --git a/visualpython/css/m_apps/instance.css b/visualpython/css/m_apps/instance.css index d0a38e28..653827f5 100644 --- a/visualpython/css/m_apps/instance.css +++ b/visualpython/css/m_apps/instance.css @@ -1,13 +1,33 @@ +.vp-instance-body { + display: grid; + grid-template-columns: calc(50% - 8px) calc(50% - 8px); + grid-template-rows: 1fr; + grid-row-gap: 5px; + grid-column-gap: 15px; + align-items: baseline; + align-content: baseline; + height: 100%; +} +.vp-instance-left-box, +.vp-instance-right-box { + height: 100%; +} .vp-instance-base { display: grid; width: 100%; grid-template-columns: 90px calc(100% - 90px); - grid-template-rows: 1fr; + /* grid-template-rows: 1fr; */ + grid-template-rows: min-content; grid-row-gap: 8px; } .vp-instance-base .vp-ds-button { vertical-align: top; - width: 50px; + min-width: 50px; + width: 60px; +} +.vp-instance-target-box { + grid-column-start: 1; + grid-column-end: 3; } .vp-instance-toolbar { /* display: none; */ @@ -47,7 +67,7 @@ /* UDF Editor - CodeMirror */ .vp-instance-box .CodeMirror { display: inline-block; - width: calc(100% - 55px); + width: calc(100% - 65px); height: 30px; border: 0.25px solid var(--vp-grid-line-color); border-radius: 3px; @@ -86,4 +106,22 @@ } .vp-ds-button { width: 50px; +} + +/* Preview box */ +.vp-instance-preview-title { + line-height: 30px; +} +.vp-instance-preview-box { + min-height: 352px; + width: 100%; + height: calc(100% - 30px); +} +.vp-instance-preview-content:empty::after { + content: 'No preview data'; + color: var(--vp-gray-color); +} +.vp-instance-preview-box img { + width: 100%; + height: 100%; } \ No newline at end of file diff --git a/visualpython/css/menuFrame.css b/visualpython/css/menuFrame.css index ce9d7f21..8669f867 100644 --- a/visualpython/css/menuFrame.css +++ b/visualpython/css/menuFrame.css @@ -238,7 +238,7 @@ input.vp-menu-search-box { text-align: center; box-sizing: border-box; border-radius: 3px; - padding: 10px 0px; + padding: 7.5px 0px; cursor: pointer; margin: 0; } @@ -276,7 +276,14 @@ input.vp-menu-search-box { .vp-menuitem-apps-name { color: #FFFFFF; font-size: 10px; - margin-top: 3px; + /* margin-top: 3px; */ + + display: flex; + align-items: center; + width: 56px; + height: 20px; + line-height: 9px; + justify-content: center; } /* MenuItem - Logic */ .vp-menuitem.logic-define { @@ -342,7 +349,7 @@ input.vp-menu-search-box { /* Data Analysis */ .vp-menuitem.apps .apps-icon { width: 100%; - height: 25px; + height: 24px; } .vp-menuitem.apps .apps_import { background: top / contain no-repeat url(../img/apps/apps_import.svg); @@ -386,6 +393,9 @@ input.vp-menu-search-box { .vp-menuitem.apps .apps_profiling { background: top / contain no-repeat url(../img/apps/apps_profiling.svg); } +.vp-menuitem.apps .apps_pandasOption { + background: top / contain no-repeat url(../img/apps/apps_pandasOption.svg); +} /* Visualization */ .vp-menuitem.apps .visualize_chartStyle { background: top / contain no-repeat url(../img/apps/apps_style.svg); diff --git a/visualpython/data/libraries.json b/visualpython/data/libraries.json index e2ac6ef9..bb82fabc 100644 --- a/visualpython/data/libraries.json +++ b/visualpython/data/libraries.json @@ -3063,6 +3063,20 @@ "color": 4, "icon": "apps/apps_profiling.svg" } + }, + { + "id" : "apps_pandasOption", + "type" : "function", + "level": 1, + "name" : "Pandas Option", + "tag" : "PANDAS OPTION,APPS", + "path" : "visualpython - apps - pandasoption", + "desc" : "Pandas options", + "file" : "m_apps/PandasOption", + "apps" : { + "color": 4, + "icon": "apps/apps_pandasOption.svg" + } } ] }, diff --git a/visualpython/data/m_library/instanceLibrary.js b/visualpython/data/m_library/instanceLibrary.js new file mode 100644 index 00000000..09b74d93 --- /dev/null +++ b/visualpython/data/m_library/instanceLibrary.js @@ -0,0 +1,26 @@ +define([ +], function () { + + var INSTANCE_MATCHING_LIBRARY = { + /** + * Type: { + * method: { + * target: 'key_name', + * }, ... + * } + */ + 'DataFrame': { + 'head': { + 'id': 'pdIdt_head', + 'target': 'i0' + } + }, + 'Series': { + + } + } + + return { + INSTANCE_MATCHING_LIBRARY: INSTANCE_MATCHING_LIBRARY + } +}); \ No newline at end of file diff --git a/visualpython/html/m_apps/instance.html b/visualpython/html/m_apps/instance.html index 6860d2db..e43e08a3 100644 --- a/visualpython/html/m_apps/instance.html +++ b/visualpython/html/m_apps/instance.html @@ -1,16 +1,30 @@ -
- -
- -
-
- -
+
+
+
+ + +
+
+ +
+
+ +
-
+
- - + + +
+
+
+ Instance Preview +
+
+
+
+
+ \ No newline at end of file diff --git a/visualpython/html/m_apps/pandasOption.html b/visualpython/html/m_apps/pandasOption.html new file mode 100644 index 00000000..6b9bf5da --- /dev/null +++ b/visualpython/html/m_apps/pandasOption.html @@ -0,0 +1,34 @@ + +
+
+ +
+ + +
+ + + + +
+
+
+ + + + + + + + +
+
+ + \ No newline at end of file diff --git a/visualpython/html/m_apps/sweetviz.html b/visualpython/html/m_apps/sweetviz.html index f4b7f6ba..4769125a 100644 --- a/visualpython/html/m_apps/sweetviz.html +++ b/visualpython/html/m_apps/sweetviz.html @@ -27,8 +27,8 @@
- - +
diff --git a/visualpython/html/menuFrame.html b/visualpython/html/menuFrame.html index 0564174b..a46f4d37 100644 --- a/visualpython/html/menuFrame.html +++ b/visualpython/html/menuFrame.html @@ -40,8 +40,8 @@
  • - - Find VP Notes + + Visit community
  • diff --git a/visualpython/img/apps/apps_pandasOption.svg b/visualpython/img/apps/apps_pandasOption.svg new file mode 100644 index 00000000..b8e153a2 --- /dev/null +++ b/visualpython/img/apps/apps_pandasOption.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/visualpython/js/board/BoardFrame.js b/visualpython/js/board/BoardFrame.js index 059ec129..a1411ed6 100644 --- a/visualpython/js/board/BoardFrame.js +++ b/visualpython/js/board/BoardFrame.js @@ -978,11 +978,11 @@ define([ sessionId = panelId; } } - var movingBlock = this._blockList[sessionId].boardList[startIdx]; + var movingBlock = this._blockList[sessionId].blockList[startIdx]; if (movingBlock) { let groupBlocks = this.getGroupedBlocks(movingBlock); - this._blockList[sessionId].boardList.splice(startIdx, groupBlocks.length); - this._blockList[sessionId].boardList.splice(endIdx, 0, ...groupBlocks); + this._blockList[sessionId].blockList.splice(startIdx, groupBlocks.length); + this._blockList[sessionId].blockList.splice(endIdx, 0, ...groupBlocks); // move tag if (parentBlock != null) { // set this movingBlock as child of parentBlock diff --git a/visualpython/js/com/com_generatorV2.js b/visualpython/js/com/com_generatorV2.js index 6e353a35..4ec33271 100644 --- a/visualpython/js/com/com_generatorV2.js +++ b/visualpython/js/com/com_generatorV2.js @@ -389,7 +389,7 @@ define([ // multiple selection true 'multiple': true }); - vp_generateVarSelect(tag, obj.varType, obj.value); + vp_generateVarSelect(tag, obj.var_type, obj.value); content = tag; break; case 'col_select': @@ -688,11 +688,18 @@ define([ let isChecked = $(pageThis.wrapSelector(parent + ' #'+obj.name)).prop('checked'); value = isChecked?'True':'False'; break; + case 'var_multi': + let multiValue = $(pageThis.wrapSelector(parent + ' #'+obj.name)).val(); + if (multiValue && multiValue.length > 0) { + value = multiValue.join(', '); + } else { + value = ''; + } + break; case 'input_multi': case 'bool_select': case 'data_select': case 'var_select': - case 'var_multi': case 'col_select': case 'dtype': value = $(pageThis.wrapSelector(parent + ' #'+obj.name)).val(); diff --git a/visualpython/js/com/component/DataSelector.js b/visualpython/js/com/component/DataSelector.js index 8e54d9e8..9c120bf7 100644 --- a/visualpython/js/com/component/DataSelector.js +++ b/visualpython/js/com/component/DataSelector.js @@ -53,8 +53,8 @@ define([ pageThis: null, // target's page object id: '', // target id value: null, // pre-defined value - finish: null, // callback after selection - select: null, // callback after selection from suggestInput + finish: null, // callback after selection (value, dtype) + select: null, // callback after selection from suggestInput (value, dtype) allowDataType: null, // additional options classes: '', @@ -175,59 +175,63 @@ define([ _bindAutocomplete(varList) { let that = this; - $(com_util.formatString(".vp-ds-box-{0} input.vp-ds-target", that.uuid)).autocomplete({ - autoFocus: true, - minLength: 0, - source: function (req, res) { - var srcList = varList; - var returlList = new Array(); - for (var idx = 0; idx < srcList.length; idx++) { - // srcList as object array - if (srcList[idx].label.toString().toLowerCase().includes(req.term.trim().toLowerCase())) { - returlList.push(srcList[idx]); + try { + $(com_util.formatString(".vp-ds-box-{0} input.vp-ds-target", that.uuid)).autocomplete({ + autoFocus: true, + minLength: 0, + source: function (req, res) { + var srcList = varList; + var returlList = new Array(); + for (var idx = 0; idx < srcList.length; idx++) { + // srcList as object array + if (srcList[idx].label.toString().toLowerCase().includes(req.term.trim().toLowerCase())) { + returlList.push(srcList[idx]); + } } - } - res(returlList); - }, - select: function (evt, ui) { - let result = true; - // trigger change - $(this).val(ui.item.value); - $(this).data('type', ui.item.dtype); - - that.state.filterType = 'All'; - that.state.data = ui.item.value; - that.state.dataType = ui.item.dtype; - that.state.returnDataType = ui.item.dtype; - - that.prop.pageThis.state[that.prop.id] = ui.item.value; - that.prop.pageThis.state[that.prop.id + '_state'] = that.state; - - // select event - if (that.prop.select && typeof that.prop.select == 'function') { - result = that.prop.select(ui.item.value, ui.item.dtype); - } - $(this).trigger('change'); + res(returlList); + }, + select: function (evt, ui) { + let result = true; + // trigger change + $(this).val(ui.item.value); + $(this).data('type', ui.item.dtype); + + that.state.filterType = 'All'; + that.state.data = ui.item.value; + that.state.dataType = ui.item.dtype; + that.state.returnDataType = ui.item.dtype; + + that.prop.pageThis.state[that.prop.id] = ui.item.value; + that.prop.pageThis.state[that.prop.id + '_state'] = that.state; + + // select event + if (that.prop.select && typeof that.prop.select == 'function') { + result = that.prop.select(ui.item.value, ui.item.dtype); + } + $(this).trigger('change'); - if (result != undefined) { - return result; + if (result != undefined) { + return result; + } + return true; + }, + search: function(evt, ui) { + return true; } - return true; - }, - search: function(evt, ui) { - return true; - } - }).focus(function () { - $(this).select(); - $(this).autocomplete('search', $(this).val()); - }).click(function () { - $(this).select(); - $(this).autocomplete('search', $(this).val()); - }).autocomplete('instance')._renderItem = function(ul, item) { - return $('
  • ').attr('data-value', item.value) - .append(`
    ${item.label}
    `) - .appendTo(ul); - }; + }).focus(function () { + $(this).select(); + $(this).autocomplete('search', $(this).val()); + }).click(function () { + $(this).select(); + $(this).autocomplete('search', $(this).val()); + }).autocomplete('instance')._renderItem = function(ul, item) { + return $('
  • ').attr('data-value', item.value) + .append(`
    ${item.label}
    `) + .appendTo(ul); + }; + } catch (ex) { + vpLog.display(VP_LOG_TYPE.ERROR, ex); + } } _bindEventForPopup() { diff --git a/visualpython/js/com/component/InstanceEditor.js b/visualpython/js/com/component/InstanceEditor.js index 31a9dca8..c4c0b13c 100644 --- a/visualpython/js/com/component/InstanceEditor.js +++ b/visualpython/js/com/component/InstanceEditor.js @@ -3,8 +3,10 @@ define([ 'vp_base/js/com/com_Const', 'vp_base/js/com/com_String', 'vp_base/js/com/com_util', - 'vp_base/js/com/component/SuggestInput' -], function(insCss, com_Const, com_String, com_util, SuggestInput) { + 'vp_base/js/com/component/SuggestInput', + 'vp_base/data/m_library/instanceLibrary', + 'vp_base/js/com/component/LibraryComponent' +], function(insCss, com_Const, com_String, com_util, SuggestInput, instanceLibrary, LibraryComponent) { // temporary const @@ -35,12 +37,17 @@ define([ * @constructor */ class InstanceEditor { - constructor(pageThis, targetId, containerId = 'vp_wrapper', popup = false) { + constructor(pageThis, targetId, containerId = 'vp_wrapper', config = {}) { this.pageThis = pageThis; this.targetId = targetId; this.uuid = 'u' + com_util.getUUID(); this.containerId = containerId; - this.popup = popup; + this.config = { + popup: false, + showAlert: false, // show alert by modal or not + targetType: 'instance', // instance / outside + ...config + } this.state = { code: '', @@ -70,7 +77,6 @@ define([ return this.state.list; } init() { - this.reload(); } wrapSelector(selector = '') { @@ -166,6 +172,7 @@ define([ tag.appendFormatLine('
    ', VP_INS_PARAMETER_BOX); tag.appendFormatLine('', VP_INS_PARAMETER, 'input parameter'); + tag.appendFormatLine('', 'vp-ins-opt-button'); tag.appendLine('
    '); // VP_INS_PARAMETER tag.appendLine('
  • '); // VP_INS_BOX END @@ -279,6 +286,14 @@ define([ } } }); + + // open option popup + $(document).on('click', this.wrapSelector('.vp-ins-opt-button:not(.disabled)'), function(event) { + // TODO: pdIdt_head to general + if (that.optionPopup) { + that.optionPopup.open(); + } + }); } reload(callback = undefined) { var that = this; @@ -292,8 +307,15 @@ define([ if (variable == '') { if (!this.isFirstPage) { - this.renderFirstPage(); - this.isFirstPage = true; + // if it's outside mode + if (this.config.targetType === 'outside') { + this.isFirstPage = false; + this.renderPage(); + return; + } else { + this.renderFirstPage(); + this.isFirstPage = true; + } } } else { this.isFirstPage = false; @@ -408,8 +430,44 @@ define([ // get parameter var splitList = variable.split('.'); + var hasOption = false; + if (splitList && splitList.length > 0) { var lastSplit = splitList[splitList.length - 1]; + // get target code + var methodName = lastSplit.match(/[a-zA-Z_]+/i)[0]; + var targetCode = splitList.slice(0, splitList.length - 1).join('.'); + if ((varType in instanceLibrary.INSTANCE_MATCHING_LIBRARY) && (methodName in instanceLibrary.INSTANCE_MATCHING_LIBRARY[varType])) { + // get target library + var targetLib = instanceLibrary.INSTANCE_MATCHING_LIBRARY[varType][methodName]; + var targetId = targetLib.target; + that.optionPopup = new LibraryComponent({ + [targetId]: targetCode, + config: { + name: methodName, category: 'Instance', + saveOnly: true, + id: targetLib.id + } + }, + { + pageThis: that, + useInputVariable: true, + targetSelector: that.pageThis.wrapSelector('#' + that.targetId), + finish: function(code) { + // TODO: save state + + $(that.pageThis.wrapSelector('#' + that.targetId)).trigger({ + type: "instance_editor_replaced", + originCode: that.state.code, + newCode: code + }); + } + }); + hasOption = true; + } else { + that.optionPopup = null; + } + // if bracket is at the end of code var matchList = lastSplit.match(/\(.*?\)$/gi); if (matchList != null && matchList.length > 0) { @@ -418,12 +476,27 @@ define([ var parameter = lastBracket.substr(1, lastBracket.length - 2); $(that.wrapSelector('.' + VP_INS_PARAMETER)).val(parameter); $(that.wrapSelector('.' + VP_INS_PARAMETER)).show(); + if (hasOption) { + if ($(that.wrapSelector('.vp-ins-opt-button')).hasClass('disabled')) { + $(that.wrapSelector('.vp-ins-opt-button')).removeClass('disabled'); + } + } else { + if (!$(that.wrapSelector('.vp-ins-opt-button')).hasClass('disabled')) { + $(that.wrapSelector('.vp-ins-opt-button')).addClass('disabled'); + } + } } else { $(that.wrapSelector('.' + VP_INS_PARAMETER)).val(''); $(that.wrapSelector('.' + VP_INS_PARAMETER)).hide(); + if (!$(that.wrapSelector('.vp-ins-opt-button')).hasClass('disabled')) { + $(that.wrapSelector('.vp-ins-opt-button')).addClass('disabled'); + } } } else { $(that.wrapSelector('.' + VP_INS_PARAMETER)).hide(); + if (!$(that.wrapSelector('.vp-ins-opt-button')).hasClass('disabled')) { + $(that.wrapSelector('.vp-ins-opt-button')).addClass('disabled'); + } } } @@ -434,9 +507,13 @@ define([ }).catch(function(resultObj) { let { result } = resultObj; // show alert if this is visible - if (that.pageThis.isHidden() == false) { + if (that.pageThis.isHidden() == false && that.config.showAlert == true) { com_util.renderAlertModal(result.ename + ': ' + result.evalue); } + // hide + if (!$(that.wrapSelector('.vp-ins-opt-button')).hasClass('disabled')) { + $(that.wrapSelector('.vp-ins-opt-button')).addClass('disabled'); + } // callback if (callback) { callback(''); diff --git a/visualpython/js/com/component/LibraryComponent.js b/visualpython/js/com/component/LibraryComponent.js index 4a0c7e05..f24a6b3d 100644 --- a/visualpython/js/com/component/LibraryComponent.js +++ b/visualpython/js/com/component/LibraryComponent.js @@ -31,7 +31,7 @@ define([ this.config.dataview = false; this.config.sizeLevel = 1; - this.packageId = this.state.config.id; + this.packageId = this.id; // deep copy package info this.package = null; try { diff --git a/visualpython/js/com/component/ModelEditor.js b/visualpython/js/com/component/ModelEditor.js index 64541c7c..d847043b 100644 --- a/visualpython/js/com/component/ModelEditor.js +++ b/visualpython/js/com/component/ModelEditor.js @@ -899,11 +899,11 @@ define([ getCode(replaceDict={}) { let code = new com_String(); - if (this.state.config.import != undefined) { - code.appendLine(this.state.config.import); + if (this.config.import != undefined) { + code.appendLine(this.config.import); code.appendLine(); } - let modelCode = com_generator.vp_codeGenerator(this.pageThis, this.state.config, this.pageThis.state); + let modelCode = com_generator.vp_codeGenerator(this.pageThis, this.config, this.pageThis.state); Object.keys(replaceDict).forEach(key => { modelCode = modelCode.replace(key, replaceDict[key]); }); diff --git a/visualpython/js/com/component/NumpyComponent.js b/visualpython/js/com/component/NumpyComponent.js index 092d83aa..a8b4b7e7 100644 --- a/visualpython/js/com/component/NumpyComponent.js +++ b/visualpython/js/com/component/NumpyComponent.js @@ -31,11 +31,11 @@ define([ this.config.dataview = false; this.config.sizeLevel = 1; - this.packageId = this.state.config.id; + this.packageId = this.id; // deep copy package info this.package = null; try { - let packageName = this.state.config.path.split(' - ')[2]; + let packageName = this.path.split(' - ')[2]; let findPackage = null; if (packageName == 'numpy') { findPackage = numpyLibrary.NUMPY_LIBRARIES[this.packageId]; diff --git a/visualpython/js/com/component/PopupComponent.js b/visualpython/js/com/component/PopupComponent.js index 207d27ef..7415b0f2 100644 --- a/visualpython/js/com/component/PopupComponent.js +++ b/visualpython/js/com/component/PopupComponent.js @@ -89,10 +89,13 @@ define([ _init() { this.eventTarget = '#vp_wrapper'; - this.id = this.state.config.id; - this.name = this.state.config.name; - this.path = this.state.config.path; - this.category = this.state.config.category; + var { config, ...state } = this.state; + this.state = state; + var { id, name, path, category, ...restConfig } = config; + this.id = id; + this.name = name; + this.path = path; + this.category = category; this.config = { @@ -110,8 +113,9 @@ define([ footer: true, position: { right: 10, top: 120 }, size: { width: 400, height: 550 }, - saveOnly: false, + saveOnly: false, // apply mode checkModules: [] // module aliases or function names + , ...restConfig }; // check BoardFrame width and set initial position of popup @@ -895,6 +899,10 @@ define([ } save() { + if (this.prop.finish && typeof this.prop.finish == 'function') { + var code = this.generateCode(); + this.prop.finish(code); + } $(this.eventTarget).trigger({ type: 'apply_option_page', blockType: 'block', diff --git a/visualpython/js/m_apps/Groupby.js b/visualpython/js/m_apps/Groupby.js index c62ccd9a..ddc20307 100644 --- a/visualpython/js/m_apps/Groupby.js +++ b/visualpython/js/m_apps/Groupby.js @@ -64,18 +64,18 @@ define([ ] this.methodList = [ - // { label: 'None', value: '' }, - { label: 'count', value: "'count'" }, - { label: 'first', value: "'first'" }, - { label: 'last', value: "'last'" }, - { label: 'size', value: "'size'" }, - { label: 'std', value: "'std'" }, - { label: 'sum', value: "'sum'" }, - { label: 'max', value: "'max'" }, - { label: 'mean', value: "'mean'" }, - { label: 'median', value: "'median'" }, - { label: 'min', value: "'min'" }, - { label: 'quantile', value: "'quantile'" }, + { label: 'None', value: '' }, + { label: 'count', value: "count" }, + { label: 'first', value: "first" }, + { label: 'last', value: "last" }, + { label: 'size', value: "size" }, + { label: 'std', value: "std" }, + { label: 'sum', value: "sum" }, + { label: 'max', value: "max" }, + { label: 'mean', value: "mean" }, + { label: 'median', value: "median" }, + { label: 'min', value: "min" }, + { label: 'quantile', value: "quantile" }, ] this.state = { @@ -617,13 +617,17 @@ define([ page.appendFormatLine('
    ', 'vp-gb-method-selector'); // method list page.appendFormatLine('
    ', 'vp-gb-method-box'); - this.methodList.forEach(method => { + this.methodList.forEach((method, idx) => { + if (idx == 0) { + return ; + } + var methodStr = "'" + method.value + "'"; var checked = ""; - if (previousList && previousList.includes(method.value)) { + if (previousList && previousList.includes(methodStr)) { checked = "checked" } page.appendFormatLine('' - , method.value, checked, method.label); + , methodStr, checked, method.label); }); page.appendLine('
    '); page.appendLine('
    '); @@ -772,6 +776,12 @@ define([ } var advMethod = $(advItemTags[i]).find('.vp-gb-adv-method').data('list'); var advUserMethod = $(advItemTags[i]).find('.vp-gb-adv-method').data('userList'); + if (!advMethod || advMethod == null) { + advMethod = []; + } + if (!advUserMethod || advUserMethod == null) { + advUserMethod = []; + } advMethod = [ ...advMethod, ...advUserMethod ]; var advNaming = $(advItemTags[i]).find('.vp-gb-adv-naming').data('dict'); if (!advMethod || advMethod.length <= 0) { diff --git a/visualpython/js/m_apps/Instance.js b/visualpython/js/m_apps/Instance.js index 512c6f76..e2253474 100644 --- a/visualpython/js/m_apps/Instance.js +++ b/visualpython/js/m_apps/Instance.js @@ -16,11 +16,12 @@ define([ __VP_TEXT_LOADER__('vp_base/html/m_apps/instance.html'), // INTEGRATION: unified version of text loader __VP_CSS_LOADER__('vp_base/css/m_apps/instance'), // INTEGRATION: unified version of css loader 'vp_base/js/com/com_String', + 'vp_base/js/com/com_util', 'vp_base/js/com/component/PopupComponent', 'vp_base/js/com/component/InstanceEditor', 'vp_base/js/com/component/DataSelector', 'vp_base/js/m_apps/Subset' -], function(insHtml, insCss, com_String, PopupComponent, InstanceEditor, DataSelector, Subset) { +], function(insHtml, insCss, com_String, com_util, PopupComponent, InstanceEditor, DataSelector, Subset) { const MAX_STACK_SIZE = 20; @@ -32,10 +33,11 @@ define([ super._init(); /** Write codes executed before rendering */ this.config.dataview = false; - this.config.sizeLevel = 1; + this.config.size = { width: 1064, height: 550 }; this.config.checkModules = ['pd']; this.state = { + target: '', vp_instanceVariable: '', variable: { stack: [] @@ -54,6 +56,12 @@ define([ _bindEvent() { super._bindEvent(); let that = this; + // target change + $(this.wrapSelector('#vp_instanceTarget')).on('change', function(event) { + let value = $(this).val(); + that.updateValue(value); + that.reloadInsEditor('variable'); + }); // clear $(this.wrapSelector('#vp_instanceClear')).on('click', function(event) { that.addStack(); @@ -177,9 +185,26 @@ define([ } templateForBody() { + let that = this; let page = $(insHtml); $(page).find('#vp_instanceVariable').val(this.state.vp_instanceVariable); + let targetSelector = new DataSelector({ + pageThis: this, id: 'vp_instanceTarget', placeholder: 'Select variable', + allowDataType: [ + 'DataFrame', 'Series', 'dict', 'list', 'int' + ], + finish: function(value, dtype) { + $(that.wrapSelector('#vp_instanceTarget')).trigger({type: 'change', value: value}); + }, + select: function(value, dtype) { + $(that.wrapSelector('#vp_instanceTarget')).trigger({type: 'change', value: value}); + // that.updateValue(value); + // that.reloadInsEditor('variable'); + } + }); + $(page).find('#vp_instanceTarget').replaceWith(targetSelector.toTagString()); + let allocateSelector = new DataSelector({ pageThis: this, id: 'vp_instanceAllocate', placeholder: 'Variable name' }); @@ -195,7 +220,7 @@ define([ let that = this; // vpSubsetEditor - this.subsetEditor = new Subset({ pandasObject: '', config: { name: 'Subset' } }, + this.subsetEditor = new Subset({ pandasObject: '', config: { name: 'Subset', category: this.name } }, { useInputVariable: true, targetSelector: this.wrapSelector('#vp_instanceVariable'), @@ -211,7 +236,7 @@ define([ this.ALLOW_SUBSET_TYPES = this.subsetEditor.getAllowSubsetTypes(); // vpInstanceEditor - this.insEditor = new InstanceEditor(this, "vp_instanceVariable", 'vp_variableInsEditContainer'); + this.insEditor = new InstanceEditor(this, "vp_instanceVariable", 'vp_variableInsEditContainer', { targetType: 'outside' }); this.insEditor.show(); @@ -268,6 +293,56 @@ define([ cm.setCursor({ line: 0, ch: value.length}); } this.state.vp_instanceVariable = value; + + // show preview + this.loadPreview(value); + } + + loadPreview(code) { + let that = this; + if (!code || code === '') { + $(that.wrapSelector('#instancePreview')).html(''); + return; + } + // show variable information on clicking variable + vpKernel.execute(code).then(function(resultObj) { + let { result, type, msg } = resultObj; + if (msg.content.data) { + var textResult = msg.content.data["text/plain"]; + var htmlResult = msg.content.data["text/html"]; + var imgResult = msg.content.data["image/png"]; + + $(that.wrapSelector('#instancePreview')).html(''); + if (htmlResult != undefined) { + // 1. HTML tag + $(that.wrapSelector('#instancePreview')).append(htmlResult); + } else if (imgResult != undefined) { + // 2. Image data (base64) + var imgTag = ''; + $(that.wrapSelector('#instancePreview')).append(imgTag); + } else if (textResult != undefined) { + // 3. Text data + var preTag = document.createElement('pre'); + $(preTag).text(textResult); + $(that.wrapSelector('#instancePreview')).html(preTag); + } + } else { + var errorContent = ''; + if (msg.content.ename) { + errorContent = com_util.templateForErrorBox(msg.content.ename, msg.content.evalue, msg.content.detail); + } + $(that.wrapSelector('#instancePreview')).html(errorContent); + vpLog.display(VP_LOG_TYPE.ERROR, msg.content.ename, msg.content.evalue, msg.content); + } + }).catch(function(resultObj) { + let { msg } = resultObj; + var errorContent = ''; + if (msg.content.ename) { + errorContent = com_util.templateForErrorBox(msg.content.ename, msg.content.evalue, msg.content.detail); + } + $(that.wrapSelector('#instancePreview')).html(errorContent); + vpLog.display(VP_LOG_TYPE.ERROR, msg.content.ename, msg.content.evalue, msg.content); + }); } addStack() { diff --git a/visualpython/js/m_apps/PandasOption.js b/visualpython/js/m_apps/PandasOption.js new file mode 100644 index 00000000..b4eb97b2 --- /dev/null +++ b/visualpython/js/m_apps/PandasOption.js @@ -0,0 +1,101 @@ +/* + * Project Name : Visual Python + * Description : GUI-based Python code generator + * File Name : PandasOption.js + * Author : Black Logic + * Note : Pandas option + * License : GNU GPLv3 with Visual Python special exception + * Date : 2023. 03. 28 + * Change Date : + */ + +//============================================================================ +// [CLASS] PandasOption +//============================================================================ +define([ + __VP_TEXT_LOADER__('vp_base/html/m_apps/pandasOption.html'), + 'vp_base/js/com/com_util', + 'vp_base/js/com/com_Const', + 'vp_base/js/com/com_String', + 'vp_base/js/com/component/PopupComponent', + 'vp_base/js/com/component/DataSelector' +], function(poHTML, com_util, com_Const, com_String, PopupComponent, DataSelector) { + + /** + * PandasOption + */ + class PandasOption extends PopupComponent { + _init() { + super._init(); + /** Write codes executed before rendering */ + this.config.sizeLevel = 2; + this.config.dataview = false; + this.config.checkModules = ['pd']; + + this.state = { + min_rows: '', + max_rows: '', + max_cols: '', + max_colwidth: '', + float_format: '', + precision: '', + chop_threshold: '', + expand_frame_repr: '', + ...this.state + } + } + + _bindEvent() { + super._bindEvent(); + /** Implement binding events */ + var that = this; + + // setting popup - set default + $(this.wrapSelector('#setDefault')).on('change', function() { + let checked = $(this).prop('checked'); + + if (checked) { + // disable input + $(that.wrapSelector('.vp-pandas-option-body input')).prop('disabled', true); + } else { + // enable input + $(that.wrapSelector('.vp-pandas-option-body input')).prop('disabled', false); + } + }); + } + + templateForBody() { + let page = $(poHTML); + + return page; + } + + render() { + super.render(); + + + } + + generateCode() { + let that = this; + let code = []; + + let setDefault = $(this.wrapSelector('#setDefault')).prop('checked'); + if (setDefault == true) { + Object.keys(this.state).forEach((key) => { + code.push(com_util.formatString("pd.reset_option('display.{0}')", key)); + }) + } else { + Object.keys(this.state).forEach((key) => { + if (that.state[key] && that.state[key] != '') { + code.push(com_util.formatString("pd.set_option('display.{0}', {1})", key, that.state[key])); + } + }) + } + return code.join('\n'); + } + + } + + return PandasOption; +}); \ No newline at end of file diff --git a/visualpython/js/m_apps/Subset.js b/visualpython/js/m_apps/Subset.js index c446d458..762d885e 100644 --- a/visualpython/js/m_apps/Subset.js +++ b/visualpython/js/m_apps/Subset.js @@ -1145,13 +1145,6 @@ define([ that.focus(); }); $(this.targetSelector).on('apply_option_page', function(evt) { - let code = that.generateCode(); - - // if finish callback is available - if (that.finish && typeof that.finish == 'function') { - that.finish(code); - } - that.close(); }); } diff --git a/visualpython/js/m_apps/Sweetviz.js b/visualpython/js/m_apps/Sweetviz.js index c0284f44..d0071449 100644 --- a/visualpython/js/m_apps/Sweetviz.js +++ b/visualpython/js/m_apps/Sweetviz.js @@ -100,7 +100,7 @@ define([ } var title = $(that.wrapSelector('#vp_pfTitle')).val(); var filePath = $(that.wrapSelector('#vp_pfPath')).val(); - var openBrowser = $(that.wrapSelector('#vp_pfOpenBrowser')).prop('checked'); + // var openBrowser = $(that.wrapSelector('#vp_pfOpenBrowser')).prop('checked'); var code = new com_String(); switch(parseInt(type)) { case PROFILE_TYPE.GENERATE: @@ -110,14 +110,14 @@ define([ } else { code.appendFormatLine("{0} = sweetviz.analyze({1})", saveas, df); } - // show html - code.appendFormat("{0}.show_html(", saveas); + // show notebook + code.appendFormat("{0}.show_notebook(", saveas); if (filePath && filePath != '') { code.appendFormat("filepath='{0}'", filePath); } - if (openBrowser === false) { - code.append(", open_browser=False"); - } + // if (openBrowser === false) { + // code.append(", open_browser=False"); + // } code.appendLine(')'); code.append(saveas); break; diff --git a/visualpython/js/menu/TaskItem.js b/visualpython/js/menu/TaskItem.js index 540c35c0..dcb63181 100644 --- a/visualpython/js/menu/TaskItem.js +++ b/visualpython/js/menu/TaskItem.js @@ -64,8 +64,9 @@ define([ _getOptionInfo() { let task = this.state.task; let info = {}; - if (task && task.state && task.state.config) { - let { id, name, desc, apps }= task.state.config; + if (task && task.state && task.config) { + let { id, name } = task; + let { desc, apps }= task.config; info = { id: id, title: name,