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 @@
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/img/import.svg b/visualpython/img/import.svg
index 68d506d4..5f188e5b 100644
--- a/visualpython/img/import.svg
+++ b/visualpython/img/import.svg
@@ -1,7 +1,7 @@
-
-
-
-
+
+
+
+
diff --git a/visualpython/img/setting.svg b/visualpython/img/setting.svg
index b7b7f375..10b10e2d 100644
--- a/visualpython/img/setting.svg
+++ b/visualpython/img/setting.svg
@@ -1,5 +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_Config.js b/visualpython/js/com/com_Config.js
index 346e0f15..9c38f813 100644
--- a/visualpython/js/com/com_Config.js
+++ b/visualpython/js/com/com_Config.js
@@ -931,7 +931,7 @@ define([
/**
* Version
*/
- Config.version = "2.3.4";
+ Config.version = "2.3.5";
/**
* Type of mode
diff --git a/visualpython/js/com/com_Const.js b/visualpython/js/com/com_Const.js
index 8315ca65..e8cd8bbb 100644
--- a/visualpython/js/com/com_Const.js
+++ b/visualpython/js/com/com_Const.js
@@ -19,7 +19,7 @@ define ([
class Constants { }
Constants.TOOLBAR_BTN_INFO = {
- HELP: "Visual Python 2.3.4"
+ HELP: "Visual Python 2.3.5"
, ICON: "vp-main-icon"
, ID: "vpBtnToggle"
, NAME: "toggle-vp"
diff --git a/visualpython/js/com/com_Kernel.js b/visualpython/js/com/com_Kernel.js
index d7a468f2..e5ebdf1d 100644
--- a/visualpython/js/com/com_Kernel.js
+++ b/visualpython/js/com/com_Kernel.js
@@ -654,13 +654,13 @@ define([
});
}
- getDataList(dataTypeList=[], excludeList=[]) {
+ getDataList(dataTypeList=[], excludeList=[], allowModule=false) {
// use function command to get variable list of selected data types
var cmdSB = '_vp_print(_vp_get_variables_list(None))';
if (!dataTypeList || dataTypeList.length <= 0) {
dataTypeList = [];
}
- cmdSB = com_util.formatString('_vp_print(_vp_get_variables_list({0}, {1}))', JSON.stringify(dataTypeList), JSON.stringify(excludeList));
+ cmdSB = com_util.formatString('_vp_print(_vp_get_variables_list({0}, {1}, {2}))', JSON.stringify(dataTypeList), JSON.stringify(excludeList), allowModule?'True':'False');
var that = this;
return new Promise(function(resolve, reject) {
@@ -914,7 +914,7 @@ define([
* @param {String} configType vpudf, vpcfg
* @returns
*/
- setLabConfig(content, configType='vpudf') {
+ setLabConfig(content={}, configType='vpudf') {
var that = this;
var configFile = '';
switch (configType) {
@@ -930,7 +930,7 @@ define([
}
// write file
var sbfileSaveCmd = new com_String();
- sbfileSaveCmd.appendFormat("_vp_set_lab_vpcfg('{0}', '{1}')", configFile, content);
+ sbfileSaveCmd.appendFormat("_vp_set_lab_vpcfg('{0}', {1})", configFile, content);
return new Promise(function(resolve, reject) {
that.execute(sbfileSaveCmd.toString())
.then(function(resultObj) {
diff --git a/visualpython/js/com/com_generatorV2.js b/visualpython/js/com/com_generatorV2.js
index dd19b769..c05b8988 100644
--- a/visualpython/js/com/com_generatorV2.js
+++ b/visualpython/js/com/com_generatorV2.js
@@ -360,7 +360,7 @@ define([
let dataSelector = new DataSelector({
pageThis: pageThis,
id: obj.name,
- allowDataType: obj.varType,
+ allowDataType: obj.var_type,
placeholder: obj.placeholder || 'Select data',
value: value,
required: obj.required === true
@@ -373,6 +373,7 @@ define([
type: 'text',
id: obj.name,
class: 'vp-input vp-state',
+ placeholder: obj.placeholder || 'Select data',
required: obj.required === true
});
vp_generateVarSuggestInput(pageThis.wrapSelector(), obj);
@@ -386,7 +387,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':
@@ -685,11 +686,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();
@@ -774,6 +782,13 @@ define([
if (code.startsWith(' = ')) {
code = code.substr(3);
}
+ // prevent code: without allocation code (${o0} = code)
+ let outputCodeMatch = code.match(/^\$\{.+\} = /);
+ if (outputCodeMatch) {
+ let matchLength = outputCodeMatch[0].length;
+ let matchStartIdx = outputCodeMatch['index'];
+ code = code.substr(matchStartIdx + matchLength);
+ }
// show_result
// get output variables
if (_VP_SHOW_RESULT && package.options) {
diff --git a/visualpython/js/com/component/DataSelector.js b/visualpython/js/com/component/DataSelector.js
index 8e54d9e8..fc232574 100644
--- a/visualpython/js/com/component/DataSelector.js
+++ b/visualpython/js/com/component/DataSelector.js
@@ -53,13 +53,14 @@ 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
- allowDataType: null,
+ finish: null, // callback after selection (value, dtype)
+ select: null, // callback after selection from suggestInput (value, dtype)
+ allowDataType: null, // list of allowed data types
// additional options
classes: '',
placeholder: 'Select variable',
required: false,
+ allowModule: false,
...this.prop
}
@@ -175,59 +176,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} | ${item.dtype}
`)
- .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} | ${item.dtype}
`)
+ .appendTo(ul);
+ };
+ } catch (ex) {
+ vpLog.display(VP_LOG_TYPE.ERROR, ex);
+ }
}
_bindEventForPopup() {
@@ -308,13 +313,18 @@ define([
loadVariables() {
let that = this;
// Searchable variable types
- let types = [
+ let types = [];
+ if (this.prop.allowModule) {
+ types = ['module'];
+ }
+ types = [
+ ...types,
...vpConfig.getDataTypes(),
// ML Data types
...vpConfig.getMLDataTypes()
];
- vpKernel.getDataList(types).then(function(resultObj) {
+ vpKernel.getDataList(types, [], this.prop.allowModule).then(function(resultObj) {
var varList = JSON.parse(resultObj.result);
// re-mapping variable list
varList = varList.map(obj => {
diff --git a/visualpython/js/com/component/InstanceEditor.js b/visualpython/js/com/component/InstanceEditor.js
index 31a9dca8..f8fac9f7 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('Option ', 'vp-ins-opt-button');
tag.appendLine('
'); // VP_INS_PARAMETER
tag.appendLine(' '); // VP_INS_BOX END
@@ -279,6 +286,13 @@ define([
}
}
});
+
+ // open option popup
+ $(document).on('click', this.wrapSelector('.vp-ins-opt-button:not(.disabled)'), function(event) {
+ if (that.optionPopup) {
+ that.optionPopup.open();
+ }
+ });
}
reload(callback = undefined) {
var that = this;
@@ -289,19 +303,98 @@ define([
return;
}
this.state.code = variable;
+ var prevVarType = that.state.type;
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;
this.renderPage();
}
+ var splitList = [];
+ if (variable != '') {
+ splitList = variable.split('.');
+ }
+ var hasOption = false;
+ // get parameter
+ 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 ((prevVarType in instanceLibrary.INSTANCE_MATCHING_LIBRARY) && (methodName in instanceLibrary.INSTANCE_MATCHING_LIBRARY[prevVarType])) {
+ // get target library
+ var targetLib = instanceLibrary.INSTANCE_MATCHING_LIBRARY[prevVarType][methodName];
+ var targetId = targetLib.target;
+ var popupState = {
+ config: {
+ name: methodName, category: 'Instance',
+ id: targetLib.id,
+ saveOnly: true,
+ noOutput: true
+ }
+ }
+ // add targetid as state if exists
+ if (targetId) {
+ popupState[targetId] = targetCode;
+ }
+ that.optionPopup = new LibraryComponent(popupState,
+ {
+ pageThis: that,
+ useInputVariable: true,
+ targetSelector: that.pageThis.wrapSelector('#' + that.targetId),
+
+ finish: function(code) {
+ // set parameter
+ let lastSplit = code?.split('.')?.pop();
+ // if bracket is at the end of code
+ let matchList = lastSplit.match(/\(.*?\)$/gi);
+ if (matchList != null && matchList.length > 0) {
+ let lastBracket = matchList[matchList.length - 1];
+ // remove first/last brackets
+ let parameter = lastBracket.substr(1, lastBracket.length - 2);
+ $(that.wrapSelector('.' + VP_INS_PARAMETER)).val(parameter);
+ }
+
+ $(that.pageThis.wrapSelector('#' + that.targetId)).trigger({
+ type: "instance_editor_replaced",
+ originCode: that.state.code,
+ newCode: code
+ });
+ }
+ }
+ );
+ hasOption = true;
+ } else {
+ that.optionPopup = null;
+ }
+
+ 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 {
+ if (!$(that.wrapSelector('.vp-ins-opt-button')).hasClass('disabled')) {
+ $(that.wrapSelector('.vp-ins-opt-button')).addClass('disabled');
+ }
+ }
var code = com_util.formatString('_vp_print(_vp_load_instance("{0}"))', variable);
-
vpKernel.execute(code).then(function (resultObj) {
let { result } = resultObj;
var varObj = {
@@ -316,6 +409,10 @@ define([
var varType = varObj.type;
var varList = varObj.list;
+ if (varType == 'module') {
+ // get module name
+ varType = varObj.name;
+ }
that.state.type = varType;
that.state.list = varList;
@@ -407,9 +504,9 @@ define([
});
// get parameter
- var splitList = variable.split('.');
if (splitList && splitList.length > 0) {
var lastSplit = splitList[splitList.length - 1];
+
// if bracket is at the end of code
var matchList = lastSplit.match(/\(.*?\)$/gi);
if (matchList != null && matchList.length > 0) {
@@ -417,26 +514,22 @@ define([
// remove first/last brackets
var parameter = lastBracket.substr(1, lastBracket.length - 2);
$(that.wrapSelector('.' + VP_INS_PARAMETER)).val(parameter);
- $(that.wrapSelector('.' + VP_INS_PARAMETER)).show();
+ $(that.wrapSelector('.' + VP_INS_PARAMETER)).prop('disabled', false);
} else {
$(that.wrapSelector('.' + VP_INS_PARAMETER)).val('');
- $(that.wrapSelector('.' + VP_INS_PARAMETER)).hide();
+ $(that.wrapSelector('.' + VP_INS_PARAMETER)).prop('disabled', true);
}
} else {
- $(that.wrapSelector('.' + VP_INS_PARAMETER)).hide();
+ $(that.wrapSelector('.' + VP_INS_PARAMETER)).prop('disabled', true);
}
}
-
- // callback
- if (callback) {
- callback(varObj);
- }
}).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);
}
+ }).finally(function() {
// callback
if (callback) {
callback('');
diff --git a/visualpython/js/com/component/LibraryComponent.js b/visualpython/js/com/component/LibraryComponent.js
index 4a0c7e05..c7050460 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 {
@@ -132,6 +132,10 @@ define([
// show interface
// com_generator.vp_showInterfaceOnPage(this.wrapSelector(), this.package);
+ if (this.config.noOutput && this.config.noOutput === true) {
+ // no allocateTo
+ this.package.options = this.package.options.filter(x => x.output != true);
+ }
com_generatorV2.vp_showInterfaceOnPage(this, this.package, this.state);
// hide required page if no options
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 4f71e2cb..356c93ce 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;
-
+ 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 = {
sizeLevel: 0, // 0: 400x400 / 1: 500x500 / 2: 600x500 / 3: 750x500
@@ -109,8 +112,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
@@ -894,6 +898,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/com/component/SuggestInput.js b/visualpython/js/com/component/SuggestInput.js
index 4cd434e4..54888724 100644
--- a/visualpython/js/com/component/SuggestInput.js
+++ b/visualpython/js/com/component/SuggestInput.js
@@ -109,7 +109,7 @@ define([
// make attributes
var attributes = Object.keys(this._attributes).map(key => key + '="' + this._attributes[key] + '"').join(" ");
- sbTagString.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('{2} '
- , 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 a4f0e6c5..1f534ce1 100644
--- a/visualpython/js/m_apps/Instance.js
+++ b/visualpython/js/m_apps/Instance.js
@@ -16,10 +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, Subset) {
+], function(insHtml, insCss, com_String, com_util, PopupComponent, InstanceEditor, DataSelector, Subset) {
const MAX_STACK_SIZE = 20;
@@ -31,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: []
@@ -53,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();
+ });
// clear
$(this.wrapSelector('#vp_instanceClear')).on('click', function(event) {
that.addStack();
@@ -139,7 +148,7 @@ define([
var selectedVariable = event.varName;
let fullCode = nowCode + selectedVariable;
that.updateValue(fullCode);
- that.reloadInsEditor('variable');
+ that.reloadInsEditor();
});
// instance_editor_replaced - variable
@@ -148,7 +157,7 @@ define([
var newCode = event.newCode;
that.updateValue(newCode);
- that.reloadInsEditor('variable');
+ that.reloadInsEditor();
});
// co-op with Subset
@@ -176,8 +185,33 @@ 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: [
+ 'module', 'DataFrame', 'Series', 'dict', 'list', 'int'
+ ],
+ allowModule: true,
+ 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();
+ }
+ });
+ $(page).find('#vp_instanceTarget').replaceWith(targetSelector.toTagString());
+
+ let allocateSelector = new DataSelector({
+ pageThis: this, id: 'vp_instanceAllocate', placeholder: 'Variable name'
+ });
+ $(page).find('#vp_instanceAllocate').replaceWith(allocateSelector.toTagString());
+
+
return page;
}
@@ -187,7 +221,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'),
@@ -203,7 +237,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();
@@ -260,6 +294,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() {
@@ -286,7 +370,7 @@ define([
return lastValue;
}
- reloadInsEditor(type='') {
+ reloadInsEditor() {
var that = this;
var tempPointer = this.pointer;
var callbackFunction = function (varObj) {
diff --git a/visualpython/js/m_apps/PandasOption.js b/visualpython/js/m_apps/PandasOption.js
new file mode 100644
index 00000000..b9077691
--- /dev/null
+++ b/visualpython/js/m_apps/PandasOption.js
@@ -0,0 +1,102 @@
+/*
+ * 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));
+ // })
+ code.push("pd.reset_option('^display')");
+ } 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/Snippets.js b/visualpython/js/m_apps/Snippets.js
index c9656b84..fe1ac196 100644
--- a/visualpython/js/m_apps/Snippets.js
+++ b/visualpython/js/m_apps/Snippets.js
@@ -126,7 +126,41 @@ define([
filesPath.forEach(fileObj => {
var fileName = fileObj.file;
var selectedPath = fileObj.path;
- fetch(selectedPath).then(function(file) {
+ if (vpConfig.extensionType === 'lab') {
+ vpKernel.readFile(selectedPath).then(function(resultObj) {
+ try {
+ var snippetData = JSON.parse(resultObj.result);
+ var timestamp = new Date().getTime();
+
+ var keys = Object.keys(snippetData);
+ var importKeys = [];
+ var newSnippet = {};
+ keys.forEach(key => {
+ var importKey = key;
+ var importNo = 1;
+ var titleList = Object.keys(that.codemirrorList);
+ // set duplicate title
+ while(titleList.includes(importKey)) {
+ importKey = key + '_imported' + importNo;
+ importNo += 1;
+ }
+ newSnippet = { ...newSnippet, [importKey]: { code: snippetData[key], timestamp: timestamp } };
+
+ importKeys.push(importKey);
+ });
+ vpConfig.setData(newSnippet).then(function() {
+ that.importedList = [ ...importKeys ];
+ that.loadUdfList();
+ com_util.renderSuccessMessage(fileName + ' imported ');
+ });
+ } catch (ex) {
+ com_util.renderAlertModal('Not applicable file contents with vp format! (JSON)');
+ }
+ }).catch(function(err) {
+ vpLog.display(VP_LOG_TYPE.ERROR, err);
+ });
+ } else {
+ fetch(selectedPath).then(function(file) {
if (file.status != 200) {
alert("The file format is not valid.");
return;
@@ -159,6 +193,8 @@ define([
com_util.renderSuccessMessage(fileName + ' imported ');
});
});
+ }
+
});
}
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/m_library/m_pandas/getValueCounts.js b/visualpython/js/m_library/m_pandas/getValueCounts.js
index 837e2033..3fe3c44f 100644
--- a/visualpython/js/m_library/m_pandas/getValueCounts.js
+++ b/visualpython/js/m_library/m_pandas/getValueCounts.js
@@ -33,12 +33,12 @@ define([
super.render();
// add var selector
- var varSelector = new VarSelector(['DataFrame', 'Series', 'Index'], 'DataFrame', false);
- varSelector.setComponentId('i0');
- varSelector.addClass('vp-state');
- varSelector.setUseColumn(true);
- varSelector.setValue(this.state.i0);
- $(this.wrapSelector('#i0')).replaceWith(varSelector.render());
+ // var varSelector = new VarSelector(['DataFrame', 'Series', 'Index'], 'DataFrame', false);
+ // varSelector.setComponentId('i0');
+ // varSelector.addClass('vp-state');
+ // varSelector.setUseColumn(true);
+ // varSelector.setValue(this.state.i0);
+ // $(this.wrapSelector('#i0')).replaceWith(varSelector.render());
}
}
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,
diff --git a/visualpython/python/fileNaviCommand.py b/visualpython/python/fileNaviCommand.py
index 154b1a2a..f38cdbd6 100644
--- a/visualpython/python/fileNaviCommand.py
+++ b/visualpython/python/fileNaviCommand.py
@@ -5,6 +5,7 @@
import os as _vp_os
import stat as _vp_stat
import ctypes as _vp_ctypes
+import json as _vp_json
def _vp_get_userprofile_path():
"""
@@ -197,7 +198,7 @@ def _vp_get_lab_vpcfg_path():
return _vpcfg_path
return ''
-def _vp_set_lab_vpcfg(configFile, content):
+def _vp_set_lab_vpcfg(configFile, content={}):
if _vp_os.name == 'nt':
# windows
_user_path = _vp_get_userprofile_path()
@@ -207,7 +208,7 @@ def _vp_set_lab_vpcfg(configFile, content):
_vpcfg_path = _vp_os.path.join(_user_path, '.visualpython')
_vp_os.makedirs(_vpcfg_path, exist_ok=True)
with open(_vp_os.path.join(_vpcfg_path, configFile), "w") as f:
- f.write(content)
+ f.write(_vp_json.dumps(content))
return True
def _vp_read_file(filePath):
diff --git a/visualpython/python/variableCommand.py b/visualpython/python/variableCommand.py
index f76e10c3..a6bc7fcd 100644
--- a/visualpython/python/variableCommand.py
+++ b/visualpython/python/variableCommand.py
@@ -20,8 +20,14 @@ def _vp_load_instance(var=''):
else:
varList = dir(eval(var))
query = var + '.'
+
+ varType = type(eval(var)).__name__
# result = { 'type': type(eval(var)).__name__, 'list': [{'name': v, 'type': type(eval(var + '.' + v)).__name__} for v in _vp_vars if (not v.startswith('_')) and (v not in _VP_NOT_USING_VAR)] }
- result = {'type': type(eval(var)).__name__, 'list': []}
+ if varType == 'module':
+ varName = eval(var).__name__
+ result = {'type': type(eval(var)).__name__, 'name': varName, 'list': []}
+ else:
+ result = {'type': type(eval(var)).__name__, 'list': []}
tmpList = []
for v in varList:
@@ -41,19 +47,22 @@ def _vp_get_type(var=None):
return str(type(var).__name__)
-def _vp_get_variables_list(types, exclude_types=[]):
+def _vp_get_variables_list(types, exclude_types=[], allow_module=False):
"""
Get Variable list in types
"""
# notUsingVariables = ['_html', '_nms', 'NamespaceMagics', '_Jupyter', 'In', 'Out', 'exit', 'quit', 'get_ipython']
# notUsingTypes = ['module', 'function', 'builtin_function_or_method', 'instance', '_Feature', 'type', 'ufunc']
+ not_using_types = _VP_NOT_USING_TYPES
varList = []
searchList = globals()
if (type(types) == list) and (len(types) > 0):
varList = [{'varName': v, 'varType': type(eval(v)).__name__, 'varInfo': _vp_get_variable_info(eval(v))} for v in searchList if (not v.startswith('_')) & (v not in _VP_NOT_USING_VAR) & (type(eval(v)).__name__ not in exclude_types) & (type(eval(v)).__name__ in types)]
else:
- varList = [{'varName': v, 'varType': type(eval(v)).__name__, 'varInfo': _vp_get_variable_info(eval(v))} for v in searchList if (not v.startswith('_')) & (v not in _VP_NOT_USING_VAR) & (type(eval(v)).__name__ not in exclude_types) & (type(eval(v)).__name__ not in _VP_NOT_USING_TYPES)]
+ if allow_module == True:
+ not_using_types.remove('module')
+ varList = [{'varName': v, 'varType': type(eval(v)).__name__, 'varInfo': _vp_get_variable_info(eval(v))} for v in searchList if (not v.startswith('_')) & (v not in _VP_NOT_USING_VAR) & (type(eval(v)).__name__ not in exclude_types) & (type(eval(v)).__name__ not in not_using_types)]
return varList