');
+
+ // set content
+ $(this.wrapSelector('.vp-inner-popup-body')).html(content.toString());
return content.toString();
}
- renderReplacePage = function() {
+ renderReplacePage() {
var content = new com_String();
content.appendFormatLine('
', 'vp-inner-popup-use-regex', 'Use Regular Expression');
content.appendLine('
');
@@ -709,7 +810,7 @@ define([
return content.toString();
}
- renderReplaceInput = function(index) {
+ renderReplaceInput(index) {
var content = new com_String();
content.appendLine('
');
content.appendLine('');
@@ -725,7 +826,7 @@ define([
return content.toString();
}
- renderAsType = function() {
+ renderAsType() {
var astypeList = this.astypeList;
var content = new com_String();
content.appendFormatLine('', 'vp-inner-popup-astype');
@@ -748,18 +849,62 @@ define([
});
content.appendLine('');
content.append('
');
+
+ // set content
+ $(this.wrapSelector('.vp-inner-popup-body')).html(content.toString());
return content.toString();
}
- openInputPopup = function(type, width=400, height=400) {
+ openInputPopup(type, width=400, height=400) {
var title = '';
var content = '';
let size = { width: width, height: height };
+ let that = this;
switch (parseInt(type)) {
case FRAME_EDIT_TYPE.ADD_COL:
title = 'Add Column';
content = this.renderAddPage('column', 'Column Name');
+
+ // bind codemirror
+ this.subsetCm = this.initCodemirror({
+ key: 'vp-inner-popup-subset',
+ selector: this.wrapSelector('.vp-inner-popup-subset'),
+ type: 'readonly'
+ });
+ // set subset
+ let contentState = that.getPopupContent(type);
+ this.subsetEditor = new Subset({
+ pandasObject: this.state.tempObj,
+ selectedColumns: [ com_util.convertToStr(contentState.name, contentState.nameastext) ],
+ config: { name: 'Subset' } },
+ {
+ useInputVariable: true,
+ useInputColumns: true,
+ targetSelector: this.wrapSelector('.vp-inner-popup-subset'),
+ pageThis: this,
+ allowSubsetTypes: ['iloc', 'loc'],
+ beforeOpen: function(subsetThis) {
+ let contentState = that.getPopupContent(type);
+ let name = com_util.convertToStr(contentState.name, contentState.nameastext);
+ subsetThis.state.selectedColumns = [ name ];
+ },
+ finish: function(code) {
+ that.subsetCm.setValue(code);
+ that.subsetCm.save();
+ setTimeout(function () {
+ that.subsetCm.refresh();
+ }, 1);
+ }
+ });
+ // initial code
+ var code = this.subsetEditor.generateCode();
+ that.subsetCm.setValue(code);
+ that.subsetCm.save();
+ setTimeout(function () {
+ that.subsetCm.refresh();
+ }, 1);
+
break;
case FRAME_EDIT_TYPE.ADD_ROW:
title = 'Add Row';
@@ -773,6 +918,43 @@ define([
title = 'Replace';
// content = this.renderReplacePage();
content = this.renderAddPage('replace', 'Column');
+
+ // bind codemirror
+ this.subsetCm = this.initCodemirror({
+ key: 'vp-inner-popup-subset',
+ selector: this.wrapSelector('.vp-inner-popup-subset'),
+ type: 'readonly'
+ });
+ // set subset
+ this.subsetEditor = new Subset({
+ pandasObject: this.state.tempObj,
+ selectedColumns: that.state.selected.map(col=>col.code),
+ config: { name: 'Subset' } },
+ {
+ useInputVariable: true,
+ useInputColumns: true,
+ targetSelector: this.wrapSelector('.vp-inner-popup-subset'),
+ pageThis: this,
+ allowSubsetTypes: ['iloc', 'loc'],
+ beforeOpen: function(subsetThis) {
+ subsetThis.state.selectedColumns = that.state.selected.map(col=>col.code);
+ },
+ finish: function(code) {
+ that.subsetCm.setValue(code);
+ that.subsetCm.save();
+ setTimeout(function () {
+ that.subsetCm.refresh();
+ }, 1);
+ }
+ });
+ // initial code
+ var code = this.subsetEditor.generateCode();
+ that.subsetCm.setValue(code);
+ that.subsetCm.save();
+ setTimeout(function () {
+ that.subsetCm.refresh();
+ }, 1);
+
break;
case FRAME_EDIT_TYPE.AS_TYPE:
title = 'Convert type';
@@ -787,15 +969,10 @@ define([
// set size
$(this.wrapSelector('.vp-inner-popup-box')).css(size);
-
- // set content
- $(this.wrapSelector('.vp-inner-popup-body')).html(content);
// bindEventForAddPage
this.bindEventForPopupPage();
- let that = this;
-
// set column list
vpKernel.getColumnList(this.state.tempObj).then(function(resultObj) {
let { result } = resultObj;
@@ -863,6 +1040,10 @@ define([
});
}
}
+ } else if (tab == 'subset') {
+ content['subset'] = this.subsetCm?this.subsetCm.getValue():'';
+ content['value'] = $(this.wrapSelector('.vp-inner-popup-input3')).val();
+ content['valueastext'] = $(this.wrapSelector('.vp-inner-popup-istext3')).prop('checked');
} else if (tab == 'apply') {
content['column'] = $(this.wrapSelector('.vp-inner-popup-apply-column')).val();
content['apply'] = $(this.wrapSelector('.vp-inner-popup-apply-lambda')).val();
@@ -1035,15 +1216,15 @@ define([
code.appendFormat("{0}.drop([{1}], axis={2}, inplace=True)", tempObj, selectedName, axis);
break;
case FRAME_EDIT_TYPE.RENAME:
- var renameStr = new com_String();
+ var renameList = [];
Object.keys(content).forEach((key, idx) => {
- if (idx == 0) {
- renameStr.appendFormat("{0}: {1}", content[key].label, com_util.convertToStr(content[key].value, content[key].istext));
- } else {
- renameStr.appendFormat(", {0}: {1}", content[key].label, com_util.convertToStr(content[key].value, content[key].istext));
+ if (content[key].value != '') {
+ renameList.push(com_util.formatString("{0}: {1}", content[key].label, com_util.convertToStr(content[key].value, content[key].istext)));
}
});
- code.appendFormat("{0}.rename({1}={{2}}, inplace=True)", tempObj, axis==FRAME_AXIS.ROW?'index':'columns', renameStr.toString());
+ if (renameList.length > 0) {
+ code.appendFormat("{0}.rename({1}={{2}}, inplace=True)", tempObj, axis==FRAME_AXIS.ROW?'index':'columns', renameList.join(', '));
+ }
break;
case FRAME_EDIT_TYPE.DROP_NA:
var locObj = '';
@@ -1092,12 +1273,12 @@ define([
var tab = content.addtype;
if (tab == 'value') {
var value = com_util.convertToStr(content.value, content.valueastext);
- code.appendFormat("{0}[{1}] = {2}", tempObj, name, value);
+ code.appendFormat("{0}[[{1}]] = {2}", tempObj, name, value);
} else if (tab == 'calculation') {
var { var1col, oper, var2col } = content;
var var1code = tempObj + "['" + var1col + "']";
var var2code = tempObj + "['" + var2col + "']";
- code.appendFormat('{0}[{1}] = {2} {3} {4}', tempObj, name, var1code, oper, var2code);
+ code.appendFormat('{0}[[{1}]] = {2} {3} {4}', tempObj, name, var1code, oper, var2code);
} else if (tab == 'replace') {
var replaceStr = new com_String();
var useRegex = content['useregex'];
@@ -1120,8 +1301,11 @@ define([
code.append(', regex=True');
}
code.append(')');
+ } else if (tab == 'subset') {
+ var value = com_util.convertToStr(content.value, content.valueastext);
+ code.appendFormat("{0} = {1}", content.subset, value);
} else if (tab == 'apply') {
- code.appendFormat("{0}[{1}] = {2}[{3}].apply({4})", tempObj, name, tempObj, content.column, content.apply);
+ code.appendFormat("{0}[[{1}]] = {2}[{3}].apply({4})", tempObj, name, tempObj, content.column, content.apply);
}
break;
case FRAME_EDIT_TYPE.ADD_ROW:
@@ -1153,12 +1337,11 @@ define([
}
var that = this;
- var tempObj = this.state.tempObj;
- var lines = this.state.lines;
+ let { tempObj, lines, indexList } = this.state;
var prevLines = 0;
var scrollPos = -1;
if (more) {
- prevLines = that.state.indexList.length;
+ prevLines = indexList.length;
scrollPos = $(this.wrapSelector('.vp-fe-table')).scrollTop();
}
@@ -1320,10 +1503,16 @@ define([
// row
$(this.wrapSelector(com_util.formatString('.{0}', VP_FE_MENU_BOX))).find('div[data-axis="col"]').hide();
$(this.wrapSelector(com_util.formatString('.{0}', VP_FE_MENU_BOX))).find('div[data-axis="row"]').show();
+
+ // change sub-box style
+ $(this.wrapSelector(com_util.formatString('.{0}.vp-fe-sub-cleaning', VP_FE_MENU_SUB_BOX))).css({ 'top': '90px'});
} else if (this.state.axis == 1) {
// column
$(this.wrapSelector(com_util.formatString('.{0}', VP_FE_MENU_BOX))).find('div[data-axis="row"]').hide();
$(this.wrapSelector(com_util.formatString('.{0}', VP_FE_MENU_BOX))).find('div[data-axis="col"]').show();
+
+ // change sub-box style
+ $(this.wrapSelector(com_util.formatString('.{0}.vp-fe-sub-cleaning', VP_FE_MENU_SUB_BOX))).css({ 'top': '120px'});
}
$(this.wrapSelector(com_util.formatString('.{0}', VP_FE_MENU_BOX))).css({ top: top, left: left })
$(this.wrapSelector(com_util.formatString('.{0}', VP_FE_MENU_BOX))).show();
@@ -1333,6 +1522,21 @@ define([
$(this.wrapSelector(com_util.formatString('.{0}', VP_FE_MENU_BOX))).hide();
}
+ hide() {
+ super.hide();
+ this.subsetEditor && this.subsetEditor.hide();
+ }
+
+ close() {
+ super.close();
+ this.subsetEditor && this.subsetEditor.close();
+ }
+
+ remove() {
+ super.remove();
+ this.subsetEditor && this.subsetEditor.remove();
+ }
+
}
const VP_FE_BTN = 'vp-fe-btn';
@@ -1340,6 +1544,7 @@ define([
const VP_FE_TITLE = 'vp-fe-title';
const VP_FE_MENU_BOX = 'vp-fe-menu-box';
+ const VP_FE_MENU_SUB_BOX = 'vp-fe-menu-sub-box';
const VP_FE_MENU_ITEM = 'vp-fe-menu-item';
const VP_FE_POPUP_BOX = 'vp-fe-popup-box';
diff --git a/js/m_apps/Groupby.js b/js/m_apps/Groupby.js
index 1f405310..4e02cdc4 100644
--- a/js/m_apps/Groupby.js
+++ b/js/m_apps/Groupby.js
@@ -18,8 +18,9 @@ define([
'vp_base/js/com/com_String',
'vp_base/js/com/com_util',
'vp_base/js/com/component/PopupComponent',
+ 'vp_base/js/com/component/SuggestInput',
'vp_base/js/com/component/MultiSelector'
-], function(gbHtml, gbCss, com_String, com_util, PopupComponent, MultiSelector) {
+], function(gbHtml, gbCss, com_String, com_util, PopupComponent, SuggestInput, MultiSelector) {
/**
* Groupby
@@ -374,18 +375,29 @@ define([
* @param {string} defaultValue previous value
*/
templateForVariableList(varList, defaultValue='') {
- var tag = new com_String();
- tag.appendFormatLine('', 'vp_gbVariable');
- varList.forEach(vObj => {
- // varName, varType
- var label = vObj.varName;
- tag.appendFormatLine('{3} '
- , vObj.varName, vObj.varType
- , defaultValue == vObj.varName?'selected':''
- , label);
- });
- tag.appendLine(' '); // VP_VS_VARIABLES
- return tag.toString();
+ // var tag = new com_String();
+ // tag.appendFormatLine('', 'vp_gbVariable');
+ // varList.forEach(vObj => {
+ // // varName, varType
+ // var label = vObj.varName;
+ // tag.appendFormatLine('{3} '
+ // , vObj.varName, vObj.varType
+ // , defaultValue == vObj.varName?'selected':''
+ // , label);
+ // });
+ // tag.appendLine(' '); // VP_VS_VARIABLES
+ // return tag.toString();
+ let mappedList = varList.map(obj => { return { label: obj.varName, value: obj.varName, dtype: obj.varType } });
+
+ var variableInput = new SuggestInput();
+ variableInput.setComponentID('vp_gbVariable');
+ variableInput.addClass('vp-state');
+ variableInput.setPlaceholder('Select variable');
+ variableInput.setSuggestList(function () { return mappedList; });
+ variableInput.setNormalFilter(true);
+ variableInput.setValue(defaultValue);
+
+ return variableInput.toTagString();
}
/**
@@ -403,6 +415,7 @@ define([
var defaultMethod = '';
page.appendFormatLine('{1} ', '', 'Select method type');
page.appendFormatLine('{1} ', 'typing', 'Typing');
+ page.appendLine('----------------------- ');
this.methodList.forEach(method => {
if (method.value == '') {
return;
diff --git a/js/m_apps/Instance.js b/js/m_apps/Instance.js
index 8e05de59..63582554 100644
--- a/js/m_apps/Instance.js
+++ b/js/m_apps/Instance.js
@@ -149,27 +149,27 @@ define([
});
// co-op with Subset
- $(this.wrapSelector('#vp_instanceVariable')).on('remove_option_page', function(evt) {
- let component = evt.component;
- component.close();
- });
- $(this.wrapSelector('#vp_instanceVariable')).on('close_option_page', function(evt) {
- let component = evt.component;
- component.close();
- });
- $(this.wrapSelector('#vp_instanceVariable')).on('focus_option_page', function(evt) {
- let component = evt.component;
- component.focus();
- });
- $(this.wrapSelector('#vp_instanceVariable')).on('apply_option_page', function(evt) {
- let component = evt.component;
- // apply its value
- let code = component.generateCode();
- component.close();
- that.addStack();
- that.state.subsetEditor.state.pandasObject = code;
- that.updateValue(code);
- });
+ // $(this.wrapSelector('#vp_instanceVariable')).on('remove_option_page', function(evt) {
+ // let component = evt.component;
+ // component.close();
+ // });
+ // $(this.wrapSelector('#vp_instanceVariable')).on('close_option_page', function(evt) {
+ // let component = evt.component;
+ // component.close();
+ // });
+ // $(this.wrapSelector('#vp_instanceVariable')).on('focus_option_page', function(evt) {
+ // let component = evt.component;
+ // component.focus();
+ // });
+ // $(this.wrapSelector('#vp_instanceVariable')).on('apply_option_page', function(evt) {
+ // let component = evt.component;
+ // // apply its value
+ // let code = component.generateCode();
+ // component.close();
+ // that.addStack();
+ // that.state.subsetEditor.state.pandasObject = code;
+ // that.updateValue(code);
+ // });
}
templateForBody() {
@@ -179,12 +179,19 @@ define([
render() {
super.render();
+ let that = this;
+
// vpSubsetEditor
this.state.subsetEditor = new Subset({ pandasObject: '', config: { name: 'Subset' } },
{
useInputVariable: true,
targetSelector: this.wrapSelector('#vp_instanceVariable'),
- pageThis: this
+ pageThis: this,
+ finish: function(code) {
+ that.addStack();
+ that.state.subsetEditor.state.pandasObject = code;
+ that.updateValue(code);
+ }
});
this.state.subsetEditor.disableButton();
diff --git a/js/m_apps/Profiling.js b/js/m_apps/Profiling.js
index c57442d7..37f7135c 100644
--- a/js/m_apps/Profiling.js
+++ b/js/m_apps/Profiling.js
@@ -18,8 +18,9 @@ define([
'vp_base/js/com/com_String',
'vp_base/js/com/com_interface',
'vp_base/js/com/component/PopupComponent',
+ 'vp_base/js/com/component/SuggestInput',
'vp_base/js/com/component/FileNavigation'
-], function(proHTML, proCss, com_String, com_interface, PopupComponent, FileNavigation) {
+], function(proHTML, proCss, com_String, com_interface, PopupComponent, SuggestInput, FileNavigation) {
const PROFILE_TYPE = {
NONE: -1,
@@ -44,7 +45,7 @@ define([
this.config.codeview = false;
this.config.dataview = false;
this.config.runButton = false;
- this.config.size = { width: 500, height: 430 };
+ this.config.size = { width: 500, height: 500 };
this.selectedReport = '';
}
@@ -167,7 +168,7 @@ define([
// render variable list
// replace
$(that.wrapSelector('#vp_pfVariable')).replaceWith(function() {
- return that.renderVariableList(varList);
+ return that.templateForVariableList(varList);
});
$(that.wrapSelector('#vp_pfVariable')).trigger('change');
} catch (ex) {
@@ -176,20 +177,35 @@ define([
});
}
- renderVariableList(varList) {
- var tag = new com_String();
+ templateForVariableList(varList) {
var beforeValue = $(this.wrapSelector('#vp_pfVariable')).val();
- tag.appendFormatLine('', 'vp_pfVariable');
- varList.forEach(vObj => {
- // varName, varType
- var label = vObj.varName;
- tag.appendFormatLine('{3} '
- , vObj.varName, vObj.varType
- , beforeValue == vObj.varName?'selected':''
- , label);
- });
- tag.appendLine(' '); // VP_VS_VARIABLES
- return tag.toString();
+ if (beforeValue == null) {
+ beforeValue = '';
+ }
+ // var tag = new com_String();
+ // tag.appendFormatLine('', 'vp_pfVariable');
+ // varList.forEach(vObj => {
+ // // varName, varType
+ // var label = vObj.varName;
+ // tag.appendFormatLine('{3} '
+ // , vObj.varName, vObj.varType
+ // , beforeValue == vObj.varName?'selected':''
+ // , label);
+ // });
+ // tag.appendLine(' '); // VP_VS_VARIABLES
+ // return tag.toString();
+
+ let mappedList = varList.map(obj => { return { label: obj.varName, value: obj.varName, dtype: obj.varType } });
+
+ var variableInput = new SuggestInput();
+ variableInput.setComponentID('vp_pfVariable');
+ variableInput.addClass('vp-pf-select');
+ variableInput.setPlaceholder('Select variable');
+ variableInput.setSuggestList(function () { return mappedList; });
+ variableInput.setNormalFilter(true);
+ variableInput.setValue(beforeValue);
+
+ return variableInput.toTagString();
}
/**
diff --git a/js/m_apps/Reshape.js b/js/m_apps/Reshape.js
index 2c782cdc..c78f819a 100644
--- a/js/m_apps/Reshape.js
+++ b/js/m_apps/Reshape.js
@@ -18,8 +18,9 @@ define([
'vp_base/js/com/com_String',
'vp_base/js/com/com_util',
'vp_base/js/com/component/PopupComponent',
+ 'vp_base/js/com/component/SuggestInput',
'vp_base/js/com/component/MultiSelector'
-], function(reshapeHtml, reshapeCss, com_String, com_util, PopupComponent, MultiSelector) {
+], function(reshapeHtml, reshapeCss, com_String, com_util, PopupComponent, SuggestInput, MultiSelector) {
/**
* Reshape
@@ -37,13 +38,16 @@ define([
pivot: {
index: [],
columns: [],
- values: []
+ values: [],
+ aggfunc: []
},
melt: {
idVars: [],
ValueVars: [],
varName: '',
- valueName: ''
+ varNameText: true,
+ valueName: '',
+ valueNameText: true
},
userOption: '',
allocateTo: '',
@@ -97,7 +101,7 @@ define([
that._resetColumnSelector(that.wrapSelector('#vp_rsValueVars'));
that.state.pivot = {
- index: [], columns: [], values: []
+ index: [], columns: [], values: [], aggfunc: []
};
that.state.melt = {
idVars: [], valueVars: []
@@ -115,13 +119,8 @@ define([
var type = $(this).val();
that.state.type = type;
// change visibility
- if (type == 'pivot') {
- $(that.wrapSelector('.vp-rs-type-box.melt')).hide();
- $(that.wrapSelector('.vp-rs-type-box.pivot')).show();
- } else {
- $(that.wrapSelector('.vp-rs-type-box.pivot')).hide();
- $(that.wrapSelector('.vp-rs-type-box.melt')).show();
- }
+ $(that.wrapSelector('.vp-rs-type-box')).hide();
+ $(that.wrapSelector('.vp-rs-type-box.' + type)).show();
// clear user option
$(that.wrapSelector('#vp_rsUserOption')).val('');
@@ -167,6 +166,19 @@ define([
that.openColumnSelector(targetVariable, $(that.wrapSelector('#vp_rsValues')), 'Select columns', excludeList);
});
+ // aggfunc change event
+ $(document).on('change', this.wrapSelector('#vp_rsAggfunc'), function(event) {
+ var colList = event.dataList;
+ that.state.pivot.aggfunc = colList;
+ });
+
+ // aggfunc select button event
+ $(document).on('click', this.wrapSelector('#vp_rsAggfunc'), function() {
+ var targetVariable = [ that.state.variable ];
+ var excludeList = that.state.pivot.aggfunc.map(obj => obj.code);
+ that.openMethodSelector(targetVariable, $(that.wrapSelector('#vp_rsAggfunc')), 'Select columns', excludeList);
+ });
+
// id vars change event
$(document).on('change', this.wrapSelector('#vp_rsIdVars'), function(event) {
var colList = event.dataList;
@@ -294,7 +306,9 @@ define([
this._loadColumnSelectorInput(this.wrapSelector('#vp_rsIdVars'), melt.idVars);
this._loadColumnSelectorInput(this.wrapSelector('#vp_rsValueVars'), melt.valueVars);
$(this.wrapSelector('#vp_rsVarName')).val(melt.varName);
+ $(this.wrapSelector('#varNameText')).prop('checked', melt.varNameText);
$(this.wrapSelector('#vp_rsValueName')).val(melt.valueName);
+ $(this.wrapSelector('#valueNameText')).prop('checked', melt.valueNameText);
// userOption
$(this.wrapSelector('#vp_rsUserOption')).val(userOption);
@@ -310,19 +324,31 @@ define([
* @param {string} defaultValue previous value
*/
renderVariableList(id, varList, defaultValue='') {
- var tag = new com_String();
- tag.appendFormatLine('', id);
- varList.forEach(vObj => {
- // varName, varType
- var label = vObj.varName;
- tag.appendFormatLine('{3} '
- , vObj.varName, vObj.varType
- , defaultValue == vObj.varName?'selected':''
- , label);
- });
- tag.appendLine(' '); // VP_VS_VARIABLES
+ // var tag = new com_String();
+ // tag.appendFormatLine('', id);
+ // varList.forEach(vObj => {
+ // // varName, varType
+ // var label = vObj.varName;
+ // tag.appendFormatLine('{3} '
+ // , vObj.varName, vObj.varType
+ // , defaultValue == vObj.varName?'selected':''
+ // , label);
+ // });
+ // tag.appendLine(' '); // VP_VS_VARIABLES
+ // $(this.wrapSelector('#' + id)).replaceWith(function() {
+ // return tag.toString();
+ // });
+ let mappedList = varList.map(obj => { return { label: obj.varName, value: obj.varName, dtype: obj.varType } });
+
+ var variableInput = new SuggestInput();
+ variableInput.setComponentID(id);
+ variableInput.addClass('vp-state');
+ variableInput.setPlaceholder('Select variable');
+ variableInput.setSuggestList(function () { return mappedList; });
+ variableInput.setNormalFilter(true);
+ variableInput.setValue(defaultValue);
$(this.wrapSelector('#' + id)).replaceWith(function() {
- return tag.toString();
+ return variableInput.toTagString();
});
}
@@ -331,13 +357,39 @@ define([
* @param {Array} previousList previous selected columns
* @param {Array} excludeList columns to exclude
*/
- renderColumnSelector(targetVariable, previousList, excludeList) {
+ renderColumnSelector(targetVariable, previousList, excludeList) {
this.popup.ColSelector = new MultiSelector(
this.wrapSelector('.vp-inner-popup-body'),
{ mode: 'columns', parent: targetVariable, selectedList: previousList, excludeList: excludeList }
);
}
+ /**
+ * Render method selector using MultiSelector module
+ * @param {Array} previousList previous selected methods
+ * @param {Array} excludeList methods to exclude
+ */
+ renderMethodSelector(targetVariable, previousList, excludeList) {
+ let methodList = [
+ { value: 'count', code: "'count'" },
+ { value: 'first', code: "'first'" },
+ { value: 'last', code: "'last'" },
+ { value: 'size', code: "'size'" },
+ { value: 'std', code: "'std'" },
+ { value: 'sum', code: "'sum'" },
+ { value: 'max', code: "'max'" },
+ { value: 'mean', code: "'mean'" },
+ { value: 'median', code: "'median'" },
+ { value: 'min', code: "'min'" },
+ { value: 'quantile', code: "'quantile'" },
+ ];
+
+ this.popup.ColSelector = new MultiSelector(
+ this.wrapSelector('.vp-inner-popup-body'),
+ { mode: 'data', parent: targetVariable, dataList: methodList, selectedList: previousList, excludeList: excludeList }
+ );
+ }
+
/**
* Load variable list (dataframe)
*/
@@ -409,6 +461,45 @@ define([
}
}
+ } else if (type == 'pivot_table') {
+ //================================================================
+ // pivot_table
+ //================================================================
+ // index (optional)
+ if (pivot.index && pivot.index.length > 0) {
+ if (pivot.index.length == 1) {
+ options.push(com_util.formatString("index={0}", pivot.index[0].code));
+ } else {
+ options.push(com_util.formatString("index=[{0}]", pivot.index.map(col => col.code).join(',')));
+ }
+ }
+
+ // columns
+ if (pivot.columns && pivot.columns.length > 0) {
+ if (pivot.columns.length == 1) {
+ options.push(com_util.formatString("columns={0}", pivot.columns[0].code));
+ } else {
+ options.push(com_util.formatString("columns=[{0}]", pivot.columns.map(col => col.code).join(',')));
+ }
+ }
+
+ // values (optional)
+ if (pivot.values && pivot.values.length > 0) {
+ if (pivot.values.length == 1) {
+ options.push(com_util.formatString("values={0}", pivot.values[0].code));
+ } else {
+ options.push(com_util.formatString("values=[{0}]", pivot.values.map(col => col.code).join(',')));
+ }
+ }
+
+ // aggfunc
+ if (pivot.aggfunc && pivot.aggfunc.length > 0) {
+ if (pivot.aggfunc.length == 1) {
+ options.push(com_util.formatString("aggfunc={0}", pivot.aggfunc[0].code));
+ } else {
+ options.push(com_util.formatString("aggfunc=[{0}]", pivot.aggfunc.map(col => col.code).join(',')));
+ }
+ }
} else {
//================================================================
// melt
@@ -433,12 +524,12 @@ define([
// var name (optional)
if (melt.varName) {
- options.push(com_util.formatString("var_name='{0}'", melt.varName));
+ options.push(com_util.formatString("var_name={0}", com_util.convertToStr(melt.varName, melt.varNameText)));
}
// value name (optional)
- if (melt.varName) {
- options.push(com_util.formatString("value_name='{0}'", melt.valueName));
+ if (melt.valueName) {
+ options.push(com_util.formatString("value_name={0}", com_util.convertToStr(melt.valueName, melt.valueNameText)));
}
}
@@ -498,6 +589,19 @@ define([
this.openInnerPopup(title);
}
+ openMethodSelector(targetVariable, targetSelector, title='Select methods', excludeList=[]) {
+ this.popup.targetVariable = targetVariable;
+ this.popup.targetSelector = targetSelector;
+ var previousList = this.popup.targetSelector.data('list');
+ if (previousList) {
+ previousList = previousList.map(col => col.code)
+ }
+ this.renderMethodSelector(targetVariable, previousList, excludeList);
+
+ // set title
+ this.openInnerPopup(title);
+ }
+
handleInnerOk() {
// ok input popup
var dataList = this.popup.ColSelector.getDataList();
diff --git a/js/m_apps/Subset.js b/js/m_apps/Subset.js
index 9d2f3e26..afae413a 100644
--- a/js/m_apps/Subset.js
+++ b/js/m_apps/Subset.js
@@ -30,19 +30,34 @@ define([
_init() {
super._init();
this.config.sizeLevel = 3;
+ // use Run/Add cell
+ this.useCell = true;
+
/** Write codes executed before rendering */
this.targetSelector = this.prop.targetSelector;
this.pageThis = this.prop.pageThis;
+
this.useInputVariable = this.prop.useInputVariable;
if (this.useInputVariable) {
this.eventTarget = this.targetSelector;
+ this.useCell = false; // show apply button only
}
-
- // use Run/Add cell
- this.useCell = true;
+ this.useInputColumns = this.prop.useInputColumns;
+ this.beforeOpen = this.prop.beforeOpen;
+ this.finish = this.prop.finish;
// specify pandas object types
this.pdObjTypes = ['DataFrame', 'Series'];
+ this.allowSubsetTypes = ['subset', 'iloc', 'loc', 'query'];
+ this.subsetLabels = {
+ 'subset': 'subset',
+ 'iloc' : 'iloc (integer location)',
+ 'loc' : 'loc (location)',
+ 'query' : 'query'
+ };
+ if (this.prop.allowSubsetTypes) {
+ this.allowSubsetTypes = this.prop.allowSubsetTypes;
+ }
this.stateLoaded = false;
@@ -70,6 +85,7 @@ define([
columnList: [],
colPointer: { start: -1, end: -1 },
colPageDom: '',
+ selectedColumns: [],
...this.state
};
@@ -103,7 +119,18 @@ define([
this.renderButton();
// hide allocate to
- $(this.wrapSelector('.vp-ds-allocate-to')).closest('tr').hide();
+ $(this.wrapSelector('.' + VP_DS_ALLOCATE_TO)).closest('tr').hide();
+ }
+
+ if (this.useInputColumns) {
+ // hide make copy
+ $(this.wrapSelector('.' + VP_DS_USE_COPY)).parent().hide();
+ // hide to frame
+ $(this.wrapSelector('.' + VP_DS_TO_FRAME)).parent().hide();
+ // hide allocate to
+ $(this.wrapSelector('.' + VP_DS_ALLOCATE_TO)).closest('tr').hide();
+ // hide column box
+ $(this.wrapSelector('.' + VP_DS_TAB_PAGE_BOX + '.subset-column')).hide();
}
}
@@ -132,22 +159,29 @@ define([
// set button next to input tag
var buttonTag = new com_String();
buttonTag.appendFormat('{3} ',
- VP_DS_BTN, this.uuid, 'vp-button', 'Edit');
+ VP_DS_BTN, this.uuid, 'vp-button', 'Subset');
if (this.pageThis) {
$(this.targetSelector).parent().append(buttonTag.toString());
}
}
renderSubsetType(dataType) {
var subsetType = this.state.subsetType;
+ let that = this;
var tag = new com_String();
tag.appendFormatLine('', VP_DS_SUBSET_TYPE, 'vp-select');
- tag.appendFormatLine('{2} ', 'subset', subsetType == 'subset'?'selected':'', 'subset');
- tag.appendFormatLine('{2} ', 'loc', subsetType == 'loc'?'selected':'', 'loc');
- tag.appendFormatLine('{2} ', 'iloc', subsetType == 'iloc'?'selected':'', 'iloc');
- if (dataType == 'DataFrame') {
- tag.appendFormatLine('{2} ', 'query', subsetType == 'query'?'selected':'', 'query');
- }
+ this.allowSubsetTypes.forEach(thisType => {
+ if (thisType != 'query' || dataType == 'DataFrame') {
+ let label = that.subsetLabels[thisType];
+ tag.appendFormatLine('{2} ', thisType, subsetType == thisType?'selected':'', label);
+ }
+ });
+ // tag.appendFormatLine('{2} ', 'subset', subsetType == 'subset'?'selected':'', 'subset');
+ // tag.appendFormatLine('{2} ', 'loc', subsetType == 'loc'?'selected':'', 'loc');
+ // tag.appendFormatLine('{2} ', 'iloc', subsetType == 'iloc'?'selected':'', 'iloc');
+ // if (dataType == 'DataFrame') {
+ // tag.appendFormatLine('{2} ', 'query', subsetType == 'query'?'selected':'', 'query');
+ // }
tag.appendLine(' ');
return tag.toString();
@@ -206,7 +240,7 @@ define([
vpSearchSuggest.addClass(VP_DS_SELECT_SEARCH);
vpSearchSuggest.setPlaceholder('Search Row');
vpSearchSuggest.setSuggestList(function () { return that.state.rowList; });
- vpSearchSuggest.setSelectEvent(function (value) {
+ vpSearchSuggest.setSelectEvent(function (value, item) {
$(this.wrapSelector()).val(value);
$(this.wrapSelector()).trigger('change');
});
@@ -448,12 +482,7 @@ define([
tag.appendLine('');
tag.appendLine(this.templateForConditionColumnInput(colList));
- tag.appendFormatLine('', 'vp-select s', 'vp-oper-list');
- var operList = ['', '==', '!=', 'contains', 'not contains', '<', '<=', '>', '>=', 'starts with', 'ends with'];
- operList.forEach(oper => {
- tag.appendFormatLine('{1} ', oper, oper);
- });
- tag.appendLine(' ');
+ tag.appendLine(this.templateForConditionOperator(''));
tag.appendLine(' ');
tag.appendLine('
');
@@ -491,6 +520,22 @@ define([
tag.appendLine('');
return tag.toString();
}
+ templateForConditionOperator(dtype='object') {
+ var tag = new com_String();
+ tag.appendFormatLine('', 'vp-select s', 'vp-oper-list');
+ var operList = ['', '==', '!=', '<', '<=', '>', '>=', 'contains', 'not contains', 'starts with', 'ends with', 'isnull()', 'notnull()'];
+ if (dtype == '') {
+ // .index
+ operList = ['', '==', '!=', '<', '<=', '>', '>='];
+ } else if (dtype != 'object') {
+ operList = ['', '==', '!=', '<', '<=', '>', '>=', 'isnull()', 'notnull()'];
+ }
+ operList.forEach(oper => {
+ tag.appendFormatLine('{1} ', oper, oper);
+ });
+ tag.appendLine(' ');
+ return tag.toString();
+ }
templateForConditionCondInput(category, dtype='object') {
var vpCondSuggest = new SuggestInput();
vpCondSuggest.addClass('vp-input m vp-condition');
@@ -582,7 +627,7 @@ define([
* - render on VP_DS_PANDAS_OBJECT
*/
loadVariables() {
- var that = this;
+ let that = this;
var types = that.pdObjTypes;
var prevValue = this.state.pandasObject;
@@ -614,19 +659,35 @@ define([
let { result } = resultObj;
var varList = JSON.parse(result);
varList = varList.map(function (v) {
- return { label: v.varName + ' (' + v.varType + ')', value: v.varName, dtype: v.varType };
+ return { label: v.varName, value: v.varName, dtype: v.varType };
});
that.state.dataList = varList;
// 1. Target Variable
var prevValue = $(that.wrapSelector('.' + VP_DS_PANDAS_OBJECT)).val();
- $(that.wrapSelector('.' + VP_DS_PANDAS_OBJECT_BOX)).replaceWith(function () {
- var pdVarSelect = new VarSelector(that.pdObjTypes, that.state.dataType, false, false);
- pdVarSelect.addClass(VP_DS_PANDAS_OBJECT);
- pdVarSelect.addBoxClass(VP_DS_PANDAS_OBJECT_BOX);
- pdVarSelect.setValue(prevValue);
- return pdVarSelect.render();
+ // $(that.wrapSelector('.' + VP_DS_PANDAS_OBJECT_BOX)).replaceWith(function () {
+ // var pdVarSelect = new VarSelector(that.pdObjTypes, that.state.dataType, false, false);
+ // pdVarSelect.addClass(VP_DS_PANDAS_OBJECT);
+ // pdVarSelect.addBoxClass(VP_DS_PANDAS_OBJECT_BOX);
+ // pdVarSelect.setValue(prevValue);
+ // return pdVarSelect.render();
+ // });
+ var variableInput = new SuggestInput();
+ variableInput.addClass(VP_DS_PANDAS_OBJECT);
+ variableInput.setPlaceholder('Select variable');
+ variableInput.setSuggestList(function () { return varList; });
+ variableInput.setSelectEvent(function (value, item) {
+ $(this.wrapSelector()).val(value);
+ $(this.wrapSelector()).data('dtype', item.dtype);
+ that.state.pandasObject = value;
+ that.state.dataType = item.dtype;
+ $(this.wrapSelector()).trigger('change');
+ });
+ variableInput.setNormalFilter(true);
+ variableInput.setValue(prevValue);
+ $(that.wrapSelector('.' + VP_DS_PANDAS_OBJECT)).replaceWith(function() {
+ return variableInput.toTagString();
});
if (!that.stateLoaded) {
that.reloadSubsetData();
@@ -635,7 +696,7 @@ define([
}
}
loadSubsetType(dataType) {
- var that = this;
+ let that = this;
$(this.wrapSelector('.' + VP_DS_SUBSET_TYPE)).replaceWith(function () {
return that.renderSubsetType(dataType);
});
@@ -976,10 +1037,34 @@ define([
// open popup
$(document).on('click', com_util.formatString('.{0}.{1}', VP_DS_BTN, this.uuid), function (event) {
if (!$(this).hasClass('disabled')) {
- that.useCell = false; // show apply button only
+ if (that.beforeOpen && typeof that.beforeOpen == 'function') {
+ that.beforeOpen(that);
+ }
that.open();
+ $(that.wrapSelector()).css({ 'z-index': 205 }); // move forward
}
});
+
+ // co-op with parent Popup
+ $(this.targetSelector).on('remove_option_page', function(evt) {
+ that.close();
+ });
+ $(this.targetSelector).on('close_option_page', function(evt) {
+ that.close();
+ });
+ $(this.targetSelector).on('focus_option_page', function(evt) {
+ 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();
+ });
}
// df selection/change
@@ -1041,7 +1126,9 @@ define([
});
// show column box
- $(that.wrapSelector('.' + VP_DS_TAB_PAGE_BOX + '.subset-column')).show();
+ if (that.useInputColumns != true) {
+ $(that.wrapSelector('.' + VP_DS_TAB_PAGE_BOX + '.subset-column')).show();
+ }
} else if (that.state.dataType == 'Series') {
// get result and load column list
vpKernel.getRowList(varName).then(function (resultObj) {
@@ -1331,17 +1418,22 @@ define([
that.generateCode();
});
+ // change column selection for condition page
$(document).on('change', this.wrapSelector('.vp-ds-cond-tbl .vp-col-list'), function () {
var thisTag = $(this);
var varName = that.state.pandasObject;
var colName = $(this).find('option:selected').attr('data-code');
var colDtype = $(this).find('option:selected').attr('data-dtype');
+ var operTag = $(this).closest('td').find('.vp-oper-list');
var condTag = $(this).closest('td').find('.vp-condition');
if (colName == '.index') {
// index
$(thisTag).closest('td').find('.vp-cond-use-text').prop('checked', false);
+ $(operTag).replaceWith(function () {
+ return that.templateForConditionOperator('');
+ });
$(condTag).replaceWith(function () {
return that.templateForConditionCondInput([], '');
});
@@ -1358,12 +1450,18 @@ define([
} else {
$(thisTag).closest('td').find('.vp-cond-use-text').prop('checked', false);
}
+ $(operTag).replaceWith(function () {
+ return that.templateForConditionOperator(colDtype);
+ });
$(condTag).replaceWith(function () {
return that.templateForConditionCondInput(category, colDtype);
});
that.generateCode();
} catch {
$(thisTag).closest('td').find('.vp-cond-use-text').prop('checked', false);
+ $(operTag).replaceWith(function () {
+ return that.templateForConditionOperator(colDtype);
+ });
$(condTag).replaceWith(function () {
return that.templateForConditionCondInput([], colDtype);
});
@@ -1373,6 +1471,23 @@ define([
}
});
+ // change operator selection
+ $(document).on('change', this.wrapSelector('.vp-ds-cond-tbl .vp-oper-list'), function () {
+ var oper = $(this).val();
+ var condTag = $(this).closest('td').find('.vp-condition');
+ var useTextTag = $(this).closest('td').find('.vp-cond-use-text');
+ // var colDtype = $(this).closest('td').find('.vp-col-list option:selected').attr('data-dtype');
+
+ // if operator is isnull(), notnull(), disable condition input
+ if (oper == 'isnull()' || oper == 'notnull()') {
+ $(condTag).prop('disabled', true);
+ $(useTextTag).prop('disabled', true);
+ } else {
+ $(condTag).prop('disabled', false);
+ $(useTextTag).prop('disabled', false);
+ }
+ });
+
// use text
$(document).on('change', this.wrapSelector('.vp-ds-cond-tbl .vp-cond-use-text'), function () {
that.generateCode();
@@ -1447,7 +1562,7 @@ define([
var rowList = [];
for (var i = 0; i < rowTags.length; i++) {
var rowValue = $(rowTags[i]).data('code');
- if (rowValue != undefined) {
+ if (rowValue !== undefined) {
rowList.push(rowValue);
}
}
@@ -1500,15 +1615,17 @@ define([
condValue = com_util.formatString("'{0}'", cond);
}
if (oper == 'contains') {
- rowSelection.appendFormat('{0}.str.contains({1})', colValue, condValue);
+ rowSelection.appendFormat('`{0}`.str.contains({1})', colValue, condValue);
} else if (oper == 'not contains') {
- rowSelection.appendFormat('~{0}.str.contains({1})', colValue, condValue);
+ rowSelection.appendFormat('~`{0}`.str.contains({1})', colValue, condValue);
} else if (oper == 'starts with') {
- rowSelection.appendFormat('{0}.str.startswith({1})', colValue, condValue);
+ rowSelection.appendFormat('`{0}`.str.startswith({1})', colValue, condValue);
} else if (oper == 'ends with') {
- rowSelection.appendFormat('{0}.str.endswith({1})', colValue, condValue);
+ rowSelection.appendFormat('`{0}`.str.endswith({1})', colValue, condValue);
+ } else if (oper == 'isnull()' || oper == 'notnull()') {
+ rowSelection.appendFormat('`{0}`.{1}', colValue, oper);
} else {
- rowSelection.appendFormat('{0}{1}{2}', colValue, oper != ''?(' ' + oper):'', condValue != ''?(' ' + condValue):'');
+ rowSelection.appendFormat('`{0}`{1}{2}', colValue, oper != ''?(' ' + oper):'', condValue != ''?(' ' + condValue):'');
}
if (condList.length > 1) {
rowSelection.append(')');
@@ -1538,6 +1655,8 @@ define([
rowSelection.appendFormat('{0}.str.startswith({1})', colValue, condValue);
} else if (oper == 'ends with') {
rowSelection.appendFormat('{0}.str.endswith({1})', colValue, condValue);
+ } else if (oper == 'isnull()' || oper == 'notnull()') {
+ rowSelection.appendFormat('{0}.{1}', colValue, oper);
} else {
rowSelection.appendFormat('{0}{1}{2}', colValue, oper != ''?(' ' + oper):'', condValue != ''?(' ' + condValue):'');
}
@@ -1580,32 +1699,41 @@ define([
$(this.wrapSelector('.' + VP_DS_TO_FRAME)).parent().hide();
if (this.state.dataType == 'DataFrame') {
if (this.state.colType == 'indexing') {
- var colTags = $(this.wrapSelector('.' + VP_DS_SELECT_ITEM + '.select-col.added:not(.moving)'));
- if (colTags.length > 0) {
- var colList = [];
- for (var i = 0; i < colTags.length; i++) {
- var colValue = $(colTags[i]).data('code');
- if (colValue) {
- colList.push(colValue);
- }
- }
-
- // hide/show to frame
+ if (this.useInputColumns == true) {
+ colList = this.state.selectedColumns;
if (colList.length == 1) {
- $(this.wrapSelector('.' + VP_DS_TO_FRAME)).parent().show();
-
- // to frame
- if (this.state.toFrame) {
- colSelection.appendFormat('[{0}]', colList.toString());
- } else {
- colSelection.appendFormat('{0}', colList.toString());
- }
+ colSelection.appendFormat('{0}', colList.toString());
} else {
colSelection.appendFormat('[{0}]', colList.toString());
}
-
} else {
- colSelection.append(':');
+ var colTags = $(this.wrapSelector('.' + VP_DS_SELECT_ITEM + '.select-col.added:not(.moving)'));
+ if (colTags.length > 0) {
+ var colList = [];
+ for (var i = 0; i < colTags.length; i++) {
+ var colValue = $(colTags[i]).data('code');
+ if (colValue) {
+ colList.push(colValue);
+ }
+ }
+
+ // hide/show to frame
+ if (colList.length == 1) {
+ $(this.wrapSelector('.' + VP_DS_TO_FRAME)).parent().show();
+
+ // to frame
+ if (this.state.toFrame) {
+ colSelection.appendFormat('[{0}]', colList.toString());
+ } else {
+ colSelection.appendFormat('{0}', colList.toString());
+ }
+ } else {
+ colSelection.appendFormat('[{0}]', colList.toString());
+ }
+
+ } else {
+ colSelection.append(':');
+ }
}
} else if (this.state.colType == 'slicing') {
var start = $(this.wrapSelector('.' + VP_DS_COL_SLICE_START)).data('code');
diff --git a/js/m_ml/ModelInfo.js b/js/m_ml/ModelInfo.js
index 65053e6c..1f715372 100644
--- a/js/m_ml/ModelInfo.js
+++ b/js/m_ml/ModelInfo.js
@@ -313,9 +313,17 @@ define([
generateCode() {
let { model } = this.state;
+ let codeList = [];
let code = new com_String();
let replaceDict = {'${model}': model};
+ // If functions are available
+ if (this.state.optionConfig.functions != undefined) {
+ this.state.optionConfig.functions.forEach(func => {
+ codeList.push(func);
+ });
+ }
+
// If import code is available, generate its code in front of code
if (this.state.optionConfig.import != undefined) {
code.appendLine(this.state.optionConfig.import);
@@ -342,8 +350,9 @@ define([
}
}
}
+ codeList.push(code.toString());
- return code.toString();
+ return codeList;
}
getModelCategory(modelType) {
@@ -399,22 +408,61 @@ define([
{ name: 'importance_allocate', label: 'Allocate to', component: ['input'], placeholder: 'New variable', value: 'importances' }
]
},
+ 'feature_importances': {
+ name: 'feature_importances',
+ label: 'Feature importances',
+ functions: [
+ "def create_feature_importances(model, X_train=None, sort=False):\
+ \n if isinstance(X_train, pd.core.frame.DataFrame):\
+ \n feature_names = X_train.columns\
+ \n else:\n\
+ \n feature_names = [ 'X{}'.format(i) for i in range(len(model.feature_importances_)) ]\
+ \n\
+ \n df_i = pd.DataFrame(model.feature_importances_, index=feature_names, columns=['Feature_importance'])\
+ \n df_i['Percentage'] = 100 * (df_i['Feature_importance'] / df_i['Feature_importance'].max())\
+ \n if sort: df_i.sort_values(by='Feature_importance', ascending=False, inplace=True)\
+ \n df_i = df_i.round(2)\
+ \n\
+ \n return df_i"
+ ],
+ code: "${fi_allocate} = create_feature_importances(${model}, ${fi_featureData}${sort})",
+ description: 'Allocate feature_importances_',
+ options: [
+ { name: 'fi_featureData', label: 'Feature Data', component: ['var_select'], var_type: ['DataFrame', 'Series', 'ndarray', 'list', 'dict'], value: 'X_train' },
+ { name: 'fi_allocate', label: 'Allocate to', component: ['input'], placeholder: 'New variable', value: 'df_i' },
+ { name: 'sort', label: 'Sort data', component: ['bool_checkbox'], value: true, usePair: true }
+ ]
+ },
'plot_feature_importances': {
name: 'plot_feature_importances',
label: 'Plot feature importances',
- code: "def plot_feature_importances(model):\n\
- n_features = len(model.feature_importances_)\n\
- feature_names = [ 'X{}'.format(i) for i in range(n_features) ]\n\
- plt.barh(np.arange(n_features), model.feature_importances_, align='center')\n\
- plt.yticks(np.arange(n_features), feature_names)\n\
- plt.xlabel('Feature importance')\n\
- plt.ylabel('Features')\n\
- plt.ylim(-1, n_features)\n\
- plt.show()\n\n\
-plot_feature_importances(${model})",
- description: '',
+ functions: [
+ "def create_feature_importances(model, X_train=None, sort=False):\
+ \n if isinstance(X_train, pd.core.frame.DataFrame):\
+ \n feature_names = X_train.columns\
+ \n else:\n\
+ \n feature_names = [ 'X{}'.format(i) for i in range(len(model.feature_importances_)) ]\
+ \n\
+ \n df_i = pd.DataFrame(model.feature_importances_, index=feature_names, columns=['Feature_importance'])\
+ \n df_i['Percentage'] = 100 * (df_i['Feature_importance'] / df_i['Feature_importance'].max())\
+ \n if sort: df_i.sort_values(by='Feature_importance', ascending=False, inplace=True)\
+ \n df_i = df_i.round(2)\
+ \n\
+ \n return df_i",
+ "def plot_feature_importances(model, X_train=None, sort=False):\
+ \n df_i = create_feature_importances(model, X_train, sort)\
+ \n\
+ \n df_i['Percentage'].sort_values().plot(kind='barh')\
+ \n plt.xlabel('Feature importance Percentage')\
+ \n plt.ylabel('Features')\
+ \n\
+ \n plt.show()"
+ ],
+ code: "plot_feature_importances(${model}, ${fi_featureData}${sort})",
+ description: 'Draw feature_importances_',
options: [
-
+ { name: 'fi_featureData', label: 'Feature Data', component: ['var_select'], var_type: ['DataFrame', 'Series', 'ndarray', 'list', 'dict'], value: 'X_train' },
+ { name: 'sort', label: 'Sort data', component: ['bool_checkbox'], value: true, usePair: true }
]
}
}
@@ -522,6 +570,7 @@ plot_feature_importances(${model})",
]
},
'permutation_importance': defaultInfos['permutation_importance'],
+ 'feature_importances': defaultInfos['feature_importances'],
'plot_feature_importances': defaultInfos['plot_feature_importances'],
'Coefficient': {
name: 'coef_',
@@ -573,11 +622,11 @@ plot_feature_importances(${model})",
name: 'roc_curve',
label: 'ROC Curve',
import: 'from sklearn import metrics',
- code: "fpr, tpr, thresholds = metrics.roc_curve(${roc_targetData}, ${model}.predict_proba(${roc_featureData})[:, 1])\n\
-plt.plot(fpr, tpr, label='ROC Curve')\n\
-plt.xlabel('Sensitivity')\n\
-plt.ylabel('Specificity')\n\
-plt.show()",
+ code: "fpr, tpr, thresholds = metrics.roc_curve(${roc_targetData}, ${model}.predict_proba(${roc_featureData})[:, 1])\
+ \nplt.plot(fpr, tpr, label='ROC Curve')\
+ \nplt.xlabel('Sensitivity')\
+ \nplt.ylabel('Specificity')\
+ \nplt.show()",
description: '',
options: [
{ name: 'roc_targetData', label: 'Target Data', component: ['var_select'], var_type: ['DataFrame', 'Series', 'ndarray', 'list', 'dict'], value: 'y_test' },
@@ -595,8 +644,16 @@ plt.show()",
{ name: 'auc_featureData', label: 'Feature Data', component: ['var_select'], var_type: ['DataFrame', 'Series', 'ndarray', 'list', 'dict'], value: 'X_test' }
]
},
- 'permutation_importance': defaultInfos['permutation_importance'],
- 'plot_feature_importances': defaultInfos['plot_feature_importances']
+ 'permutation_importance': defaultInfos['permutation_importance']
+ }
+
+ // feature importances
+ if (modelType != 'LogisticRegression' && modelType != 'SVC') {
+ infos = {
+ ...infos,
+ 'feature_importances': defaultInfos['feature_importances'],
+ 'plot_feature_importances': defaultInfos['plot_feature_importances']
+ }
}
// use decision_function on ROC, AUC
@@ -608,11 +665,11 @@ plt.show()",
...infos,
'roc_curve': {
...infos['roc_curve'],
- code: "fpr, tpr, thresholds = metrics.roc_curve(${roc_targetData}, ${model}.decision_function(${roc_featureData}))\n\
-plt.plot(fpr, tpr, label='ROC Curve')\n\
-plt.xlabel('Sensitivity')\n\
-plt.ylabel('Specificity')\n\
-plt.show()"
+ code: "fpr, tpr, thresholds = metrics.roc_curve(${roc_targetData}, ${model}.decision_function(${roc_featureData}))\
+ \nplt.plot(fpr, tpr, label='ROC Curve')\
+ \nplt.xlabel('Sensitivity')\
+ \nplt.ylabel('Specificity')\
+ \nplt.show()"
},
'auc': {
...infos['auc'],
diff --git a/js/m_ml/dataSplit.js b/js/m_ml/dataSplit.js
index 6005e748..2051234c 100644
--- a/js/m_ml/dataSplit.js
+++ b/js/m_ml/dataSplit.js
@@ -19,8 +19,9 @@ define([
'vp_base/js/com/com_Const',
'vp_base/js/com/com_String',
'vp_base/js/com/component/PopupComponent',
- 'vp_base/js/com/component/VarSelector2'
-], function(dsHtml, com_util, com_interface, com_Const, com_String, PopupComponent, VarSelector2) {
+ 'vp_base/js/com/component/VarSelector2',
+ 'vp_base/js/com/component/DataSelector'
+], function(dsHtml, com_util, com_interface, com_Const, com_String, PopupComponent, VarSelector2, DataSelector) {
/**
* Data split
@@ -37,6 +38,7 @@ define([
targetData: '',
testSize: 0.25,
shuffle: 'True',
+ stratify: '',
trainFeatures: 'X_train',
trainTarget: 'y_train',
testFeatures: 'X_test',
@@ -101,27 +103,20 @@ define([
}
$(page).find('#testSize').html(sizeOptions);
- // varselector TEST:
- let varSelector = new VarSelector2(this.wrapSelector());
- varSelector.setComponentID('featureData');
- varSelector.addClass('vp-state vp-input');
- varSelector.setValue(this.state.featureData);
- varSelector.setPlaceholder('Select feature data');
- $(page).find('#featureData').replaceWith(varSelector.toTagString());
-
- varSelector = new VarSelector2(this.wrapSelector());
- varSelector.setComponentID('targetData');
- varSelector.addClass('vp-state vp-input');
- varSelector.setValue(this.state.targetData);
- varSelector.setPlaceholder('Select target data');
- $(page).find('#targetData').replaceWith(varSelector.toTagString());
-
- varSelector = new VarSelector2(this.wrapSelector());
- varSelector.setComponentID('stratify');
- varSelector.addClass('vp-state vp-input');
- varSelector.setValue(this.state.stratify);
- varSelector.setPlaceholder('None');
- $(page).find('#stratify').replaceWith(varSelector.toTagString());
+ let featureSelector = new DataSelector({
+ pageThis: this, id: 'featureData', placeholder: 'Select feature data'
+ });
+ $(page).find('#featureData').replaceWith(featureSelector.toTagString());
+
+ let targetSelector = new DataSelector({
+ pageThis: this, id: 'targetData', placeholder: 'Select target data'
+ });
+ $(page).find('#targetData').replaceWith(targetSelector.toTagString());
+
+ let stratifySelector = new DataSelector({
+ pageThis: this, id: 'stratify', placeholder: 'None'
+ });
+ $(page).find('#stratify').replaceWith(stratifySelector.toTagString());
// load state
let that = this;
diff --git a/js/m_visualize/Plotly.js b/js/m_visualize/Plotly.js
new file mode 100644
index 00000000..cec98db6
--- /dev/null
+++ b/js/m_visualize/Plotly.js
@@ -0,0 +1,349 @@
+/*
+ * Project Name : Visual Python
+ * Description : GUI-based Python code generator
+ * File Name : Plotly.js
+ * Author : Black Logic
+ * Note : Visualization > Plotly
+ * License : GNU GPLv3 with Visual Python special exception
+ * Date : 2022. 05. 16
+ * Change Date :
+ */
+
+//============================================================================
+// [CLASS] Plotly
+//============================================================================
+define([
+ 'text!vp_base/html/m_visualize/plotly.html!strip',
+ 'css!vp_base/css/m_visualize/plotly.css',
+ 'vp_base/js/com/com_String',
+ 'vp_base/js/com/com_generatorV2',
+ 'vp_base/js/com/com_util',
+ 'vp_base/js/com/component/PopupComponent',
+ 'vp_base/js/com/component/SuggestInput',
+ 'vp_base/js/com/component/FileNavigation',
+ 'vp_base/js/com/component/DataSelector',
+ 'vp_base/data/m_visualize/plotlyLibrary',
+], function(ptHTML, ptCss, com_String, com_generator, com_util, PopupComponent, SuggestInput, FileNavigation, DataSelector, PLOTLY_LIBRARIES) {
+
+ /**
+ * TODO: libraries.json add menu
+ * {
+ "id" : "visualize_plotly",
+ "type" : "function",
+ "level": 1,
+ "name" : "Plotly",
+ "tag" : "PLOTLY,VISUALIZATION,VISUALIZE",
+ "path" : "visualpython - visualization - plotly",
+ "desc" : "Plotly express",
+ "file" : "m_visualize/Plotly",
+ "apps" : {
+ "color": 5,
+ "icon": "apps/apps_visualize.svg"
+ }
+ },
+ */
+ class Plotly extends PopupComponent {
+ _init() {
+ super._init();
+
+ this.config.size = { width: 1064, height: 550 };
+ this.config.installButton = true;
+ this.config.importButton = true;
+ this.config.dataview = false;
+
+ this.state = {
+ chartType: 'scatter',
+ data: '',
+ userOption: '',
+ autoRefresh: true,
+ ...this.state
+ }
+
+ /**
+ * Plotly.express functions
+ * ---
+ * Basics: scatter, line, area, bar, funnel, timeline
+ * Part-of-Whole: pie, sunburst, treemap, icicle, funnel_area
+ * 1D Distributions: histogram, box, violin, strip, ecdf
+ * 2D Distributions: density_heatmap, density_contour
+ * Matrix or Image Input: imshow
+ * 3-Dimensional: scatter_3d, line_3d
+ * Multidimensional: scatter_matrix, parallel_coordinates, parallel_categories
+ * Tile Maps: scatter_mapbox, line_mapbox, choropleth_mapbox, density_mapbox
+ * Outline Maps: scatter_geo, line_geo, choropleth
+ * Polar Charts: scatter_polar, line_polar, bar_polar
+ * Ternary Charts: scatter_ternary, line_ternary
+ */
+ this.chartConfig = PLOTLY_LIBRARIES;
+ this.chartTypeList = {
+ 'Basics': [ 'scatter', 'line', 'area', 'bar', 'funnel', 'timeline' ],
+ 'Part-of-Whole': [ 'pie', 'sunburst', 'treemap', 'icicle', 'funnel_area' ],
+ '1D Distributions': [ 'histogram', 'box', 'violin', 'strip', 'ecdf' ],
+ '2D Distributions': [ 'density_heatmap', 'density_contour' ],
+ 'Matrix or Image Input': [ 'imshow' ],
+ '3-Dimensional': [ 'scatter_3d', 'line_3d' ],
+ 'Multidimensional': [ 'scatter_matrix', 'parallel_coordinates', 'parallel_categories' ],
+ 'Tile Maps': [ 'scatter_mapbox', 'line_mapbox', 'choropleth_mapbox', 'density_mapbox' ],
+ 'Outline Maps': [ 'scatter_geo', 'line_geo', 'choropleth' ],
+ 'Polar Charts': [ 'scatter_polar', 'line_polar', 'bar_polar' ],
+ 'Ternary Charts': [ 'scatter_ternary', 'line_ternary' ],
+ }
+
+ }
+
+ _bindEvent() {
+ super._bindEvent();
+
+ let that = this;
+
+ // change tab
+ $(this.wrapSelector('.vp-tab-item')).on('click', function() {
+ let type = $(this).data('type'); // data / wordcloud / plot
+
+ $(that.wrapSelector('.vp-tab-bar .vp-tab-item')).removeClass('vp-focus');
+ $(this).addClass('vp-focus');
+
+ $(that.wrapSelector('.vp-tab-page-box > .vp-tab-page')).hide();
+ $(that.wrapSelector(com_util.formatString('.vp-tab-page[data-type="{0}"]', type))).show();
+ });
+
+ // use data or not
+ $(this.wrapSelector('#setXY')).on('change', function() {
+ let setXY = $(this).prop('checked');
+ if (setXY == false) {
+ // set Data
+ $(that.wrapSelector('#data')).prop('disabled', false);
+
+ $(that.wrapSelector('#x')).closest('.vp-ds-box').replaceWith(' ');
+ $(that.wrapSelector('#y')).closest('.vp-ds-box').replaceWith(' ');
+ $(that.wrapSelector('#hue')).closest('.vp-ds-box').replaceWith(' ');
+ } else {
+ // set X Y indivisually
+ // disable data selection
+ $(that.wrapSelector('#data')).prop('disabled', true);
+ $(that.wrapSelector('#data')).val('');
+ that.state.data = '';
+ that.state.x = '';
+ that.state.y = '';
+ that.state.hue = '';
+
+ let dataSelectorX = new DataSelector({ pageThis: that, id: 'x' });
+ $(that.wrapSelector('#x')).replaceWith(dataSelectorX.toTagString());
+
+ let dataSelectorY = new DataSelector({ pageThis: that, id: 'y' });
+ $(that.wrapSelector('#y')).replaceWith(dataSelectorY.toTagString());
+
+ let dataSelectorHue = new DataSelector({ pageThis: that, id: 'hue' });
+ $(that.wrapSelector('#hue')).replaceWith(dataSelectorHue.toTagString());
+
+ }
+ });
+
+ // load preview
+ $(document).off('change', this.wrapSelector('.vp-state'));
+ $(document).on('change', this.wrapSelector('.vp-state'), function(evt) {
+ that._saveSingleState($(this)[0]);
+ if (that.state.autoRefresh) {
+ that.loadPreview();
+ }
+ evt.stopPropagation();
+ });
+
+ }
+
+ templateForBody() {
+ let page = $(ptHTML);
+
+ let that = this;
+
+ // chart types
+ let chartTypeTag = new com_String();
+ Object.keys(this.chartTypeList).forEach(chartCategory => {
+ let chartOptionTag = new com_String();
+ that.chartTypeList[chartCategory].forEach(opt => {
+ let optConfig = that.chartConfig[opt];
+ let selectedFlag = '';
+ if (opt == that.state.chartType) {
+ selectedFlag = 'selected';
+ }
+ chartOptionTag.appendFormatLine('{2} ',
+ opt, selectedFlag, opt);
+ })
+ chartTypeTag.appendFormatLine('{1} ',
+ chartCategory, chartOptionTag.toString());
+ });
+ $(page).find('#chartType').html(chartTypeTag.toString());
+
+ // chart variable
+ let dataSelector = new DataSelector({
+ type: 'data',
+ pageThis: this,
+ id: 'data',
+ select: function(value, dtype) {
+ that.state.dtype = dtype;
+ console.log('data selected');
+
+ if (dtype == 'DataFrame') {
+ $(that.wrapSelector('#x')).prop('disabled', false);
+ $(that.wrapSelector('#y')).prop('disabled', false);
+
+ // bind column source using selected dataframe
+ com_generator.vp_bindColumnSource(that, 'data', ['x', 'y'], 'select', true, true);
+ } else {
+ $(that.wrapSelector('#x')).prop('disabled', true);
+ $(that.wrapSelector('#y')).prop('disabled', true);
+ }
+ },
+ finish: function(value, dtype) {
+ that.state.dtype = dtype;
+ console.log('data selected');
+
+ if (dtype == 'DataFrame') {
+ $(that.wrapSelector('#x')).prop('disabled', false);
+ $(that.wrapSelector('#y')).prop('disabled', false);
+
+ // bind column source using selected dataframe
+ com_generator.vp_bindColumnSource(that, 'data', ['x', 'y'], 'select', true, true);
+ } else {
+ $(that.wrapSelector('#x')).prop('disabled', true);
+ $(that.wrapSelector('#y')).prop('disabled', true);
+ }
+ }
+ });
+ $(page).find('#data').replaceWith(dataSelector.toTagString());
+
+ //================================================================
+ // Load state
+ //================================================================
+ Object.keys(this.state).forEach(key => {
+ let tag = $(page).find('#' + key);
+ let tagName = $(tag).prop('tagName'); // returns with UpperCase
+ let value = that.state[key];
+ if (value == undefined) {
+ return;
+ }
+ switch(tagName) {
+ case 'INPUT':
+ let inputType = $(tag).prop('type');
+ if (inputType == 'text' || inputType == 'number' || inputType == 'hidden') {
+ $(tag).val(value);
+ break;
+ }
+ if (inputType == 'checkbox') {
+ $(tag).prop('checked', value);
+ break;
+ }
+ break;
+ case 'TEXTAREA':
+ case 'SELECT':
+ default:
+ $(tag).val(value);
+ break;
+ }
+ });
+
+ return page;
+ }
+
+ render() {
+ super.render();
+
+ let that = this;
+
+ // Add style
+ $(this.wrapSelector('.vp-popup-body-top-bar')).css({
+ 'position': 'absolute',
+ 'left': 'calc(50% - 250px)'
+ });
+ $(this.wrapSelector('.vp-popup-codeview-box')).css({
+ 'height': '200px'
+ });
+
+ this.loadPreview();
+ }
+
+ loadPreview() {
+ let that = this;
+ let code = this.generateCode(true);
+
+ // 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('#vp_ptPreview')).html('');
+ if (htmlResult != undefined) {
+ // 1. HTML tag
+ $(that.wrapSelector('#vp_ptPreview')).append(htmlResult);
+ } else if (imgResult != undefined) {
+ // 2. Image data (base64)
+ var imgTag = ' ';
+ $(that.wrapSelector('#vp_ptPreview')).append(imgTag);
+ } else if (textResult != undefined) {
+ // 3. Text data
+ var preTag = document.createElement('pre');
+ $(preTag).text(textResult);
+ $(that.wrapSelector('#vp_ptPreview')).html(preTag);
+ }
+ } else {
+ var errorContent = '';
+ if (msg.content.ename) {
+ errorContent = com_util.templateForErrorBox(msg.content.ename, msg.content.evalue);
+ }
+ $(that.wrapSelector('#vp_ptPreview')).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);
+ }
+ $(that.wrapSelector('#vp_ptPreview')).html(errorContent);
+ vpLog.display(VP_LOG_TYPE.ERROR, msg.content.ename, msg.content.evalue, msg.content);
+ });
+ }
+
+ generateInstallCode() {
+ return ['!pip install plotly'];
+ }
+
+ generateImportCode() {
+ var code = new com_String();
+ code.appendLine('import plotly.express as px'); // need to be installed
+ code.appendLine('import plotly');
+ code.append('plotly.offline.init_notebook_mode(connected=True)');
+ return [code.toString()];
+ }
+
+ generateCode(preview=false) {
+ /**
+ * Plotly is not showing sometimes...
+ * import plotly
+ * plotly.offline.init_notebook_mode(connected=True)
+ */
+ let {
+ chartType,
+ data, x, y, setXY,
+ userOption
+ } = this.state;
+ let code = new com_String();
+ let config = this.chartConfig[chartType];
+
+ let etcOptionCode = [];
+ // add user option
+ if (userOption != '') {
+ etcOptionCode.push(userOption);
+ }
+
+ let generatedCode = com_generator.vp_codeGenerator(this, config, this.state, etcOptionCode.join(', '));
+ code.append(generatedCode);
+ return code.toString();
+ }
+ }
+
+ return Plotly;
+});
\ No newline at end of file
diff --git a/js/m_visualize/Seaborn.js b/js/m_visualize/Seaborn.js
index 32498693..4cfb407b 100644
--- a/js/m_visualize/Seaborn.js
+++ b/js/m_visualize/Seaborn.js
@@ -45,6 +45,19 @@ define([
x: '',
y: '',
hue: '',
+ // axes options
+ x_limit_from: '',
+ x_limit_to: '',
+ y_limit_from: '',
+ y_limit_to: '',
+ xticks: '',
+ xticks_label: '',
+ xticks_rotate: '',
+ removeXticks: false,
+ yticks: '',
+ yticks_label: '',
+ yticks_rotate: '',
+ removeYticks: false,
// info options
title: '',
x_label: '',
@@ -56,11 +69,8 @@ define([
useGrid: '',
gridColor: '#000000',
markerStyle: '',
- // setting options
- x_limit_from: '',
- x_limit_to: '',
- y_limit_from: '',
- y_limit_to: '',
+ // code option
+ userCode: '',
// preview options
useSampling: true,
sampleCount: 30,
@@ -157,6 +167,15 @@ define([
$(that.wrapSelector(com_util.formatString('.vp-tab-page-box.{0} > .vp-tab-page', level))).hide();
$(that.wrapSelector(com_util.formatString('.vp-tab-page[data-type="{0}"]', type))).show();
});
+
+ $(this.wrapSelector('#chartType')).on('change', function() {
+ // add bins to histplot
+ let chartType = $(this).val();
+ $(that.wrapSelector('.sb-option')).hide();
+ if (chartType == 'histplot') {
+ $(that.wrapSelector('.sb-option.bins')).show();
+ }
+ })
// use data or not
$(this.wrapSelector('#setXY')).on('change', function() {
@@ -240,6 +259,7 @@ define([
pageThis: this,
id: 'data',
select: function(value, dtype) {
+ that.state.data = value;
that.state.dtype = dtype;
if (dtype == 'DataFrame') {
@@ -311,6 +331,12 @@ define([
});
$(page).find('#sampleCount').html(sampleCountTag.toString());
+ // data options depend on chart type
+ $(page).find('.sb-option').hide();
+ if (this.state.chartType == 'histplot') {
+ $(page).find('.sb-option.bins').show();
+ }
+
//================================================================
// Load state
//================================================================
@@ -414,6 +440,25 @@ define([
$(this.wrapSelector('#hue')).prop('disabled', true);
}
}
+
+ // load code tab - code mirror
+ let that = this;
+ let userCodeKey = 'userCode1';
+ let userCodeTarget = this.wrapSelector('#' + userCodeKey);
+ this.codeArea = this.initCodemirror({
+ key: userCodeKey,
+ selector: userCodeTarget,
+ events: [{
+ key: 'change',
+ callback: function(instance, evt) {
+ // save its state
+ instance.save();
+ that.state[userCodeKey] = $(userCodeTarget).val();
+ // refresh preview
+ that.loadPreview();
+ }
+ }]
+ });
this.loadPreview();
}
@@ -584,9 +629,12 @@ define([
generateCode(preview=false) {
let {
chartType, data, x, y, hue, setXY, userOption='',
+ x_limit_from, x_limit_to, y_limit_from, y_limit_to,
+ xticks, xticks_label, xticks_rotate, removeXticks,
+ yticks, yticks_label, yticks_rotate, removeYticks,
title, x_label, y_label, legendPos,
useColor, color, useGrid, gridColor, markerStyle,
- x_limit_from, x_limit_to, y_limit_from, y_limit_to,
+ userCode1,
useSampling, sampleCount
} = this.state;
@@ -643,6 +691,56 @@ define([
let generatedCode = com_generator.vp_codeGenerator(this, config, state, etcOptionCode.join(', '));
+ // Axes
+ if (x_limit_from != '' && x_limit_to != '') {
+ chartCode.appendFormatLine("plt.xlim(({0}, {1}))", x_limit_from, x_limit_to);
+ }
+ if (y_limit_from != '' && y_limit_to != '') {
+ chartCode.appendFormatLine("plt.ylim(({0}, {1}))", y_limit_from, y_limit_to);
+ }
+ if (legendPos != '') {
+ chartCode.appendFormatLine("plt.legend(loc='{0}')", legendPos);
+ }
+ if (removeXticks === true) {
+ // use empty list to disable xticks
+ chartCode.appendLine("plt.xticks([])");
+ } else {
+ let xticksOptList = [];
+ if (xticks && xticks !== '') {
+ xticksOptList.push(xticks);
+ // Not able to use xticks_label without xticks
+ if (xticks_label && xticks_label != '') {
+ xticksOptList.push(xticks_label);
+ }
+ }
+ if (xticks_rotate && xticks_rotate !== '') {
+ xticksOptList.push('rotation=' + xticks_rotate)
+ }
+ // Add option to chart code if available
+ if (xticksOptList.length > 0) {
+ chartCode.appendFormatLine("plt.xticks({0})", xticksOptList.join(', '));
+ }
+ }
+ if (removeYticks === true) {
+ // use empty list to disable yticks
+ chartCode.appendLine("plt.yticks([])");
+ } else {
+ let yticksOptList = [];
+ if (yticks && yticks !== '') {
+ yticksOptList.push(yticks);
+ // Not able to use xticks_label without xticks
+ if (yticks_label && yticks_label != '') {
+ yticksOptList.push(yticks_label);
+ }
+ }
+ if (yticks_rotate && yticks_rotate !== '') {
+ yticksOptList.push('rotation=' + yticks_rotate)
+ }
+ // Add option to chart code if available
+ if (yticksOptList.length > 0) {
+ chartCode.appendFormatLine("plt.yticks({0})", yticksOptList.join(', '));
+ }
+ }
// Info
if (title && title != '') {
chartCode.appendFormatLine("plt.title('{0}')", title);
@@ -653,15 +751,6 @@ define([
if (y_label && y_label != '') {
chartCode.appendFormatLine("plt.ylabel('{0}')", y_label);
}
- if (x_limit_from != '' && x_limit_to != '') {
- chartCode.appendFormatLine("plt.xlim(({0}, {1}))", x_limit_from, x_limit_to);
- }
- if (y_limit_from != '' && y_limit_to != '') {
- chartCode.appendFormatLine("plt.ylim(({0}, {1}))", y_limit_from, y_limit_to);
- }
- if (legendPos != '') {
- chartCode.appendFormatLine("plt.legend(loc='{0}')", legendPos);
- }
// Style - Grid
// plt.grid(True, axis='x', color='red', alpha=0.5, linestyle='--')
let gridCodeList = [];
@@ -674,9 +763,7 @@ define([
if (gridCodeList.length > 0) {
chartCode.appendFormatLine("plt.grid({0})", gridCodeList.join(', '));
}
- chartCode.append('plt.show()');
- let convertedData = data;
if (preview) {
// Ignore warning
code.appendLine('import warnings');
@@ -692,9 +779,17 @@ define([
code.appendLine(chartCode.toString());
} else {
code.appendLine(generatedCode);
- code.appendLine(chartCode.toString());
+ if (chartCode.length > 0) {
+ code.append(chartCode.toString());
+ }
}
+ if (userCode1 && userCode1 != '') {
+ code.appendLine(userCode1);
+ }
+
+ code.append('plt.show()');
+
// remove last Enter(\n) from code and then run it
return code.toString().replace(/\n+$/, "");
}
diff --git a/js/m_visualize/WordCloud.js b/js/m_visualize/WordCloud.js
index 922fe14e..bce06f24 100644
--- a/js/m_visualize/WordCloud.js
+++ b/js/m_visualize/WordCloud.js
@@ -62,6 +62,8 @@ define([
that.state.useFile = true;
$(that.wrapSelector('.vp-wc-file-option')).show();
+ $(that.wrapSelector('#useFile')).prop('checked', true);
+ $(that.wrapSelector('#useFile')).trigger('change');
// set text
$(that.wrapSelector('#data')).val(path);
@@ -71,6 +73,16 @@ define([
fileNavi.open();
});
+ // use file
+ $(this.wrapSelector('#useFile')).on('change', function() {
+ let checked = $(this).prop('checked');
+ if (checked === true) {
+ $(that.wrapSelector('.vp-wc-file-option')).show();
+ } else {
+ $(that.wrapSelector('.vp-wc-file-option')).hide();
+ }
+ });
+
// change tab
$(this.wrapSelector('.vp-tab-item')).on('click', function() {
let type = $(this).data('type'); // data / wordcloud / plot
@@ -91,6 +103,11 @@ define([
}
evt.stopPropagation();
});
+
+ // preview refresh
+ $(this.wrapSelector('#previewRefresh')).on('click', function() {
+ that.loadPreview();
+ });
}
@@ -158,10 +175,12 @@ define([
id: 'data',
select: function() {
that.state.useFile = false;
+ $(that.wrapSelector('#useFile')).prop('checked', false);
$(that.wrapSelector('.vp-wc-file-option')).hide();
},
finish: function() {
that.state.useFile = false;
+ $(that.wrapSelector('#useFile')).prop('checked', false);
$(that.wrapSelector('.vp-wc-file-option')).hide();
}
});
@@ -201,6 +220,7 @@ define([
suggestInput.addClass('vp-input vp-state');
suggestInput.setSuggestList(function() { return encodingList; });
suggestInput.setPlaceholder('encoding option');
+ suggestInput.setValue(that.state.encoding);
return suggestInput.toTagString();
});