Skip to content

Commit 64ba621

Browse files
author
minjk-bl
committed
Chart - add import option box
1 parent 450d305 commit 64ba621

File tree

4 files changed

+220
-24
lines changed

4 files changed

+220
-24
lines changed

css/component/common.css

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@
6666
border-right: 1px solid var(--font-primary);
6767
}
6868

69+
/* Scrollbar */
70+
.vp-scrollbar {
71+
overflow-y: auto;
72+
--webkit-mask-position: left top;
73+
}
74+
.vp-scrollbar::-webkit-scrollbar {
75+
width: 5px;
76+
height: 5px;
77+
}
78+
.vp-scrollbar::-webkit-scrollbar-thumb {
79+
border: 0.3px solid #C4C4C4;
80+
background: #C4C4C4;
81+
}
82+
6983
/* Width selector */
7084
.wp50 {
7185
width: 50px;
@@ -80,6 +94,13 @@
8094
width: 120px;
8195
}
8296

97+
.w40 {
98+
width: 40%;
99+
}
100+
.w100 {
101+
width: 100%;
102+
}
103+
83104
/* font selector */
84105
.fb {
85106
font-weight: bold;

css/matplotlib/plot.css

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,37 @@
33
--bgcolor: #696969;
44
}
55

6+
/* Import Options box*/
7+
.vp-import-box {
8+
display: grid;
9+
grid-template-rows: 30px;
10+
grid-row-gap: 5px;
11+
border: 1px solid var(--border-gray-color);
12+
padding: 10px 0px;
13+
}
14+
.vp-import-box label {
15+
min-width: 130px;
16+
max-width: 300px;
17+
vertical-align: middle;
18+
text-align: left;
19+
font-weight: bold;
20+
height: 30px;
21+
padding: 2px 5px 2px 16px;
22+
}
23+
.vp-import-box input[type="text"] {
24+
width: 160px;
25+
}
26+
.vp-import-box input[type="number"] {
27+
width: 79px;
28+
}
29+
.vp-pl-import-run {
30+
float: right;
31+
margin-right: 10px;
32+
}
33+
634
.vp-icon-btn.vp-close-view {
735
position: absolute;
8-
right: 10px;
36+
right: 20px;
937
cursor: pointer;
1038
}
1139
.vp-option-title {
@@ -268,18 +296,19 @@
268296
.vp-method-select {
269297
border: 0.25px solid #C4C4C4;
270298
overflow-y: auto;
271-
width: 125px;
299+
width: 250px;
272300
height: 100px;
273301
}
274302
.vp-column-select-item,
275303
.vp-method-select-item {
276-
padding-left: 3px;
277304
cursor: pointer;
305+
padding: 3px;
306+
border-bottom: 0.25px solid var(--border-gray-color);
278307
}
279308
.vp-column-select-item.selected,
280309
.vp-method-select-item.selected {
281310
color: var(--font-hightlight);
282-
background: #C4C4C4;
311+
background: var(--light-gray-color);
283312
}
284313

285314
/* Select Data Button */

src/matplotlib/plot.html

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@
1616
<hr style="margin: 0px;"/>
1717
<div id="vp_varViewDetail">
1818
<table class="vp-option-table vp-var-view-detail no-selection">
19-
<colgroup><col width="40%"/><col width="*"/></colgroup>
19+
<colgroup>
20+
<!-- <col width="40%"/> -->
21+
<col width="*"/>
22+
</colgroup>
2023
<thead>
2124
<tr>
2225
<th>Column</th>
23-
<th>Method</th>
26+
<!-- <th>Method</th> -->
2427
</tr>
2528
</thead>
2629
<tbody>
@@ -30,12 +33,11 @@
3033

3134
</div>
3235
</td>
33-
<td>
36+
<!-- <td>
3437
<div id="vp_varDetailArray" class="vp-method-select">
35-
<!-- detail array -->
3638
3739
</div>
38-
</td>
40+
</td> -->
3941
</tr>
4042
</tbody>
4143
</table>

src/matplotlib/plot.js

Lines changed: 159 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ define([
77
, 'nbextensions/visualpython/src/common/vpFuncJS'
88
, 'nbextensions/visualpython/src/container/vpContainer'
99
, 'nbextensions/visualpython/src/pandas/common/pandasGenerator'
10+
, 'nbextensions/visualpython/src/common/component/vpSuggestInputText'
1011
, 'nbextensions/visualpython/src/pandas/fileNavigation/index'
11-
], function (requirejs, $, vpCommon, vpConst, sb, vpFuncJS, vpContainer, pdGen, fileNavigation) {
12+
], function (requirejs, $, vpCommon, vpConst, sb, vpFuncJS, vpContainer, pdGen, vpSuggestInputText, fileNavigation) {
1213
// 옵션 속성
1314
const funcOptProp = {
1415
stepCount : 1
@@ -124,13 +125,54 @@ define([
124125
var sbPageContent = new sb.StringBuilder();
125126
var sbTagString = new sb.StringBuilder();
126127

128+
// Box 1. Import
129+
var accBoxImport = this.createOptionContainer('Import Options');
130+
accBoxImport.setOpenBox(true);
131+
sbTagString.clear();
132+
sbTagString.appendFormatLine('<div class="{0}">', 'vp-import-box');
133+
// import
134+
sbTagString.appendLine('<div>');
135+
sbTagString.appendFormatLine('<label for="{0}" class="{1}">{2}</label>', 'vp_plImport', '', 'Matplot.pyplot as');
136+
sbTagString.appendFormatLine('<input type="text" id="{0}" placeholder="{1}" value="{2}" disabled>', 'vp_plImport', 'alias', 'plt');
137+
sbTagString.appendLine('</div>');
138+
// figure size
139+
sbTagString.appendLine('<div>');
140+
sbTagString.appendFormatLine('<label for="{0}" class="{1}">{2}</label>', 'vp_plFigureWidth', '', 'Figure size');
141+
sbTagString.appendFormatLine('<input type="number" id="{0}" placeholder="{1}" value="{2}">', 'vp_plFigureWidth', 'width', 12);
142+
sbTagString.appendFormatLine('<input type="number" id="{0}" placeholder="{1}" value="{2}">', 'vp_plFigureHeight', 'height', 8);
143+
sbTagString.appendLine('</div>');
144+
// style sheet
145+
sbTagString.appendLine('<div>');
146+
sbTagString.appendFormatLine('<label for="{0}" class="{1}">{2}</label>', 'vp_plStyle', '', 'Style sheet');
147+
sbTagString.appendFormatLine('<input type="text" id="{0}" placeholder="{1}">', 'vp_plStyle', 'style name');
148+
sbTagString.appendLine('</div>');
149+
// divider
150+
sbTagString.appendLine('<hr style="margin: 5px 0;"/>');
151+
// system font
152+
sbTagString.appendLine('<div>');
153+
sbTagString.appendFormatLine('<label for="{0}" class="{1}">{2}</label>', 'vp_plFontName', '', 'System font');
154+
sbTagString.appendFormatLine('<input type="text" id="{0}" placeholder="{1}">', 'vp_plFontName', 'font name');
155+
sbTagString.appendLine('</div>');
156+
// font size
157+
sbTagString.appendLine('<div>');
158+
sbTagString.appendFormatLine('<label for="{0}" class="{1}">{2}</label>', 'vp_plFontSize', '', 'Font size');
159+
sbTagString.appendFormatLine('<input type="number" id="{0}" placeholder="{1}" value="{2}">', 'vp_plFontSize', 'size', 10);
160+
sbTagString.appendLine('</div>');
161+
// import button
162+
sbTagString.appendLine('<div>');
163+
sbTagString.appendFormatLine('<input type="button" id="{0}" class="{1}" value="{2}">', 'vp_plImportRun', 'vp-button activated vp-pl-import-run', 'Import');
164+
sbTagString.appendLine('</div>');
165+
166+
sbTagString.appendLine('</div>');
167+
accBoxImport.appendContent(sbTagString.toString());
168+
sbPageContent.appendLine(accBoxImport.toTagString());
127169

128170
// Popup Box. variable view box
129171
sbTagString.clear();
130172
sbTagString.appendLine('<div id="vp_varViewBox" class="vp-var-view-box">');
131173
sbTagString.appendLine('<div class="vp-icon-btn vp-close-view"><img src="/nbextensions/visualpython/resource/close_big.svg"/></div>');
132174
// variable list
133-
sbTagString.appendLine('<div class="vp-var-view-div">');
175+
sbTagString.appendLine('<div class="vp-var-view-div vp-scrollbar">');
134176
sbTagString.appendLine('<table id="vp_varViewList" class="vp-option-table vp-var-view-list no-selection">');
135177
sbTagString.appendLine('<colgroup><col width="40%"/><col width="*"/></colgroup>');
136178
sbTagString.appendLine('<thead>');
@@ -145,28 +187,27 @@ define([
145187
// detail
146188
sbTagString.appendLine('<div id="vp_varViewDetail">');
147189
sbTagString.appendLine('<table class="vp-option-table vp-var-view-detail no-selection">');
148-
sbTagString.appendLine('<colgroup><col width="40%"/><col width="*"/></colgroup>');
149-
sbTagString.appendLine('<thead><tr><th>Column</th><th>Method</th></tr></thead>');
150-
sbTagString.appendLine('<tbody>');
151-
sbTagString.appendLine('<tr><td><div id="vp_varDetailColList" class="vp-column-select"></div></td>');
152-
sbTagString.appendLine('<td><div id="vp_varDetailArray" class="vp-method-select"></div></td></tr>');
153-
sbTagString.appendLine('</tbody>');
190+
sbTagString.appendLine('<colgroup><col width="*"/></colgroup>');
191+
sbTagString.appendLine('<thead><tr><th>Column</th></tr></thead>');
192+
sbTagString.appendLine('<tbody><tr>');
193+
sbTagString.appendLine('<td><div id="vp_varDetailColList" class="vp-column-select vp-scrollbar"></div></td>');
194+
// sbTagString.appendLine('<td><div id="vp_varDetailArray" class="vp-method-select"></div></td>');
195+
sbTagString.appendLine('</tr></tbody>');
154196
sbTagString.appendLine('</table>');
155197
sbTagString.appendLine('</div>');
156198
// footer
157199
sbTagString.appendLine('<div class="var-view-footer">');
158200
sbTagString.appendLine('<input id="vp_varSelectCode" type="text" class="vp-input" readonly/>');
159-
sbTagString.appendLine('<input id="vp_varSelectBtn" type="button" value="select"/>');
201+
sbTagString.appendLine('<input id="vp_varSelectBtn" type="button" class="vp-button activated wp50" value="Select"/>');
160202
sbTagString.appendLine('</div>');
161203
sbTagString.appendLine('</div>');
162204
sbPageContent.appendLine(sbTagString.toString());
163205

164-
// Box 1. Required Input & Output
206+
// Box 2. Required Input & Output
165207
var accBoxRequire = this.createOptionContainer(vpConst.API_REQUIRE_OPTION_BOX_CAPTION);
166208
accBoxRequire.setOpenBox(true);
167209

168210
sbTagString.clear();
169-
// 대상변수 자동입력 칸 //FIXME:
170211
sbTagString.appendLine('<input type="hidden" class="vp-input input-single" id="i0" value="plt"/>');
171212

172213
sbTagString.appendFormatLine('<div class="{0} {1}">{2}</div>', 'vp-thead', vpConst.COLOR_FONT_ORANGE, 'Chart Type');
@@ -265,11 +306,11 @@ define([
265306
, 'vp_userOption', 'key=value, key=value ...');
266307
tblLayoutRequire.addRow('User Option', sbTagString.toString());
267308

268-
// 박스에 추가
309+
// add to box
269310
accBoxRequire.appendContent(tblLayoutRequire.toTagString());
270311
sbPageContent.appendLine(accBoxRequire.toTagString());
271312

272-
// Box 2. Additional Options
313+
// Box 3. Additional Options
273314
var tblAdditional = this.createVERSimpleLayout("15%");
274315
var accBoxAdditional = this.createOptionContainer('Additional Options');
275316
accBoxAdditional.setOpenBox(true);
@@ -322,7 +363,7 @@ define([
322363
sbTagString.appendFormatLine('<div id="{0}" class="{1}"></div>', 'vp_openFileNavigationBtn', 'vp-file-browser-button');
323364
tblAdditional.addRow('Save Figure', sbTagString.toString());
324365

325-
// 박스에 추가
366+
// add to box
326367
accBoxAdditional.appendContent(tblAdditional.toTagString());
327368
sbPageContent.appendLine(accBoxAdditional.toTagString());
328369

@@ -331,7 +372,8 @@ define([
331372
this.setPage(sbPageContent.toString());
332373

333374

334-
// 차트 서브플롯 페이지 구성
375+
// Chart subplot option
376+
this.bindImportOptions();
335377
this.bindSubplotOption1();
336378
this.bindCmapSelector();
337379

@@ -364,6 +406,76 @@ define([
364406
$(this.wrapSelector('.vp_functionName')).text(funcOptProp.funcName);
365407
}
366408

409+
/**
410+
* Bind Import options event
411+
*/
412+
MatplotPackage.prototype.bindImportOptions = function() {
413+
var that = this;
414+
415+
//====================================================================
416+
// Stylesheet suggestinput
417+
//====================================================================
418+
var stylesheetTag = $(this.wrapSelector('#vp_plStyle'));
419+
// search available stylesheet list
420+
var code = new sb.StringBuilder();
421+
// FIXME: convert it to kernelApi
422+
code.appendLine('import matplotlib.pyplot as plt');
423+
code.appendLine('import json');
424+
code.append(`print(json.dumps([{ 'label': s, 'value': s } for s in plt.style.available]))`);
425+
this.kernelExecute(code.toString(), function(result) {
426+
// get available stylesheet list
427+
var varList = JSON.parse(result);
428+
var suggestInput = new vpSuggestInputText.vpSuggestInputText();
429+
suggestInput.setComponentID('vp_plStyle');
430+
suggestInput.setSuggestList(function() { return varList; });
431+
suggestInput.setPlaceholder('style name');
432+
// suggestInput.setNormalFilter(false);
433+
$(stylesheetTag).replaceWith(function() {
434+
return suggestInput.toTagString();
435+
});
436+
});
437+
438+
//====================================================================
439+
// System font suggestinput
440+
//====================================================================
441+
var fontFamilyTag = $(this.wrapSelector('#vp_plFontName'));
442+
// search system font list
443+
var code = new sb.StringBuilder();
444+
// FIXME: convert it to kernelApi
445+
code.appendLine('import json');
446+
code.appendLine("import matplotlib.font_manager as fm");
447+
code.appendLine("_ttflist = fm.fontManager.ttflist");
448+
code.append("print(json.dumps([{'label': f.name, 'value': f.name } for f in _ttflist]))");
449+
this.kernelExecute(code.toString(), function(result) {
450+
// get available font list
451+
var varList = JSON.parse(result);
452+
var suggestInput = new vpSuggestInputText.vpSuggestInputText();
453+
suggestInput.setComponentID('vp_plFontName');
454+
suggestInput.setSuggestList(function() { return varList; });
455+
suggestInput.setPlaceholder('font name');
456+
// suggestInput.setNormalFilter(false);
457+
$(fontFamilyTag).replaceWith(function() {
458+
return suggestInput.toTagString();
459+
});
460+
});
461+
462+
//====================================================================
463+
// Events
464+
//====================================================================
465+
$(this.wrapSelector('#vp_plImportRun')).click(function() {
466+
// generateImportCode
467+
var code = that.generateImportCode();
468+
// run cell
469+
$(vpCommon.wrapSelector('#vp_appsCode')).trigger({
470+
type: 'popup_run',
471+
title: 'Snippets',
472+
code: code,
473+
addCell: true,
474+
runCell: true
475+
});
476+
});
477+
}
478+
367479
/**
368480
* 서브플롯 옵션 페이지 구성
369481
*/
@@ -978,6 +1090,38 @@ define([
9781090
return code;
9791091
}
9801092

1093+
/**
1094+
* Generate Import options code
1095+
* @returns code
1096+
*/
1097+
MatplotPackage.prototype.generateImportCode = function() {
1098+
var code = new sb.StringBuilder();
1099+
1100+
// get parameters
1101+
var alias = $(this.wrapSelector('#vp_plImport')).val();
1102+
var figWidth = $(this.wrapSelector('#vp_plFigureWidth')).val();
1103+
var figHeight = $(this.wrapSelector('#vp_plFigureHeight')).val();
1104+
var styleName = $(this.wrapSelector('#vp_plStyle')).val();
1105+
var fontName = $(this.wrapSelector('#vp_plFontName')).val();
1106+
var fontSize = $(this.wrapSelector('#vp_plFontSize')).val();
1107+
1108+
code.appendLine('import matplotlib.pyplot as plt');
1109+
code.appendFormatLine("plt.rc('figure', figsize=({0}, {1}))", figWidth, figHeight);
1110+
if (styleName && styleName.length > 0) {
1111+
code.appendFormatLine("plt.style.use('{0}')", styleName);
1112+
}
1113+
code.appendLine();
1114+
1115+
code.appendLine('from matplotlib import rcParams');
1116+
if (fontName && fontName.length > 0) {
1117+
code.appendFormatLine("rcParams['font.family'] = '{0}'", fontName);
1118+
}
1119+
code.appendFormatLine("rcParams['font.size'] = {0}", fontSize);
1120+
code.append("rcParams['axes.unicode_minus'] = False");
1121+
1122+
return code.toString();
1123+
}
1124+
9811125
/**
9821126
* 코드 생성
9831127
* @param {boolean} exec 실행여부

0 commit comments

Comments
 (0)