diff --git a/css/common/subsetEditor.css b/css/common/subsetEditor.css
index 1a1450ba..663ea3f5 100644
--- a/css/common/subsetEditor.css
+++ b/css/common/subsetEditor.css
@@ -242,16 +242,11 @@
margin: auto;
display: inherit;
}
-.vp-ds-select-add-btn {
+.vp-ds-select-btn-box button {
height: 24px;
background: #FFFFFF;
border: 0.25px solid #E4E4E4;
-}
-.vp-ds-select-del-btn {
- height: 24px;
- background: #FFFFFF;
- border: 0.25px solid #E4E4E4;
- margin-top: 5px;
+ grid-row-gap: 5px;
}
.vp-ds-btn-add-condition {
width: 95px;
diff --git a/src/api/functions/fileNaviCommand.py b/src/api/functions/fileNaviCommand.py
index 52858a8d..97c1a466 100644
--- a/src/api/functions/fileNaviCommand.py
+++ b/src/api/functions/fileNaviCommand.py
@@ -3,6 +3,7 @@
"""
import os as _vp_os
+import stat as _vp_stat
def _vp_get_userprofile_path():
"""
@@ -64,9 +65,17 @@ def _vp_sizeof_fmt(num, suffix='B'):
num /= 1024.0
return '%.1f%s%s' % (num, 'Yi', suffix)
-def _vp_search_path(path):
+def _vp_search_path(path, show_hidden=False):
"""
Search child folder and file list under the given path
+ path: str
+ path to search file/dir list
+ show_hidden: bool (optional; default: False)
+ set True for show hidden file/dir
+ returns: list
+ list with scanned file/dir list
+ 0 element with current and parent path information
+ 1~n elements with file/dir list under given path
"""
import datetime as _dt
_current = _vp_os.path.abspath(path)
@@ -76,20 +85,21 @@ def _vp_search_path(path):
_info = []
_info.append({'current':_current,'parent':_parent})
for _entry in i:
- _name = _entry.name
- _path = _entry.path # 파일 경로
- _stat = _entry.stat()
- _size = _vp_sizeof_fmt(_stat.st_size) # 파일 크기
- _a_time = _stat.st_atime # 최근 액세스 시간
- _a_dt = _dt.datetime.fromtimestamp(_a_time).strftime('%Y-%m-%d %H:%M')
- _m_time = _stat.st_mtime # 최근 수정 시간
- _m_dt = _dt.datetime.fromtimestamp(_m_time).strftime('%Y-%m-%d %H:%M')
- _e_type = 'other'
- if _entry.is_file():
- _e_type = 'file'
- elif _entry.is_dir():
- _e_type = 'dir'
- _info.append({'name':_name, 'type':_e_type, 'path':_path, 'size':_size, 'atime':str(_a_dt), 'mtime':str(_m_dt)})
+ if show_hidden or _vp_check_hidden(_entry.path) == False:
+ _name = _entry.name
+ _path = _entry.path # 파일 경로
+ _stat = _entry.stat()
+ _size = _vp_sizeof_fmt(_stat.st_size) # 파일 크기
+ _a_time = _stat.st_atime # 최근 액세스 시간
+ _a_dt = _dt.datetime.fromtimestamp(_a_time).strftime('%Y-%m-%d %H:%M')
+ _m_time = _stat.st_mtime # 최근 수정 시간
+ _m_dt = _dt.datetime.fromtimestamp(_m_time).strftime('%Y-%m-%d %H:%M')
+ _e_type = 'other'
+ if _entry.is_file():
+ _e_type = 'file'
+ elif _entry.is_dir():
+ _e_type = 'dir'
+ _info.append({'name':_name, 'type':_e_type, 'path':_path, 'size':_size, 'atime':str(_a_dt), 'mtime':str(_m_dt)})
return _info
def _vp_get_image_by_path(path):
@@ -104,10 +114,20 @@ def _vp_get_relative_path(start, path):
"""
Get relative path using start path and current path
start: str
- start path
+ start path+
path: str
current path
returns: str
current relative path
"""
- return _vp_os.path.relpath(path, start)
\ No newline at end of file
+ return _vp_os.path.relpath(path, start)
+
+def _vp_check_hidden(path):
+ """
+ Check if it's hidden
+ path: str
+ file path
+ returns: bool
+ True for hidden file/dir, False for others
+ """
+ return bool(_vp_os.stat(path).st_file_attributes & _vp_stat.FILE_ATTRIBUTE_HIDDEN)
\ No newline at end of file
diff --git a/src/common/vpBind.js b/src/common/vpBind.js
index 46499646..f57cfb04 100644
--- a/src/common/vpBind.js
+++ b/src/common/vpBind.js
@@ -72,11 +72,11 @@ define([
this.codepreview = undefined;
this.howList = [
- { label: 'Inner', value: 'inner' },
- { label: 'Outer', value: 'outer' },
- { label: 'Left', value: 'left' },
- { label: 'Right', value: 'right' },
- { label: 'Cross', value: 'cross' },
+ { label: 'Inner', value: 'inner', desc: 'Inner join' },
+ { label: 'Full outer', value: 'outer', desc: 'Full outer join' },
+ { label: 'Left outer', value: 'left', desc: 'Left outer join' },
+ { label: 'Right outer', value: 'right', desc: 'Right outer join' },
+ { label: 'Cross', value: 'cross', desc: 'Cartesian product' },
]
}
@@ -116,13 +116,16 @@ define([
$(this._wrapSelector('#vp_bdHow')).val(merge.how);
this._loadSelectorInput(this._wrapSelector('#vp_bdOn'), merge.on);
- if (on && on.length > 0) {
+ if (merge.on && merge.on.length > 0) {
$(this._wrapSelector('#vp_bdLeftOnSelect')).attr('disabled', true);
$(this._wrapSelector('#vp_bdRightOnSelect')).attr('disabled', true);
+ $(this._wrapSelector('#vp_bdLeftIndex')).attr('disabled', true);
+ $(this._wrapSelector('#vp_bdRightIndex')).attr('disabled', true);
}
this._loadSelectorInput(this._wrapSelector('#vp_bdLeftOn'), merge.left.on);
this._loadSelectorInput(this._wrapSelector('#vp_bdRightOn'), merge.right.on);
- if (merge.left.on.length > 0 || merge.right.on.length > 0) {
+ if (merge.left.on.length > 0 || merge.right.on.length > 0
+ || merge.left.useIndex || merge.right.useIndex) {
$(this._wrapSelector('#vp_bdOnSelect')).attr('disabled', true);
}
@@ -361,7 +364,7 @@ define([
page.appendFormatLine('');
page.appendLine('');
@@ -666,9 +669,13 @@ define([
if (colList && colList.length > 0) {
$(that._wrapSelector('#vp_bdLeftOnSelect')).attr('disabled', true);
$(that._wrapSelector('#vp_bdRightOnSelect')).attr('disabled', true);
+ $(that._wrapSelector('#vp_bdLeftIndex')).attr('disabled', true);
+ $(that._wrapSelector('#vp_bdRightIndex')).attr('disabled', true);
} else {
$(that._wrapSelector('#vp_bdLeftOnSelect')).attr('disabled', false);
$(that._wrapSelector('#vp_bdRightOnSelect')).attr('disabled', false);
+ $(that._wrapSelector('#vp_bdLeftIndex')).attr('disabled', false);
+ $(that._wrapSelector('#vp_bdRightIndex')).attr('disabled', false);
}
});
@@ -927,7 +934,7 @@ define([
//================================================================
// On columns
//================================================================
- code.appendFormat(', on=[{0}]', on.map(col => col.code));
+ code.appendFormat(', on=[{0}]', merge.on.map(col => col.code));
} else {
//====================================================================
// Left & Right On columns
diff --git a/src/common/vpCommon.js b/src/common/vpCommon.js
index 9bb9d060..61ae16ef 100644
--- a/src/common/vpCommon.js
+++ b/src/common/vpCommon.js
@@ -298,7 +298,6 @@ define([
iopub: {
output: function(msg) {
// msg.content.data['text/plain']
- console.log(msg);
resolve(msg.content.data);
}
}
diff --git a/src/common/vpGroupby.js b/src/common/vpGroupby.js
index 8cab9a4d..d909e303 100644
--- a/src/common/vpGroupby.js
+++ b/src/common/vpGroupby.js
@@ -102,6 +102,7 @@ define([
]
this.methodList = [
+ { label: 'None', value: '' },
{ label: 'count', value: 'count' },
{ label: 'first', value: 'first' },
{ label: 'last', value: 'last' },
@@ -134,13 +135,14 @@ define([
_loadState(state) {
var {
variable, groupby, useGrouper, grouperNumber, grouperPeriod,
- display, method, advanced, allocateTo, resetIndex,
+ display, method, advanced, allocateTo, toFrame, resetIndex,
advPageDom, advColList, advNamingList
} = state;
$(this._wrapSelector('#vp_gbVariable')).val(variable);
$(this._wrapSelector('#vp_gbBy')).val(groupby.map(col=>col.code).join(','));
$(this._wrapSelector('#vp_gbBy')).data('list', groupby);
+ $(this._wrapSelector('#vp_gbResetIndex')).val(resetIndex?'yes':'no');
if (useGrouper) {
$(this._wrapSelector('#vp_gbByGrouper')).removeAttr('disabled');
$(this._wrapSelector('#vp_gbByGrouper')).prop('checked', useGrouper);
@@ -157,7 +159,7 @@ define([
$(this._wrapSelector('#vp_gbAdvanced')).trigger('change');
}
$(this._wrapSelector('#vp_gbAllocateTo')).val(allocateTo);
- $(this._wrapSelector('#vp_gbResetIndex')).val(resetIndex?'yes':'no');
+ $(this._wrapSelector('#vp_gbToFrame')).val(toFrame);
$(this._wrapSelector('.vp-gb-adv-box')).html(advPageDom);
@@ -358,6 +360,7 @@ define([
page.appendLine('
');
page.appendFormatLine('', 'vp_gbAllocateTo', 'wp80', 'Allocate to');
page.appendFormatLine('', 'vp_gbAllocateTo', 'New variable name');
+ page.appendFormatLine('', 'vp_gbToFrame', 'To DataFrame');
page.appendLine('
');
page.appendLine(''); // end of df-box
@@ -618,6 +621,7 @@ define([
$(document).off('change', this._wrapSelector('#vp_gbMethodSelect'));
$(document).off('change', this._wrapSelector('#vp_gbAdvanced'));
$(document).off('change', this._wrapSelector('#vp_gbAllocateTo'));
+ $(document).off('change', this._wrapSelector('#vp_gbToFrame'));
$(document).off('change', this._wrapSelector('#vp_gbResetIndex'));
$(document).off('click', this._wrapSelector('#vp_gbAdvAdd'));
@@ -716,6 +720,12 @@ define([
$(document).on('change', this._wrapSelector('#vp_gbDisplay'), function(event) {
var colList = event.dataList;
that.state.display = colList;
+
+ if (colList && colList.length == 1) {
+ $(that._wrapSelector('#vp_gbToFrame')).parent().show();
+ } else {
+ $(that._wrapSelector('#vp_gbToFrame')).parent().hide();
+ }
});
// display select button event
@@ -756,6 +766,11 @@ define([
$(document).on('change', this._wrapSelector('#vp_gbAllocateTo'), function() {
that.state.allocateTo = $(this).val();
});
+
+ // to dataframe event
+ $(document).on('change', this._wrapSelector('#vp_gbToFrame'), function() {
+ that.state.toFrame = $(this).prop('checked') == true;
+ });
// reset index checkbox event
$(document).on('change', this._wrapSelector('#vp_gbResetIndex'), function() {
@@ -1009,9 +1024,13 @@ define([
var code = new sb.StringBuilder();
var {
variable, groupby, useGrouper, grouperNumber, grouperPeriod,
- display, method, advanced, allocateTo, resetIndex
+ display, method, advanced, allocateTo, toFrame, resetIndex
} = this.state;
+ if (!variable || variable == '') {
+ return '';
+ }
+
// mapping colList states
groupby = groupby.map(col => col.code);
display = display.map(col => col.code);
@@ -1048,13 +1067,13 @@ define([
//====================================================================
var colStr = '';
if (display) {
- if (display.length == 1) {
- // for 1 column
- colStr = '[' + display.join('') + ']';
- } else if (display.length > 1) {
+ if (toFrame || display.length > 1) {
// over 2 columns
colStr = '[[' + display.join(',') + ']]';
- }
+ } else if (display.length == 1) {
+ // for 1 column
+ colStr = '[' + display.join('') + ']';
+ }
}
//====================================================================
@@ -1172,21 +1191,24 @@ define([
//================================================================
// Method code generation
//================================================================
- methodStr.appendFormat('{0}()', method);
+ if (method != '') {
+ methodStr.appendFormat('{0}()', method);
+ }
}
- // when using as_index option with Grouper, use .reset_index()
- if (useGrouper && resetIndex) {
- methodStr.append('.reset_index()');
+ if (method != '') {
+ // when using as_index option with Grouper, use .reset_index()
+ if (useGrouper && resetIndex) {
+ methodStr.append('.reset_index()');
+ }
+ // display columns
+ code.appendFormat('{0}.{1}', colStr, methodStr.toString());
}
- // display columns
- code.appendFormat('{0}.{1}', colStr, methodStr.toString());
-
+
if (allocateTo && allocateTo != '') {
code.appendLine();
code.append(allocateTo);
}
-
return code.toString();
}
diff --git a/src/common/vpSubsetEditor.js b/src/common/vpSubsetEditor.js
index 498cfbe0..4d977c06 100644
--- a/src/common/vpSubsetEditor.js
+++ b/src/common/vpSubsetEditor.js
@@ -72,8 +72,10 @@ define([
const VP_DS_DRAGGABLE = 'vp-ds-draggable';
/** select btns */
+ const VP_DS_SELECT_ADD_ALL_BTN = 'vp-ds-select-add-all-btn';
const VP_DS_SELECT_ADD_BTN = 'vp-ds-select-add-btn';
const VP_DS_SELECT_DEL_BTN = 'vp-ds-select-del-btn';
+ const VP_DS_SELECT_DEL_ALL_BTN = 'vp-ds-select-del-all-btn';
/** slicing box */
const VP_DS_SLICING_BOX = 'vp-ds-slicing-box';
@@ -509,8 +511,12 @@ define([
tag.appendLine(''); // VP_DS_SELECT_LEFT
// row select - buttons
tag.appendFormatLine('', VP_DS_SELECT_BTN_BOX);
+ tag.appendFormatLine('
'
+ , VP_DS_SELECT_ADD_ALL_BTN, 'select-row', 'Add all items', '

');
tag.appendFormatLine('
', VP_DS_SELECT_ADD_BTN, 'select-row', '

');
tag.appendFormatLine('
', VP_DS_SELECT_DEL_BTN, 'select-row', '

');
+ tag.appendFormatLine('
'
+ , VP_DS_SELECT_DEL_ALL_BTN, 'select-row', 'Remove all items', '

');
tag.appendLine('
'); // VP_DS_SELECT_BTNS
// row select - right
tag.appendFormatLine('', VP_DS_SELECT_RIGHT);
@@ -612,8 +618,12 @@ define([
tag.appendLine('
'); // VP_DS_SELECT_LEFT
// col select - buttons
tag.appendFormatLine('', VP_DS_SELECT_BTN_BOX);
+ tag.appendFormatLine('
'
+ , VP_DS_SELECT_ADD_ALL_BTN, 'select-col', 'Add all items', '

');
tag.appendFormatLine('
', VP_DS_SELECT_ADD_BTN, 'select-col', '

');
tag.appendFormatLine('
', VP_DS_SELECT_DEL_BTN, 'select-col', '

');
+ tag.appendFormatLine('
'
+ , VP_DS_SELECT_DEL_ALL_BTN, 'select-col', 'Remove all items', '

');
tag.appendLine('
'); // VP_DS_SELECT_BTNS
// col select - right
tag.appendFormatLine('', VP_DS_SELECT_RIGHT);
@@ -1320,8 +1330,10 @@ define([
$(document).off('change', this.wrapSelector('.select-row .' + VP_DS_SELECT_SEARCH));
$(document).off('change', this.wrapSelector('.select-col .' + VP_DS_SELECT_SEARCH));
$(document).off('click', this.wrapSelector('.' + VP_DS_SELECT_ITEM));
+ $(document).off('click', this.wrapSelector('.' + VP_DS_SELECT_ADD_ALL_BTN));
$(document).off('click', this.wrapSelector('.' + VP_DS_SELECT_ADD_BTN));
$(document).off('click', this.wrapSelector('.' + VP_DS_SELECT_DEL_BTN));
+ $(document).off('click', this.wrapSelector('.' + VP_DS_SELECT_DEL_ALL_BTN));
$(document).off('click', this.wrapSelector('.vp-add-col'));
$(document).off('click', this.wrapSelector('.vp-del-col'));
$(document).off('change', this.wrapSelector('.vp-ds-slicing-box input[type="text"]'));
@@ -1653,6 +1665,21 @@ define([
}
});
+ // item indexing - add all
+ $(document).on('click', this.wrapSelector('.' + VP_DS_SELECT_ADD_ALL_BTN), function(event) {
+ var itemType = $(this).hasClass('select-row')? 'row':'col';
+ var selector = '.select-' + itemType;
+
+ $(that.wrapSelector('.' + VP_DS_SELECT_BOX + '.left .' + VP_DS_SELECT_ITEM + selector)).appendTo(
+ $(that.wrapSelector(selector + ' .' + VP_DS_SELECT_BOX + '.right'))
+ );
+ $(that.wrapSelector(selector + ' .' + VP_DS_SELECT_BOX + ' .' + VP_DS_SELECT_ITEM)).addClass('added');
+ $(that.wrapSelector('.' + VP_DS_SELECT_ITEM + '.selected')).removeClass('selected');
+ that.state[itemType + 'Pointer'] = { start: -1, end: -1 };
+
+ that.generateCode();
+ });
+
// item indexing - add
$(document).on('click', this.wrapSelector('.' + VP_DS_SELECT_ADD_BTN), function(event) {
var itemType = $(this).hasClass('select-row')? 'row':'col';
@@ -1691,6 +1718,28 @@ define([
that.generateCode();
});
+ // item indexing - del all
+ $(document).on('click', this.wrapSelector('.' + VP_DS_SELECT_DEL_ALL_BTN), function(event) {
+ var itemType = $(this).hasClass('select-row')? 'row':'col';
+ var selector = '.select-' + itemType;
+
+ var targetBoxQuery = that.wrapSelector(selector + ' .' + VP_DS_SELECT_BOX + '.left');
+ $(that.wrapSelector(selector + ' .' + VP_DS_SELECT_ITEM)).appendTo(
+ $(targetBoxQuery)
+ );
+ // sort
+ $(targetBoxQuery + ' .' + VP_DS_SELECT_ITEM).sort(function(a, b) {
+ return ($(b).data('idx')) < ($(a).data('idx')) ? 1 : -1;
+ }).appendTo(
+ $(targetBoxQuery)
+ );
+ $(that.wrapSelector(selector + ' .' + VP_DS_SELECT_ITEM)).removeClass('added');
+ $(that.wrapSelector(selector + ' .' + VP_DS_SELECT_ITEM)).removeClass('selected');
+ that.state[itemType + 'Pointer'] = { start: -1, end: -1 };
+
+ that.generateCode();
+ });
+
// row-column condition add
$(document).on('click', this.wrapSelector('.vp-add-col'), function(event) {
that.handleColumnAdd();
@@ -2122,7 +2171,7 @@ define([
var rowList = [];
for (var i = 0; i < rowTags.length; i++) {
var rowValue = $(rowTags[i]).data('code');
- if (rowValue) {
+ if (rowValue != undefined) {
rowList.push(rowValue);
}
}
diff --git a/src/markdown/markdown.js b/src/markdown/markdown.js
index c23f6d48..e88b0cca 100644
--- a/src/markdown/markdown.js
+++ b/src/markdown/markdown.js
@@ -403,7 +403,7 @@ define([
MathJax.Hub.Queue(["Typeset", MathJax.Hub, that.wrapSelector(vpCommon.formatString("{0}{1}", vpConst.VP_ID_PREFIX, "markdownPreview"))]);
- // 변환안 된 이미지 있으면 경로로 설정하기 FIXME:
+ // // 변환안 된 이미지 있으면 경로로 설정하기 FIXME:
html = html.replaceAll('vpImportImage:', '');
textBlock.writeCode(html);
@@ -431,7 +431,8 @@ define([
.then(data => {
var imgResult = data["image/png"];
- textarea.value = vpCommon.formatString("{0}{4}", preText, file, vpConst.VP_MARKDOWN_TOOLBAR_IMAGE_INDICATOR, file, postText);
+ // textarea.value = vpCommon.formatString("{0}{4}", preText, file, vpConst.VP_MARKDOWN_TOOLBAR_IMAGE_INDICATOR, file, postText);
+ textarea.value = vpCommon.formatString("{0}{3}", preText, file, file, postText);
// 파일 ATTACH ID 생성
var pathSplit = file.split('.').join('/').split('/');