From 45880ca9ee55c39b689341f5d89210df5ec8f3b5 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 8 Mar 2019 16:00:33 -0700 Subject: [PATCH 1/4] ENH: export plot to vega editor --- emperor/support_files/js/controller.js | 69 +++++++++- emperor/support_files/js/model.js | 28 ++++ emperor/support_files/js/sceneplotview3d.js | 14 +- emperor/support_files/js/shape-controller.js | 1 + emperor/support_files/js/view.js | 132 +++++++++++++++++++ 5 files changed, 230 insertions(+), 14 deletions(-) diff --git a/emperor/support_files/js/controller.js b/emperor/support_files/js/controller.js index 53416eda..9a154429 100644 --- a/emperor/support_files/js/controller.js +++ b/emperor/support_files/js/controller.js @@ -661,7 +661,24 @@ define([ disabled: isLargeDataset } } - } + }, + 'openInVegaEditor': { + name: 'Open in Vega Editor', + icon: 'file-picture-o', + callback: function(key, opts) { + scope.exportToVega(); + }, + disabled: function(key, opt) { + // Only enable if this is a "vanilla" plot + if (scope.decViews.scatter.lines.left === null && + scope.decViews.scatter.lines.right === null && + scope.decViews.biplot === undefined) { + return false; + } + return true; + }, + }, + } }); @@ -931,5 +948,55 @@ define([ return obj; }; + /** + * + * Helper that posts messages between browser tabs + * + * @private + * + */ + _postMessage = function(url, payload) { + // Shamelessly pulled from https://github.com/vega/vega-embed/ + var editor = window.open(url); + var wait = 10000; + var step = 250; + var count = ~~(wait / step); + + function listen(e) { + if (e.source === editor) { + count = 0; + window.removeEventListener('message', listen, false); + } + } + + window.addEventListener('message', listen, false); + + function send() { + if (count <= 0) { + return; + } + editor.postMessage(payload, '*'); + setTimeout(send, step); + count -= 1; + } + setTimeout(send, step); + } + + /** + * + * Open in Vega editor + * + */ + EmperorController.prototype.exportToVega = function() { + var url = 'https://vega.github.io/editor/'; + var spec = this.decViews.scatter._buildVegaSpec(); + var payload = { + mode: 'vega', + renderer: 'canvas', + spec: JSON.stringify(spec), + }; + _postMessage(url, payload); + }; + return EmperorController; }); diff --git a/emperor/support_files/js/model.js b/emperor/support_files/js/model.js index ca444c0d..172dadea 100644 --- a/emperor/support_files/js/model.js +++ b/emperor/support_files/js/model.js @@ -514,6 +514,34 @@ function($, _, util) { this.axesNames = names.nonNumeric.concat(replacement); } } + this._buildAxesLabels(); + }; + + /** + * + * Helper method to build labels for all axes + * + */ + DecompositionModel.prototype._buildAxesLabels = function() { + var axesLabels = [], index, text; + for (index = 0; index < this.axesNames.length; index++) { + // when the labels get too long, it's a bit hard to look at + if (this.axesNames[index].length > 25) { + text = this.axesNames[index].slice(0, 20) + '...'; + } + else { + text = this.axesNames[index]; + } + + // account for custom axes (their percentage explained will be -1 to + // indicate that this attribute is not meaningful). + if (this.percExpl[index] >= 0) { + text += ' (' + this.percExpl[index].toPrecision(4) + ' %)'; + } + + axesLabels.push(text); + } + this.axesLabels = axesLabels; }; /** diff --git a/emperor/support_files/js/sceneplotview3d.js b/emperor/support_files/js/sceneplotview3d.js index 6856a2b3..a77d852f 100644 --- a/emperor/support_files/js/sceneplotview3d.js +++ b/emperor/support_files/js/sceneplotview3d.js @@ -525,19 +525,7 @@ define([ decomp = this.decViews[firstKey].decomp; this._dimensionsIterator(function(start, end, index) { - // when the labels get too long, it's a bit hard to look at - if (decomp.axesNames[index].length > 25) { - text = decomp.axesNames[index].slice(0, 20) + '...'; - } - else { - text = decomp.axesNames[index]; - } - - // account for custom axes (their percentage explained will be -1 to - // indicate that this attribute is not meaningful). - if (decomp.percExpl[index] >= 0) { - text += ' (' + decomp.percExpl[index].toPrecision(4) + ' %)'; - } + text = decomp.axesLabels[index]; axisLabel = makeLabel(end, text, color); axisLabel.scale.set(axisLabel.scale.x * scaling, diff --git a/emperor/support_files/js/shape-controller.js b/emperor/support_files/js/shape-controller.js index 329b7a41..aaaecacb 100644 --- a/emperor/support_files/js/shape-controller.js +++ b/emperor/support_files/js/shape-controller.js @@ -127,6 +127,7 @@ define([ _.each(group, function(element) { idx = element.idx; scope.markers[idx].geometry = geometry; + scope.markers[idx].userData.shape = shape; }); scope.needsUpdate = true; }; diff --git a/emperor/support_files/js/view.js b/emperor/support_files/js/view.js index 34b11c21..2484063c 100644 --- a/emperor/support_files/js/view.js +++ b/emperor/support_files/js/view.js @@ -151,6 +151,8 @@ DecompositionView.prototype._initBaseView = function() { mesh.position.set(plottable.coordinates[x], plottable.coordinates[y], plottable.coordinates[z] || 0); + mesh.userData.shape = 'Sphere' + scope.markers.push(mesh); if (hasConfidenceIntervals) { @@ -828,6 +830,136 @@ DecompositionView.prototype.toggleLabelVisibility = function() { this.needsUpdate = true; }; +/** + * + * Helper that builds a vega specification off of the current view state + * + * @private + */ +DecompositionView.prototype._buildVegaSpec = function() { + function rgbColor(colorObj) { + var r = colorObj.r * 255; + var g = colorObj.g * 255; + var b = colorObj.b * 255; + return 'rgb(' + r + ',' + g + ',' + b + ')'; + } + + // Maps THREE.js geometries to vega shapes + var getShape = { + Sphere: 'circle', + Diamond: 'diamond', + Cone: 'triangle-down', + Cylinder: 'square', + Ring: 'circle', + Square: 'square', + Icosahedron: 'cross', + Star: 'cross', + }; + + function viewMarkersAsVegaDataset(markers) { + var points = [], marker, i; + for (i = 0; i < markers.length; i++) { + marker = markers[i]; + if (marker.visible) { + points.push({ + id: marker.name, + x: marker.position.x, + y: marker.position.y, + color: rgbColor(marker.material.color), + originalShape: marker.userData.shape, + shape: getShape[marker.userData.shape], + scale: { x: marker.scale.x, y: marker.scale.y, }, + opacity: marker.material.opacity, + }); + } + } + return points; + }; + + // This is probably horribly slow on QIITA-scale MD files, probably needs some attention + function plottablesAsMetadata(points, header) { + var md = [], point, row, i, j; + for (i = 0; i < points.length; i++) { + point = points[i]; + row = {}; + for (j = 0; j < header.length; j++) { + row[header[j]] = point.metadata[j]; + } + md.push(row); + } + return md; + } + + var scope = this; + var model = scope.decomp; + + var axisX = scope.visibleDimensions[0]; + var axisY = scope.visibleDimensions[1]; + + var dimRanges = model.dimensionRanges; + var rangeX = [dimRanges.min[axisX], dimRanges.max[axisX]]; + var rangeY = [dimRanges.min[axisY], dimRanges.max[axisY]]; + + var baseWidth = 800; + + return { + '$schema': 'https://vega.github.io/schema/vega/v5.json', + padding: 5, + background: scope.backgroundColor, + config: { + axis: { labelColor: scope.axesColor, titleColor: scope.axesColor, }, + title: { color: scope.axesColor, }, + }, + title: 'Emperor PCoA', + data: [ + { name: 'metadata', values: plottablesAsMetadata(model.plottable, model.md_headers), }, + { + name: 'points', values: viewMarkersAsVegaDataset(scope.markers), + transform: [ + { + type: 'lookup', + from: 'metadata', + key: model.md_headers[0], + fields: ['id'], + as: ['metadata'], + } + ], + }, + ], + signals: [ + {name: 'width', update: baseWidth + ' * ((' + rangeX[1] + ') - (' + rangeX[0] + '))'}, + {name: 'height', update: baseWidth + ' * ((' + rangeY[1] + ') - (' + rangeY[0] + '))'} + ], + scales: [ + { name: 'xScale', range: 'width', domain: [rangeX[0], rangeX[1]] }, + { name: 'yScale', range: 'height', domain: [rangeY[0], rangeY[1]] } + ], + axes: [ + { orient: 'bottom', scale: 'xScale', title: model.axesLabels[axisX], }, + { orient: 'left', scale: 'yScale', title: model.axesLabels[axisY], } + ], + marks: [ + { + type: 'symbol', + from: {data: 'points'}, + encode: { + enter: { + fill: { field: 'color', }, + x: { scale: 'xScale', field: 'x', }, + y: { scale: 'yScale', field: 'y', }, + shape: { field: 'shape', }, + size: { signal: 'datum.scale.x * datum.scale.y * 100', }, + opacity: { field: 'opacity', }, + }, + update: { + tooltip: { signal: 'datum.metadata' }, + }, + }, + }, + ], + }; +} + /** * Helper function to change the opacity of an arrow object. * From b631d078b56bf6320399d547397e0d184feda11a Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 17 Apr 2019 17:30:57 -0700 Subject: [PATCH 2/4] SQUASH --- emperor/core.py | 7 ++- emperor/support_files/js/controller.js | 46 ++++++++++++------- .../templates/logic-template.html | 2 +- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/emperor/core.py b/emperor/core.py index deacb064..ac967e33 100644 --- a/emperor/core.py +++ b/emperor/core.py @@ -230,7 +230,7 @@ class Emperor(object): """ def __init__(self, ordination, mapping_file, feature_mapping_file=None, dimensions=5, remote=True, jackknifed=None, procrustes=None, - ignore_missing_samples=False): + ignore_missing_samples=False, enable_experimental=False): if ordination.samples.shape[1] < 2: raise ValueError('Ordinations with less than two dimensions are' @@ -289,6 +289,8 @@ def __init__(self, ordination, mapping_file, feature_mapping_file=None, self.procrustes_names = ['Ordination %d' % i for i in range(len(self.procrustes) + 1)] + self.experimental = enable_experimental + def __str__(self): return self.make_emperor() @@ -453,7 +455,8 @@ def make_emperor(self, standalone=False): style_template_path=basename(STYLE_PATH), base_url=self.base_url, width=self.width, - height=self.height) + height=self.height, + experimental=self.experimental) return plot diff --git a/emperor/support_files/js/controller.js b/emperor/support_files/js/controller.js index 9a154429..e7ce44ca 100644 --- a/emperor/support_files/js/controller.js +++ b/emperor/support_files/js/controller.js @@ -47,9 +47,15 @@ define([ * @constructs EmperorController * */ - function EmperorController(scatter, biplot, divId, webglcanvas) { + function EmperorController(scatter, biplot, divId, webglcanvas, experimental) { var scope = this; + /** + * Enables experimental features. + * @type {boolean} + */ + this.experimental = experimental; + /** * Scaling constant for grid dimensions (read only). * @type {float} @@ -662,24 +668,32 @@ define([ } } }, - 'openInVegaEditor': { - name: 'Open in Vega Editor', - icon: 'file-picture-o', - callback: function(key, opts) { - scope.exportToVega(); + fold2: { + name: 'EXPERIMENTAL', + visible: function(key, opts) { + return scope.experimental; }, - disabled: function(key, opt) { - // Only enable if this is a "vanilla" plot - if (scope.decViews.scatter.lines.left === null && - scope.decViews.scatter.lines.right === null && - scope.decViews.biplot === undefined) { - return false; - } - return true; + icon: '', + items: { + openInVegaEditor: { + name: 'Open in Vega Editor', + icon: 'file-picture-o', + callback: function(key, opts) { + scope.exportToVega(); + }, + disabled: function(key, opt) { + // Only enable if this is a "vanilla" plot + if (scope.decViews.scatter.lines.left === null && + scope.decViews.scatter.lines.right === null && + scope.decViews.biplot === undefined) { + return false; + } + return true; + }, + }, }, }, - - } + }, }); // The context menu is only shown if there's a single right click. We diff --git a/emperor/support_files/templates/logic-template.html b/emperor/support_files/templates/logic-template.html index e90e66ca..b025ae55 100644 --- a/emperor/support_files/templates/logic-template.html +++ b/emperor/support_files/templates/logic-template.html @@ -124,7 +124,7 @@ data.biplot.type); } - ec = new EmperorController(plot, biplot, {{ plot_id | tojson }}); + ec = new EmperorController(plot, biplot, {{ plot_id | tojson }}, undefined, {{ experimental | tojson }}); } function animate() { From 26cef290e02d33dec943410eb5770651846521bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoshiki=20V=C3=A1zquez=20Baeza?= Date: Thu, 18 Apr 2019 18:29:08 -0700 Subject: [PATCH 3/4] ENH: Experimental features are by default available This allows for a bit more flexibility while we figure out how to handle this new functionality. Also, it won't lead to any test updates that might be a bit too cumbersome. I added custom icons in the context menu for "experimental" and for "biplot labels". --- emperor/core.py | 7 +--- emperor/support_files/js/controller.js | 37 +++++++----------- .../templates/logic-template.html | 2 +- .../vendor/css/font/context-menu-icons.eot | Bin 4608 -> 5056 bytes .../vendor/css/font/context-menu-icons.ttf | Bin 4400 -> 4848 bytes .../vendor/css/font/context-menu-icons.woff | Bin 2876 -> 3188 bytes .../vendor/css/font/context-menu-icons.woff2 | Bin 2312 -> 2604 bytes .../vendor/css/jquery.contextMenu.min.css | 2 +- 8 files changed, 18 insertions(+), 30 deletions(-) diff --git a/emperor/core.py b/emperor/core.py index ac967e33..deacb064 100644 --- a/emperor/core.py +++ b/emperor/core.py @@ -230,7 +230,7 @@ class Emperor(object): """ def __init__(self, ordination, mapping_file, feature_mapping_file=None, dimensions=5, remote=True, jackknifed=None, procrustes=None, - ignore_missing_samples=False, enable_experimental=False): + ignore_missing_samples=False): if ordination.samples.shape[1] < 2: raise ValueError('Ordinations with less than two dimensions are' @@ -289,8 +289,6 @@ def __init__(self, ordination, mapping_file, feature_mapping_file=None, self.procrustes_names = ['Ordination %d' % i for i in range(len(self.procrustes) + 1)] - self.experimental = enable_experimental - def __str__(self): return self.make_emperor() @@ -455,8 +453,7 @@ def make_emperor(self, standalone=False): style_template_path=basename(STYLE_PATH), base_url=self.base_url, width=self.width, - height=self.height, - experimental=self.experimental) + height=self.height) return plot diff --git a/emperor/support_files/js/controller.js b/emperor/support_files/js/controller.js index e7ce44ca..8baf141f 100644 --- a/emperor/support_files/js/controller.js +++ b/emperor/support_files/js/controller.js @@ -47,15 +47,9 @@ define([ * @constructs EmperorController * */ - function EmperorController(scatter, biplot, divId, webglcanvas, experimental) { + function EmperorController(scatter, biplot, divId, webglcanvas) { var scope = this; - /** - * Enables experimental features. - * @type {boolean} - */ - this.experimental = experimental; - /** * Scaling constant for grid dimensions (read only). * @type {float} @@ -598,6 +592,7 @@ define([ 'labels' : { name: 'Toggle label visibility', visible: scope.decViews.biplot !== undefined, + icon: 'font', callback: function() { scope._hideBiplotLabels = Boolean(scope._hideBiplotLabels ^ true); scope.decViews.biplot.toggleLabelVisibility(); @@ -669,29 +664,25 @@ define([ } }, fold2: { - name: 'EXPERIMENTAL', - visible: function(key, opts) { - return scope.experimental; + name: 'Experimental', + disabled: function(key, opt) { + // Only enable if this is a "vanilla" plot + if (scope.decViews.scatter.lines.left === null && + scope.decViews.scatter.lines.right === null && + scope.decViews.biplot === undefined) { + return false; + } + return true; }, - icon: '', + icon: 'warning', items: { openInVegaEditor: { name: 'Open in Vega Editor', - icon: 'file-picture-o', callback: function(key, opts) { scope.exportToVega(); }, - disabled: function(key, opt) { - // Only enable if this is a "vanilla" plot - if (scope.decViews.scatter.lines.left === null && - scope.decViews.scatter.lines.right === null && - scope.decViews.biplot === undefined) { - return false; - } - return true; - }, - }, - }, + } + } }, }, }); diff --git a/emperor/support_files/templates/logic-template.html b/emperor/support_files/templates/logic-template.html index b025ae55..e90e66ca 100644 --- a/emperor/support_files/templates/logic-template.html +++ b/emperor/support_files/templates/logic-template.html @@ -124,7 +124,7 @@ data.biplot.type); } - ec = new EmperorController(plot, biplot, {{ plot_id | tojson }}, undefined, {{ experimental | tojson }}); + ec = new EmperorController(plot, biplot, {{ plot_id | tojson }}); } function animate() { diff --git a/emperor/support_files/vendor/css/font/context-menu-icons.eot b/emperor/support_files/vendor/css/font/context-menu-icons.eot index f423bae44329d0ea8b505c0feea98182af7163a0..68eec98405f3193f8df9863d61985e936f730aa5 100644 GIT binary patch delta 922 zcmXw0TWAzn5UslR_PssbaUPkTp7==O^gN;@F*=DeK0+RD5XGP$iU4)q>@*yk=Bk@PnUy*fD5kXK8e+2O{WA%uaK2^6)ow`MJok^8j zWH}1(p?*r{#N3+~H>UcoPn=7i1i)1Qux-oMj%?rP;5v#YDc-)P;FjL~HZ%^vQiQGp zBPaHE46Zf+#AyI?`S3n>ul3~QQ_{X9%Sba0YbN^;rY_&k+FwMwNn7~-ISm4CNbF? z2BbUT#)~&|yF%R`!4yOQJbnIG`%hneRxOKWeve`un9tJj>%!i9%oqdf2e(0R#2qVo zO{_ms#*3g)!?WxWNiMLnUWs)CLcClp!w|pc-DCp;eh&fFkK{-SoX}RI086!(0S*!C z_h=(eKZ$q&JvEK+`L`i&32#+F2vJUYF8}0}xEZP=1;G89rNO;nF}><-kmLmLJ;{Ce zWpuJIiQDlB+rTceSA0GHR~TYQToJFe4ce7iN4qR1{^!R)!6xd$<925@pTT^O$S=fB zJ05MqIDK}_G@_G9Ix^YS%W}QggDbl-9heTH)x?_7j#=tQTH>6$dF^7;&Q@A+US?sV zt^T;SQDaA=TjPNh5i?+J4)D}ey7j8fcIuM5Qm|yap;8I12|F=6j+pq}5iz!m{aUFY z;?%d#?Luj$U5~qQS{Ie~?T>TTcw&LlBiuGa0lmSp7-Je!T3{%@1{2c@>J7=5X=`Sk zrUT6WV>a;#?k_`_wB!&Zpc5cX1GJ(e8_}}YVm8+j?P~D}C1cSa3`bi9F_~~OEtxz` zoVD3TQx%n2GiYeK9GAKlsM8PWhQixc%y6P#FGU?AX5nqaS>pU%&`neKP4jb55*Wsa_h+PE>>n+TdH+Qcb?TUVxOlL5 Hz+dTiSGTml delta 466 zcmXv~PbhrXP-KHwOp# z4pP)72N%cX;vzYSaB@?h_gi`E>3yH)_q>1lS)IEf7aD-xz=5k@E@;RdL`ysQ_AI~# z0K{hIdLq&Etc!S_`22E8H$KwlC%~Hs+FCNZT6bIA17r+vpC;n^isx?ho4n72{salt zH{zV?YeFcI%53#x%X%>CFH(OW@#d7iWrSG^3S`hoXkFJ+@zUsKBjEj| zg#{zMnbBsl7l7Y6sHF0&ZP*7!H6aIWVX1!T2X&GJpj@`E{{y>&}xuFc+^;Z+%VLZ6BV@@$?x@(Et#FJfFA ni#HjPhAf+tRYxxK-qR?|ZT~rEKGhv;Qq#c^br@`QE&=`kHTPz) diff --git a/emperor/support_files/vendor/css/font/context-menu-icons.ttf b/emperor/support_files/vendor/css/font/context-menu-icons.ttf index 0f7f0d26b63312b0550ba521af61265dd5883d08..035ec9cc9b399eb5de9f23ca4b956f00e2f49c02 100644 GIT binary patch delta 920 zcmXw0S!fhN5UuL&nVy}AyR+HZ*?8pG*&|Af(M`;H#3X9)z!1Tx2nKZUijv&~jd+r% zAR>wy2O%KD_~nm?Bp-q(MD)k&R|1NP2!ew6BZ$YYH7hn#Ra38CSMj>;I^R;mfB;~? zDd4bhZTFT{H5XFH0dNVSn>ThhWZL^XS5bbE@~yja?!cEbJwpI2N!GNl@7Ugk&ZRnl zI7v+w_U>_aTd$5!6Zbt?b1wn%A)lcC2V}|K+~Cm`UVKXZK2qM^*S~9pJF~-fsKGV@ zoSb`f0ON3p2o;pq%-ZXY}_%j3)zf&M8y&k~)5(GF<>I`szP=CgJiu6W= z3urBIgpYp?dD~c>3_^%%syD)Zc;n0nl@SBrNy(FLZ?G=<0P#!NPi*;bLAjg59JQiU=4 z?2@ZQC!KKAL{l4UZo^hw+>~y>R1mEyR*iPllK;voK6bm7*BExDP=_U~~m|awJuE!)DtxmAk57iC9IU5L{+DQ9FhhKkJAnTfj~i3WzxJ=V!f; zieZ=IP8`!j;cNZNW@{)uOKM?m8=-(!VOfkZg-IpQlU;`Kv03H1%9vp*Mwy}kOuo~r z_%QdEAq-k_2;$HPkRkzf=%|%w*~>B0TpMYs^#Q3yBmWSNwhUq-?xbteSyG&_*?L3f zrBQOIE1Ei_YD%C?JD}+j?^#jZiTu7AarCH#_jG5jb0?=6hUUBKx2Q^?szNLLQl(^b ze!os8P0KQqNuCNvqm#d8OfWRPJLVjLCWgId=1Q@*KR@W{;dq%m;vUTJ&+qeB`WMNK Bu&@9C delta 464 zcmXv~ODIHP7(M^PV`j`?lx86&uMI_#CXv^Kg;0hpgqznaX3WSeW-L6iof!SG6lGyS zP3}U9x?*WLN!dsiBC(N;y1qN*tFQk*=R2M6@l}(qTmu8(z&ZpP`$k5)y~&yczXE6W( diff --git a/emperor/support_files/vendor/css/font/context-menu-icons.woff b/emperor/support_files/vendor/css/font/context-menu-icons.woff index 1884979cb317ff539db96826a76abf432edc3f6b..9651e4f0fc2f1fdae26c8b8f4b0daef3527b510c 100644 GIT binary patch delta 2837 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 diff --git a/emperor/support_files/vendor/css/jquery.contextMenu.min.css b/emperor/support_files/vendor/css/jquery.contextMenu.min.css index c6b57545..fdbada15 100644 --- a/emperor/support_files/vendor/css/jquery.contextMenu.min.css +++ b/emperor/support_files/vendor/css/jquery.contextMenu.min.css @@ -12,4 +12,4 @@ * MIT License http://www.opensource.org/licenses/mit-license * * Date: @DATE - */.context-menu-icon.context-menu-icon--fa::before,.context-menu-icon::before{font-style:normal;font-weight:400;font-size:1em;left:0;line-height:1;text-align:center;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:2em;position:absolute;top:50%;transform:translateY(-50%)}@font-face{font-family:context-menu-icons;src:url(font/context-menu-icons.eot?2a2es);src:url(font/context-menu-icons.eot?2a2es#iefix) format("embedded-opentype"),url(font/context-menu-icons.woff2?2a2es) format("woff2"),url(font/context-menu-icons.woff?2a2es) format("woff"),url(font/context-menu-icons.ttf?2a2es) format("truetype");font-weight:400;font-style:normal}.context-menu-icon-add:before{content:"\EA01"}.context-menu-icon-copy:before{content:"\EA02"}.context-menu-icon-cut:before{content:"\EA03"}.context-menu-icon-delete:before{content:"\EA04"}.context-menu-icon-edit:before{content:"\EA05"}.context-menu-icon-exchange:before{content:"\EA06"}.context-menu-icon-file-picture-o:before{content:"\EA07"}.context-menu-icon-folder-open-o:before{content:"\EA08"}.context-menu-icon-home:before{content:"\EA09"}.context-menu-icon-paste:before{content:"\EA0A"}.context-menu-icon-quit:before{content:"\EA0B"}.context-menu-icon-rotate-left:before{content:"\EA0C"}.context-menu-icon-save:before{content:"\EA0D"}.context-menu-icon::before{color:#2980B9;font-family:context-menu-icons}.context-menu-icon.context-menu-hover:before{color:#FFF}.context-menu-icon.context-menu-disabled::before{color:#bbb}.context-menu-icon.context-menu-icon--fa{display:list-item}.context-menu-icon.context-menu-icon--fa::before{color:#2980B9;font-family:FontAwesome}.context-menu-icon.context-menu-icon--fa.context-menu-hover:before{color:#FFF}.context-menu-icon.context-menu-icon--fa.context-menu-disabled::before{color:#bbb}.context-menu-list{background:#FFF;border:1px solid #bebebe;border-radius:.2em;box-shadow:0 2px 5px rgba(0,0,0,.5);font-family:inherit;font-size:inherit;display:inline-block;list-style-type:none;margin:.3em;max-width:26em;min-width:13em;padding:.25em 0;position:absolute}.context-menu-item{background-color:#FFF;color:#2F2F2F;padding:.2em 2em;position:relative;user-select:none}.context-menu-separator{border-bottom:1px solid #e6e6e6;margin:.35em 0;padding:0}.context-menu-item>label>input,.context-menu-item>label>textarea{user-select:text}.context-menu-item.context-menu-hover{background-color:#2980B9;color:#FFF;cursor:pointer}.context-menu-item.context-menu-disabled{background-color:#FFF;color:#bbb;cursor:default}.context-menu-input.context-menu-hover{cursor:default}.context-menu-submenu:after{content:'';border-style:solid;border-width:.25em 0 .25em .25em;border-color:transparent transparent transparent #2F2F2F;height:0;position:absolute;right:.5em;top:50%;transform:translateY(-50%);width:0;z-index:1}.context-menu-item.context-menu-input{padding:.3em .6em}.context-menu-input>label>*{vertical-align:top}.context-menu-input>label>input[type=checkbox],.context-menu-input>label>input[type=radio]{margin-right:.4em;position:relative;top:.12em}.context-menu-input>label{margin:0}.context-menu-input>label,.context-menu-input>label>input[type=text],.context-menu-input>label>select,.context-menu-input>label>textarea{box-sizing:border-box;display:block;width:100%}.context-menu-input>label>textarea{height:7em}.context-menu-item>.context-menu-list{display:none;right:-.3em;top:.3em}.context-menu-item.context-menu-visible>.context-menu-list{display:block}.context-menu-accesskey{text-decoration:underline} + */@font-face{font-family:context-menu-icons;src:url(font/context-menu-icons.eot?33z1y);src:url(font/context-menu-icons.eot?33z1y#iefix) format("embedded-opentype"),url(font/context-menu-icons.woff2?33z1y) format("woff2"),url(font/context-menu-icons.woff?33z1y) format("woff"),url(font/context-menu-icons.ttf?33z1y) format("truetype");font-weight:400;font-style:normal}.context-menu-icon-add:before{content:"\EA01"}.context-menu-icon-copy:before{content:"\EA02"}.context-menu-icon-cut:before{content:"\EA03"}.context-menu-icon-delete:before{content:"\EA04"}.context-menu-icon-edit:before{content:"\EA05"}.context-menu-icon-exchange:before{content:"\EA06"}.context-menu-icon-file-picture-o:before{content:"\EA07"}.context-menu-icon-folder-open-o:before{content:"\EA08"}.context-menu-icon-font:before{content:"\EA09"}.context-menu-icon-home:before{content:"\EA0A"}.context-menu-icon-paste:before{content:"\EA0B"}.context-menu-icon-quit:before{content:"\EA0C"}.context-menu-icon-rotate-left:before{content:"\EA0D"}.context-menu-icon-save:before{content:"\EA0E"}.context-menu-icon-warning:before{content:"\EA0F"}.context-menu-icon::before{color:#2980b9;font-family:context-menu-icons;font-style:normal;font-weight:400;font-size:1em;left:0;line-height:1;position:absolute;text-align:center;top:50%;transform:translateY(-50%);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:2em}.context-menu-icon.context-menu-hover:before{color:#fff}.context-menu-icon.context-menu-disabled::before{color:#bbb}.context-menu-icon.context-menu-icon--fa{display:list-item}.context-menu-icon.context-menu-icon--fa::before{color:#2980b9;font-family:FontAwesome;font-style:normal;font-weight:400;font-size:1em;left:0;line-height:1;position:absolute;text-align:center;top:50%;transform:translateY(-50%);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:2em}.context-menu-icon.context-menu-icon--fa.context-menu-hover:before{color:#fff}.context-menu-icon.context-menu-icon--fa.context-menu-disabled::before{color:#bbb}.context-menu-list{background:#fff;border:1px solid #bebebe;border-radius:.2em;box-shadow:0 2px 5px rgba(0,0,0,.5);font-family:inherit;font-size:inherit;display:inline-block;list-style-type:none;margin:.3em;max-width:26em;min-width:13em;padding:.25em 0;position:absolute}.context-menu-item{background-color:#fff;color:#2f2f2f;padding:.2em 2em;position:relative;user-select:none}.context-menu-separator{border-bottom:1px solid #e6e6e6;margin:.35em 0;padding:0}.context-menu-item>label>input,.context-menu-item>label>textarea{user-select:text}.context-menu-item.context-menu-hover{background-color:#2980b9;color:#fff;cursor:pointer}.context-menu-item.context-menu-disabled{background-color:#fff;color:#bbb;cursor:default}.context-menu-input.context-menu-hover{cursor:default}.context-menu-submenu:after{content:"";border-style:solid;border-width:.25em 0 .25em .25em;border-color:transparent transparent transparent #2f2f2f;height:0;position:absolute;right:.5em;top:50%;transform:translateY(-50%);width:0;z-index:1}.context-menu-item.context-menu-input{padding:.3em .6em}.context-menu-input>label>*{vertical-align:top}.context-menu-input>label>input[type=checkbox],.context-menu-input>label>input[type=radio]{margin-right:.4em;position:relative;top:.12em}.context-menu-input>label{margin:0}.context-menu-input>label,.context-menu-input>label>input[type=text],.context-menu-input>label>select,.context-menu-input>label>textarea{box-sizing:border-box;display:block;width:100%}.context-menu-input>label>textarea{height:7em}.context-menu-item>.context-menu-list{display:none;right:-.3em;top:.3em}.context-menu-item.context-menu-visible>.context-menu-list{display:block}.context-menu-accesskey{text-decoration:underline} From 1b3ef3c3c602a0ee4b09d610c115d4b1eed94159 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 18 Apr 2019 18:42:11 -0700 Subject: [PATCH 4/4] SQUASH: linty lint --- emperor/support_files/js/controller.js | 2 +- emperor/support_files/js/view.js | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/emperor/support_files/js/controller.js b/emperor/support_files/js/controller.js index 8baf141f..00390dd3 100644 --- a/emperor/support_files/js/controller.js +++ b/emperor/support_files/js/controller.js @@ -985,7 +985,7 @@ define([ count -= 1; } setTimeout(send, step); - } + }; /** * diff --git a/emperor/support_files/js/view.js b/emperor/support_files/js/view.js index 2484063c..4328872c 100644 --- a/emperor/support_files/js/view.js +++ b/emperor/support_files/js/view.js @@ -151,7 +151,7 @@ DecompositionView.prototype._initBaseView = function() { mesh.position.set(plottable.coordinates[x], plottable.coordinates[y], plottable.coordinates[z] || 0); - mesh.userData.shape = 'Sphere' + mesh.userData.shape = 'Sphere'; scope.markers.push(mesh); @@ -876,7 +876,8 @@ DecompositionView.prototype._buildVegaSpec = function() { return points; }; - // This is probably horribly slow on QIITA-scale MD files, probably needs some attention + // This is probably horribly slow on QIITA-scale MD files, probably needs + // some attention function plottablesAsMetadata(points, header) { var md = [], point, row, i, j; for (i = 0; i < points.length; i++) { @@ -912,7 +913,10 @@ DecompositionView.prototype._buildVegaSpec = function() { }, title: 'Emperor PCoA', data: [ - { name: 'metadata', values: plottablesAsMetadata(model.plottable, model.md_headers), }, + { + name: 'metadata', + values: plottablesAsMetadata(model.plottable, model.md_headers), + }, { name: 'points', values: viewMarkersAsVegaDataset(scope.markers), transform: [ @@ -927,8 +931,14 @@ DecompositionView.prototype._buildVegaSpec = function() { }, ], signals: [ - {name: 'width', update: baseWidth + ' * ((' + rangeX[1] + ') - (' + rangeX[0] + '))'}, - {name: 'height', update: baseWidth + ' * ((' + rangeY[1] + ') - (' + rangeY[0] + '))'} + { + name: 'width', + update: baseWidth + ' * ((' + rangeX[1] + ') - (' + rangeX[0] + '))', + }, + { + name: 'height', + update: baseWidth + ' * ((' + rangeY[1] + ') - (' + rangeY[0] + '))', + }, ], scales: [ { name: 'xScale', range: 'width', domain: [rangeX[0], rangeX[1]] }, @@ -958,7 +968,7 @@ DecompositionView.prototype._buildVegaSpec = function() { }, ], }; -} +}; /** * Helper function to change the opacity of an arrow object.