From bac7535232eb0c64e20d8a19321f2f97bf26d989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Tusz?= Date: Fri, 1 Apr 2016 17:41:33 -0400 Subject: [PATCH 1/7] Devtools overhaul - now with reloadng and search! --- devtools/test_dashboard_v2/devtools.js | 138 +++++++++++++++++++++++++ devtools/test_dashboard_v2/fuse.min.js | 20 ++++ devtools/test_dashboard_v2/index.html | 79 ++++++++++++++ devtools/test_dashboard_v2/mocks.js | 135 ++++++++++++++++++++++++ devtools/test_dashboard_v2/server.js | 49 +++++++++ 5 files changed, 421 insertions(+) create mode 100644 devtools/test_dashboard_v2/devtools.js create mode 100644 devtools/test_dashboard_v2/fuse.min.js create mode 100644 devtools/test_dashboard_v2/index.html create mode 100644 devtools/test_dashboard_v2/mocks.js create mode 100644 devtools/test_dashboard_v2/server.js diff --git a/devtools/test_dashboard_v2/devtools.js b/devtools/test_dashboard_v2/devtools.js new file mode 100644 index 00000000000..9ddd937e573 --- /dev/null +++ b/devtools/test_dashboard_v2/devtools.js @@ -0,0 +1,138 @@ +// Our gracious testing object +var Tabs = { + + getGraph: function(id) { + id = id || 'default-plot'; + return document.getElementById(id); + }, + + fresh: function(id) { + id = id || 'default-plot'; + + var graphDiv = Tabs.getGraph(id); + + if(graphDiv) { + graphDiv.remove(); + } + + graphDiv = document.createElement('div'); + graphDiv.className = 'dashboard-plot'; + graphDiv.id = id; + + var plotArea = document.getElementById('plots'); + plotArea.appendChild(graphDiv); + + return graphDiv; + }, + + plotMock: function(mockName, id) { + var mockURL = '/test/image/mocks/' + mockName + '.json'; + + window.Plotly.d3.json(mockURL, function(err, fig) { + window.Plotly.plot(Tabs.fresh(id), fig.data, fig.layout); + }); + }, + + snapshot: function(id) { + var gd = Tabs.getGraph(id); + + if(!gd._fullLayout || !gd._fullData) { + return; + } + + var image = new Image(); + + window.Plotly.Snapshot.toImage(gd, { format: 'png' }).on('success', function(img) { + image.src = img; + + var imageDiv = document.getElementById('snapshot'); + imageDiv.appendChild(image); + + console.warn('Snapshot complete!'); + }); + }, + + purge: function() { + var plots = document.getElementsByClassName('dashboard-plot'); + var images = document.getElementsById('snapshot'); + + while(images.firstChild) { + images.removeChild(images.firstChild); + } + + for(var i = 0; i < plots.length; i++) { + window.Plotly.purge(plots[i]); + } + }, + + onReload: function() { + return; + }, + + reload: function() { + var source = document.getElementById('source'); + var reloaded = document.getElementById('reload-time'); + + source.remove(); + + window.Plotly = null; + + source = document.createElement('script'); + source.id = 'source'; + source.src = '../../build/plotly.js'; + + document.body.appendChild(source); + + var reloadTime = new Date().toLocaleTimeString(); + console.warn('plotly.js reloaded at ' + reloadTime); + reloaded.textContent = 'last reload at ' + reloadTime; + + Tabs.onReload(); + } +}; + + +setInterval(function() { + window.gd = Tabs.getGraph() || Tabs.fresh(); + window.fullLayout = window.gd._fullLayout; + window.fullData = window.gd._fullData; +}, 1000); + + +// Mocks search and plotting +var f = new window.Fuse(window.MOCKS, { keys: ['name'] }); + +var searchBar = document.getElementById('mocks-search'); +var mocksList = document.getElementById('mocks-list'); +searchBar.addEventListener('keyup', function(e) { + + // Clear results. + while(mocksList.firstChild) { + mocksList.removeChild(mocksList.firstChild); + } + + + var results = f.search(e.target.value); + + results.forEach(function(r) { + var result = document.createElement('span'); + result.className = 'search-result'; + result.innerText = r.name; + + result.addEventListener('click', function() { + // Clear plots and plot selected. + Tabs.purge(); + Tabs.plotMock(r.file.slice(0, -5)); + console.warn('Plotting:', r.file); + + // Clear results. + while(mocksList.firstChild) { + mocksList.removeChild(mocksList.firstChild); + } + + e.target.value = ''; + }); + + mocksList.appendChild(result); + }); +}); diff --git a/devtools/test_dashboard_v2/fuse.min.js b/devtools/test_dashboard_v2/fuse.min.js new file mode 100644 index 00000000000..6978762f599 --- /dev/null +++ b/devtools/test_dashboard_v2/fuse.min.js @@ -0,0 +1,20 @@ +/** + * @license + * Fuse - Lightweight fuzzy-search + * + * Copyright (c) 2012-2016 Kirollos Risk . + * All Rights Reserved. Apache Software License 2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +!function(t){"use strict";function e(){console.log.apply(console,arguments)}function s(t,e){var s,n,i,o;for(this.list=t,this.options=e=e||{},s=0,o=["sort","shouldSort","verbose","tokenize"],n=o.length;n>s;s++)i=o[s],this.options[i]=i in e?e[i]:h[i];for(s=0,o=["searchFn","sortFn","keys","getFn","include"],n=o.length;n>s;s++)i=o[s],this.options[i]=e[i]||h[i]}function n(t,e,s){var o,r,h,a,c,p;if(e){if(h=e.indexOf("."),-1!==h?(o=e.slice(0,h),r=e.slice(h+1)):o=e,a=t[o],null!==a&&void 0!==a)if(r||"string"!=typeof a&&"number"!=typeof a)if(i(a))for(c=0,p=a.length;p>c;c++)n(a[c],r,s);else r&&n(a,r,s);else s.push(a)}else s.push(t);return s}function i(t){return"[object Array]"===Object.prototype.toString.call(t)}function o(t,e){e=e||{},this.options=e,this.options.location=e.location||o.defaultOptions.location,this.options.distance="distance"in e?e.distance:o.defaultOptions.distance,this.options.threshold="threshold"in e?e.threshold:o.defaultOptions.threshold,this.options.maxPatternLength=e.maxPatternLength||o.defaultOptions.maxPatternLength,this.pattern=e.caseSensitive?t:t.toLowerCase(),this.patternLen=t.length,this.patternLen<=this.options.maxPatternLength&&(this.matchmask=1<i;i++)this.tokenSearchers.push(new s(n[i],t));this.fullSeacher=new s(e,t)},s.prototype._startSearch=function(){var t,e,s,n,i=this.options,o=i.getFn,r=this.list,h=r.length,a=this.options.keys,c=a.length,p=null;if("string"==typeof r[0])for(s=0;h>s;s++)this._analyze("",r[s],s,s);else for(this._keyMap={},s=0;h>s;s++)for(p=r[s],n=0;c>n;n++){if(t=a[n],"string"!=typeof t){if(e=1-t.weight||1,this._keyMap[t.name]={weight:e},t.weight<=0||t.weight>1)throw new Error("Key weight has to be > 0 and <= 1");t=t.name}else this._keyMap[t]={weight:1};this._analyze(t,o(p,t,[]),p,s)}},s.prototype._analyze=function(t,s,n,o){var h,a,c,p,l,u,f,d,g,m,y,v,b,S,k,_=this.options,M=!1;if(void 0!==s&&null!==s)if(a=[],"string"==typeof s){if(h=s.split(r),_.verbose&&e("---------\nKey:",t),_.verbose&&e("Record:",h),this.options.tokenize){for(c=this.tokenSearchers,p=c.length,S=0;SS;S++)u+=a[S];u/=d,_.verbose&&e("Token score average:",u)}g=this.fullSeacher.search(s),_.verbose&&e("Full text score:",g.score),f=g.score,void 0!==u&&(f=(f+u)/2),_.verbose&&e("Score average:",f),(M||g.isMatch)&&(l=this.resultMap[o],l?l.output.push({key:t,score:f,matchedIndices:g.matchedIndices}):(this.resultMap[o]={item:n,output:[{key:t,score:f,matchedIndices:g.matchedIndices}]},this.results.push(this.resultMap[o])))}else if(i(s))for(S=0;Ss;s++)r=i[s].score,h=p?p[i[s].key].weight:1,c=r*h,1!==h?a=Math.min(a,c):(n+=c,i[s].nScore=c);1===a?l[t].score=n/o:l[t].score=a,this.options.verbose&&e(l[t])}},s.prototype._sort=function(){var t=this.options;t.shouldSort&&(t.verbose&&e("\n\nSorting...."),this.results.sort(t.sortFn))},s.prototype._format=function(){var t,s,n,i,o,r=this.options,h=r.getFn,a=[],c=this.results,p=r.include;for(r.verbose&&e("\n\nOutput:\n\n",c),i=r.id?function(t){c[t].item=h(c[t].item,r.id,[])[0]}:function(){},o=function(t){var e,s,n,i,o,r=c[t];if(p.length>0){if(e={item:r.item},-1!==p.indexOf("matches"))for(n=r.output,e.matches=[],s=0;ss;s++)i(s),t=o(s),a.push(t);return a},o.defaultOptions={location:0,distance:100,threshold:.6,maxPatternLength:32},o.prototype._calculatePatternAlphabet=function(){var t={},e=0;for(e=0;eL.maxPatternLength){if(v=t.match(new RegExp(this.pattern.replace(r,"|"))),b=!!v)for(k=[],e=0,_=v.length;_>e;e++)M=v[e],k.push([t.indexOf(M),M.length-1]);return{isMatch:b,score:b?.5:1,matchedIndices:k}}for(i=L.location,n=t.length,o=L.threshold,h=t.indexOf(this.pattern,i),S=[],e=0;n>e;e++)S[e]=0;for(-1!=h&&(o=Math.min(this._bitapScore(0,h),o),h=t.lastIndexOf(this.pattern,i+this.patternLen),-1!=h&&(o=Math.min(this._bitapScore(0,h),o))),h=-1,m=1,y=[],p=this.patternLen+n,e=0;ea;)this._bitapScore(e,i+c)<=o?a=c:p=c,c=Math.floor((p-a)/2+a);for(p=c,l=Math.max(1,i-c+1),u=Math.min(i+c,n)+this.patternLen,f=Array(u+2),f[u+1]=(1<=l;s--)if(g=this.patternAlphabet[t.charAt(s-1)],g&&(S[s-1]=1),0===e?f[s]=(f[s+1]<<1|1)&g:f[s]=(f[s+1]<<1|1)&g|((d[s+1]|d[s])<<1|1)|d[s+1],f[s]&this.matchmask&&(m=this._bitapScore(e,s-1),o>=m)){if(o=m,h=s-1,y.push(h),!(h>i))break;l=Math.max(1,2*i-h)}if(this._bitapScore(e+1,i)>o)break;d=f}return k=this._getMatchedIndices(S),{isMatch:h>=0,score:0===m?.001:m,matchedIndices:k}},o.prototype._getMatchedIndices=function(t){for(var e,s=[],n=-1,i=-1,o=0,r=r=t.length;r>o;o++)e=t[o],e&&-1===n?n=o:e||-1===n||(i=o-1,s.push([n,i]),n=-1);return t[o-1]&&s.push([n,o-1]),s},"object"==typeof exports?module.exports=s:"function"==typeof define&&define.amd?define(function(){return s}):t.Fuse=s}(this); \ No newline at end of file diff --git a/devtools/test_dashboard_v2/index.html b/devtools/test_dashboard_v2/index.html new file mode 100644 index 00000000000..63f253fdb4f --- /dev/null +++ b/devtools/test_dashboard_v2/index.html @@ -0,0 +1,79 @@ + + + + Plotly.js Devtools + + + +
+ + + + +
+ +
+
+
+ + + + + + + + diff --git a/devtools/test_dashboard_v2/mocks.js b/devtools/test_dashboard_v2/mocks.js new file mode 100644 index 00000000000..87a2de9087f --- /dev/null +++ b/devtools/test_dashboard_v2/mocks.js @@ -0,0 +1,135 @@ +var MOCKS = [ + // Cartesian + { name: 'cartesian - 10', file: '10.json' }, + { name: 'cartesian - 14', file: '14.json' }, + { name: 'cartesian - 12', file: '12.json' }, + { name: 'cartesian - 17', file: '17.json' }, + { name: 'cartesian - 22', file: '22.json' }, + { name: 'cartesian - 24', file: '24.json' }, + { name: 'cartesian - 28', file: '28.json' }, + { name: 'cartesian - 30', file: '30.json' }, + { name: 'cartesian - 32', file: '32.json' }, + { name: 'cartesian - axes booleans', file: 'axes_booleans.json' }, + { name: 'cartesian - axes labels', file: 'axes_labels.json' }, + { name: 'cartesian - axes lines', file: 'axes_lines.json' }, + { name: 'cartesian - axes range manual', file: 'axes_range_manual.json' }, + { name: 'cartesian - axes range type', file: 'axes_range_type.json' }, + { name: 'cartesian - axes range mode', file: 'axes_range_mode.json' }, + { name: 'cartesian - basic error bar', file: 'basic_error_bar.json' }, + { name: 'cartesian - bubble markersize', file: 'bubble_markersize0.json' }, + { name: 'cartesian - bubble nonnumeric sizes', file: 'bubble_nonnumeric-sizes.json' }, + { name: 'cartesian - date axes', file: 'date_axes.json' }, + { name: 'cartesian - error bar asymmetric array', file: 'error_bar_asymmetric_array.json' }, + { name: 'cartesian - error bar asymmetric constant', file: 'error_bar_asymmetric_constant.json' }, + { name: 'cartesian - error bar horizontal', file: 'error_bar_horizontal.json' }, + { name: 'cartesian - error bar style', file: 'error_bar_style.json' }, + { name: 'cartesian - fonts', file: 'fonts.json' }, + { name: 'cartesian - global font', file: 'global_font.json' }, + { name: 'cartesian - legend inside', file: 'legend_inside.json' }, + { name: 'cartesian - legend labels', file: 'legend_labels.json' }, + { name: 'cartesian - legend outside', file: 'legend_outside.json' }, + { name: 'cartesian - legend style', file: 'legend_style.json' }, + { name: 'cartesian - line style', file: 'line_style.json' }, + { name: 'cartesian - multiple subplots', file: 'multiple_subplots.json' }, + { name: 'cartesian - scatter colorscale colorbar', file: 'scatter-colorscale-colorbar.json' }, + { name: 'cartesian - scatter marker line colorscales', 'file': 'scatter-marker-line-colorscales.json' }, + { name: 'cartesian - show legend', file: 'show_legend.json' }, + { name: 'cartesian - simple inset', file: 'simple_inset.json' }, + { name: 'cartesian - size margins', file: 'size_margins.json' }, + { name: 'cartesian - stacked coupled subplots', file: 'stacked_coupled_subplots.json' }, + { name: 'cartesian - stacked subplots', file: 'stacked_subplots.json' }, + + // Geo + { name: 'geo - first', file: 'geo_first.json' }, + { name: 'geo - second', file: 'geo_second.json' }, + { name: 'geo - kavrayskiy7', file: 'geo_kavrayskiy7.json' }, + { name: 'geo - custom colorscale', file: 'geo_custom-colorscale.json' }, + { name: 'geo - scattergeo locations', file: 'geo_scattergeo-locations.json' }, + { name: 'geo - multi geos', file: 'geo_multi-geos.json' }, + { name: 'geo - usa states', file: 'geo_usa-states.json' }, + { name: 'geo - legend only', file: 'geo_legendonly.json' }, + { name: 'geo - europe bubbles', file: 'geo_europe-bubbles.json' }, + { name: 'geo - orthographic', file: 'geo_orthographic.json' }, + { name: 'geo - big frame', file: 'geo_big-frame.json' }, + { name: 'geo - background color', file: 'geo_bg-color.json' }, + { name: 'geo - canadian cities', file: 'geo_canadian-cites.json' }, + { name: 'geo - conic conformal', file: 'geo_conic-conformal.json' }, + { name: 'geo - stereograpic', file: 'geo_stereographic.json' }, + { name: 'geo - choropleth text', file: 'geo_choropleth-text.json' }, + { name: 'geo - choropleth usa', file: 'geo_choropleth-usa.json' }, + { name: 'geo - country names', file: 'geo_country-names.json' }, + + // gl2d + { name: 'gl2d - 10', file: 'gl2d_10.json' }, + { name: 'gl2d - 14', file: 'gl2d_14.json' }, + { name: 'gl2d - 12', file: 'gl2d_12.json' }, + { name: 'gl2d - 17', file: 'gl2d_17.json' }, + { name: 'gl2d - 22', file: 'gl2d_22.json' }, + { name: 'gl2d - 24', file: 'gl2d_24.json' }, + { name: 'gl2d - 28', file: 'gl2d_28.json' }, + { name: 'gl2d - 30', file: 'gl2d_30.json' }, + { name: 'gl2d - 32', file: 'gl2d_32.json' }, + { name: 'gl2d - axes booleans', file: 'gl2d_axes_booleans.json' }, + { name: 'gl2d - axes labels', file: 'gl2d_axes_labels.json' }, + { name: 'gl2d - axes lines', file: 'gl2d_axes_lines.json' }, + { name: 'gl2d - axes range_manual', file: 'gl2d_axes_range_manual.json' }, + { name: 'gl2d - axes range_type', file: 'gl2d_axes_range_type.json' }, + { name: 'gl2d - axes range_mode', file: 'gl2d_axes_range_mode.json' }, + { name: 'gl2d - basic error_bar', file: 'gl2d_basic_error_bar.json' }, + { name: 'gl2d - bubble markersize0', file: 'gl2d_bubble_markersize0.json' }, + { name: 'gl2d - bubble nonnumeric-sizes', file: 'gl2d_bubble_nonnumeric-sizes.json' }, + { name: 'gl2d - date axes', file: 'gl2d_date_axes.json' }, + { name: 'gl2d - error bar asymmetric array', file: 'gl2d_error_bar_asymmetric_array.json' }, + { name: 'gl2d - error bar asymmetric constant', file: 'gl2d_error_bar_asymmetric_constant.json' }, + { name: 'gl2d - error bar horizontal', file: 'gl2d_error_bar_horizontal.json' }, + { name: 'gl2d - error bar style', file: 'gl2d_error_bar_style.json' }, + { name: 'gl2d - fonts', file: 'gl2d_fonts.json' }, + { name: 'gl2d - global font', file: 'gl2d_global_font.json' }, + { name: 'gl2d - legend inside', file: 'gl2d_legend_inside.json' }, + { name: 'gl2d - legend labels', file: 'gl2d_legend_labels.json' }, + { name: 'gl2d - legend outside', file: 'gl2d_legend_outside.json' }, + { name: 'gl2d - legend style', file: 'gl2d_legend_style.json' }, + { name: 'gl2d - line style', file: 'gl2d_line_style.json' }, + { name: 'gl2d - multiple subplots', file: 'gl2d_multiple_subplots.json' }, + { name: 'gl2d - scatter colorscale colorbar', file: 'gl2d_scatter-colorscale-colorbar.json' }, + { name: 'gl2d - scatter marker line colorscales', file: 'gl2d_scatter-marker-line-colorscales.json' }, + { name: 'gl2d - show legend', file: 'gl2d_show_legend.json' }, + { name: 'gl2d - simple inset', file: 'gl2d_simple_inset.json' }, + { name: 'gl2d - size margins', file: 'gl2d_size_margins.json' }, + { name: 'gl2d - stacked coupled_subplots', file: 'gl2d_stacked_coupled_subplots.json' }, + { name: 'gl2d - stacked subplots', file: 'gl2d_stacked_subplots.json' }, + + // gl3d + { name: 'gl3d - bunny-hull', file: 'gl3d_bunny-hull.json' }, + { name: 'gl3d - ibm-plot', file: 'gl3d_ibm-plot.json' }, + { name: 'gl3d - marker-color', file: 'gl3d_marker-color.json' }, + { name: 'gl3d - log-axis-big', file: 'gl3d_log-axis-big.json' }, + { name: 'gl3d - delaunay', file: 'gl3d_delaunay.json' }, + { name: 'gl3d - log-axis', file: 'gl3d_log-axis.json' }, + { name: 'gl3d - multi-scene', file: 'gl3d_multi-scene.json' }, + { name: 'gl3d - surface-lighting', file: 'gl3d_surface-lighting.json' }, + { name: 'gl3d - z-range', file: 'gl3d_z-range.json' }, + { name: 'gl3d - mirror-ticks', file: 'gl3d_mirror-ticks.json' }, + { name: 'gl3d - autorange-zero', file: 'gl3d_autorange-zero.json' }, + { name: 'gl3d - contour-lines', file: 'gl3d_contour-lines.json' }, + { name: 'gl3d - xy-defined-ticks', file: 'gl3d_xy-defined-ticks.json' }, + { name: 'gl3d - opacity-surface', file: 'gl3d_opacity-surface.json' }, + { name: 'gl3d - projection-traces', file: 'gl3d_projection-traces.json' }, + { name: 'gl3d - opacity-scaling-spikes', file: 'gl3d_opacity-scaling-spikes.json' }, + { name: 'gl3d - text-weirdness', file: 'gl3d_text-weirdness.json' }, + { name: 'gl3d - wire-surface', file: 'gl3d_wire-surface.json' }, + { name: 'gl3d - triangle', file: 'gl3d_triangle.json' }, + { name: 'gl3d - snowden', file: 'gl3d_snowden.json' }, + { name: 'gl3d - bunny', file: 'gl3d_bunny.json' }, + { name: 'gl3d - ribbons', file: 'gl3d_ribbons.json' }, + { name: 'gl3d - scatter-date', file: 'gl3d_scatter-date.json' }, + { name: 'gl3d - cufflinks', file: 'gl3d_cufflinks.json' }, + { name: 'gl3d - chrisp-nan-1', file: 'gl3d_chrisp-nan-1.json' }, + { name: 'gl3d - marker-arrays', file: 'gl3d_marker-arrays.json' }, + { name: 'gl3d - scatter3d-colorscale', file: 'gl3d_scatter3d-colorscale.json' }, + { name: 'gl3d - autocolorscale', file: 'gl3d_autocolorscale.json' }, + { name: 'gl3d - nan-holes', file: 'gl3d_nan-holes.json' }, + { name: 'gl3d - scatter3d-connectgaps', file: 'gl3d_scatter3d-connectgaps.json' }, + { name: 'gl3d - tet', file: 'gl3d_tet.json' }, + { name: 'gl3d - surface_intensity', file: 'gl3d_surface_intensity.json' } +]; diff --git a/devtools/test_dashboard_v2/server.js b/devtools/test_dashboard_v2/server.js new file mode 100644 index 00000000000..82e5e09d9a2 --- /dev/null +++ b/devtools/test_dashboard_v2/server.js @@ -0,0 +1,49 @@ +var fs = require('fs'); +var http = require('http'); +var ecstatic = require('ecstatic'); +var open = require('open'); +var browserify = require('browserify'); +var watchify = require('watchify'); + +var constants = require('../../tasks/util/constants'); +var compress = require('../../tasks/util/compress_attributes'); + +var PORT = process.argv[2] || 3000; + +var server = http.createServer(ecstatic({ + root: constants.pathToRoot, + cache: 0, + gzip: true +})); + + +// Bundle development code +var b = browserify(constants.pathToPlotlyIndex, { + debug: true, + standalone: 'Plotly', + transform: [compress], + cache: {}, + packageCache: {}, + plugin: [watchify] +}); +b.on('update', bundle); + +var firstBundle = true; +function bundle() { + b.bundle(function(err) { + if(err) { + console.error('Error while bundling!', err); + } + + if(firstBundle) { + open('http://localhost:' + PORT + '/devtools/test_dashboard_v2'); + firstBundle = false; + } + console.log('Bundle updated at ' + new Date().toLocaleTimeString()); + }).pipe(fs.createWriteStream(constants.pathToPlotlyBuild)); +} + +bundle(); +server.listen(PORT); + +console.log('Building the first bundle. This might take a little while...\n'); From 49371905393e1c6b36beda2f21166d46024eb96d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Tusz?= Date: Mon, 4 Apr 2016 14:51:06 -0400 Subject: [PATCH 2/7] Change default plot id and add initial div to DOM --- devtools/test_dashboard_v2/devtools.js | 4 ++-- devtools/test_dashboard_v2/index.html | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/devtools/test_dashboard_v2/devtools.js b/devtools/test_dashboard_v2/devtools.js index 9ddd937e573..a4cd1bd8386 100644 --- a/devtools/test_dashboard_v2/devtools.js +++ b/devtools/test_dashboard_v2/devtools.js @@ -2,12 +2,12 @@ var Tabs = { getGraph: function(id) { - id = id || 'default-plot'; + id = id || 'graph'; return document.getElementById(id); }, fresh: function(id) { - id = id || 'default-plot'; + id = id || 'graph'; var graphDiv = Tabs.getGraph(id); diff --git a/devtools/test_dashboard_v2/index.html b/devtools/test_dashboard_v2/index.html index 63f253fdb4f..166b573bb6a 100644 --- a/devtools/test_dashboard_v2/index.html +++ b/devtools/test_dashboard_v2/index.html @@ -67,7 +67,9 @@
-
+
+
+
From 827b7ac063b3968b411ecdff500a2e2ec2c35baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Tusz?= Date: Tue, 5 Apr 2016 12:09:50 -0400 Subject: [PATCH 3/7] Add autogeneration for mocks, fuzzy-search on two keys, and build step --- .gitignore | 2 + devtools/test_dashboard/buttons.js | 158 -------------- .../devtools.js | 30 ++- devtools/test_dashboard/index.html | 60 ++---- devtools/test_dashboard/server.js | 193 ++++++++++++++---- devtools/test_dashboard/style.css | 54 +++++ devtools/test_dashboard/test_cartesian.js | 48 ----- devtools/test_dashboard/test_geo.js | 28 --- devtools/test_dashboard/test_gl2d.js | 48 ----- devtools/test_dashboard/test_gl3d.js | 42 ---- devtools/test_dashboard_v2/fuse.min.js | 20 -- devtools/test_dashboard_v2/index.html | 81 -------- devtools/test_dashboard_v2/mocks.js | 135 ------------ devtools/test_dashboard_v2/server.js | 49 ----- package.json | 1 + 15 files changed, 249 insertions(+), 700 deletions(-) delete mode 100644 devtools/test_dashboard/buttons.js rename devtools/{test_dashboard_v2 => test_dashboard}/devtools.js (80%) create mode 100644 devtools/test_dashboard/style.css delete mode 100644 devtools/test_dashboard/test_cartesian.js delete mode 100644 devtools/test_dashboard/test_geo.js delete mode 100644 devtools/test_dashboard/test_gl2d.js delete mode 100644 devtools/test_dashboard/test_gl3d.js delete mode 100644 devtools/test_dashboard_v2/fuse.min.js delete mode 100644 devtools/test_dashboard_v2/index.html delete mode 100644 devtools/test_dashboard_v2/mocks.js delete mode 100644 devtools/test_dashboard_v2/server.js diff --git a/.gitignore b/.gitignore index 54d6c34020d..8f830eca1b3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ build/* !build/ploticon.js !build/README.md +devtools/test_dashboard/mocks.json + npm-debug.log* diff --git a/devtools/test_dashboard/buttons.js b/devtools/test_dashboard/buttons.js deleted file mode 100644 index 3dab386271c..00000000000 --- a/devtools/test_dashboard/buttons.js +++ /dev/null @@ -1,158 +0,0 @@ -/* global Plotly:false Tabs:false */ - -var Lib = require('@src/lib'); - -var plotList = document.getElementById('plot-list'); -var anchor = document.getElementById('embedded-graph'); -var image = document.getElementById('embedded-image'); - -var gd = null; - -anchor.style.position = 'relative'; -anchor.style.top = '80px'; -anchor.style.height = '600px'; -anchor.style.width = '1000px'; - -function plotButtons(plots, figDir) { - Object.keys(plots).forEach(function(plotname) { - var button = document.createElement('button'); - - button.style.cssFloat = 'left'; - button.style.width = '100px'; - button.style.height = '40px'; - button.innerHTML = plotname; - - plotList.appendChild(button); - - button.addEventListener('click', function() { - var myImage = new Image(); - myImage.src = figDir + plotname + '.png'; - - image.innerHTML = ''; - image.appendChild(myImage); - - var currentGraphDiv = Tabs.getGraph(); - if(currentGraphDiv) Plotly.purge(currentGraphDiv); - - gd = document.createElement('div'); - gd.id = 'graph'; - - anchor.innerHTML = ''; - anchor.appendChild(gd); - - var plot = plots[plotname]; - var data = Lib.extendDeep([], plot.data); - var layout = Lib.extendDeep({}, plot.layout); - - Plotly.plot(gd, data, layout); - }); - }); - - var snapshot = document.createElement('button'); - - snapshot.style.cssFloat = 'left'; - snapshot.style.width = '100px'; - snapshot.style.height = '40px'; - snapshot.style.marginLeft = '25px'; - snapshot.innerHTML = 'snapshot'; - snapshot.style.background = 'blue'; - - plotList.appendChild(snapshot); - - snapshot.addEventListener('click', function() { - - /* - * Grab the currently loaded plot and make an image - replacing the plot. - */ - if(!gd) return; - - var layout = gd.layout; - var data = gd.data; - - if(!layout || !data) return; - - Plotly.Plots.getSubplotIds(gd._fullLayout, 'gl3d').forEach(function(key) { - var scene = gd._fullLayout[key]._scene; - scene.destroy(); - }); - - // create a fresh gd - anchor.innerHTML = ''; - gd = document.createElement('div'); - anchor.appendChild(gd); - - /* - * Replot with staticPlot - */ - Plotly.plot(gd, data, layout, {staticPlot: true, plotGlPixelRatio: 2}).then(function() { - Plotly.Plots.getSubplotIds(gd._fullLayout, 'gl3d').forEach(function(key) { - var scene = gd._fullLayout[key]._scene; - var dataURL = scene.toImage(); - - var myImage = new Image(); - myImage.src = dataURL; - - myImage.onload = function() { - myImage.height = scene.container.clientHeight; - myImage.width = scene.container.clientWidth; - }; - - image.innerHTML = ''; - image.appendChild(myImage); - }); - }); - }); - - var pummelButton = document.createElement('button'); - pummelButton.style.cssFloat = 'left'; - pummelButton.style.width = '100px'; - pummelButton.style.height = '40px'; - pummelButton.style.marginLeft = '25px'; - pummelButton.innerHTML = 'pummel3d'; - pummelButton.style.background = 'blue'; - plotList.appendChild(pummelButton); - - var i = 0; - var mock = require('@mocks/gl3d_marker-color.json'); - var statusDiv = document.getElementById('status-info'); - - pummelButton.addEventListener('click', function() { - setInterval(function() { - var plotDiv = document.createElement('div'); - window.plotDiv = plotDiv; - - plotDiv.id = 'div' + i; - document.body.appendChild(plotDiv); - - Plotly.plot(plotDiv, mock.data, mock.layout, {staticPlot: true}).then(function() { - - Plotly.Plots.getSubplotIds(plotDiv._fullLayout, 'gl3d').forEach(function(key) { - var scene = plotDiv._fullLayout[key]._scene; - scene.destroy(); - i ++; - statusDiv.innerHTML = 'Created ' + i + ' webgl contexts.'; - }); - - document.body.removeChild(plotDiv); - }); - - }, 500); - }); - - var scrapeButton = document.createElement('button'); - scrapeButton.style.cssFloat = 'left'; - scrapeButton.style.width = '100px'; - scrapeButton.style.height = '40px'; - scrapeButton.style.marginLeft = '25px'; - scrapeButton.innerHTML = 'scrape SVG'; - scrapeButton.style.background = 'blue'; - plotList.appendChild(scrapeButton); - - scrapeButton.addEventListener('click', function() { - Plotly.Snapshot.toSVG(Tabs.get()); - return; - }); - -} - -module.exports = plotButtons; diff --git a/devtools/test_dashboard_v2/devtools.js b/devtools/test_dashboard/devtools.js similarity index 80% rename from devtools/test_dashboard_v2/devtools.js rename to devtools/test_dashboard/devtools.js index a4cd1bd8386..c68e39f5eb9 100644 --- a/devtools/test_dashboard_v2/devtools.js +++ b/devtools/test_dashboard/devtools.js @@ -1,11 +1,17 @@ +var Fuse = require('fuse.js'); +var mocks = require('./mocks.json'); + + // Our gracious testing object var Tabs = { + // Return the specified plot container (or default one) getGraph: function(id) { id = id || 'graph'; return document.getElementById(id); }, + // Create a new plot container fresh: function(id) { id = id || 'graph'; @@ -25,14 +31,18 @@ var Tabs = { return graphDiv; }, + // Plot a mock by name (without .json) to the default or specified container plotMock: function(mockName, id) { var mockURL = '/test/image/mocks/' + mockName + '.json'; window.Plotly.d3.json(mockURL, function(err, fig) { window.Plotly.plot(Tabs.fresh(id), fig.data, fig.layout); + + console.warn('Plotting:', mockURL); }); }, + // Save a png snapshot and display it below the plot snapshot: function(id) { var gd = Tabs.getGraph(id); @@ -52,9 +62,10 @@ var Tabs = { }); }, + // Remove all plots and snapshots from the page purge: function() { var plots = document.getElementsByClassName('dashboard-plot'); - var images = document.getElementsById('snapshot'); + var images = document.getElementById('snapshot'); while(images.firstChild) { images.removeChild(images.firstChild); @@ -65,10 +76,12 @@ var Tabs = { } }, + // Specify what to do after each plotly.js script reload onReload: function() { return; }, + // Refreshes the plotly.js source without needing to refresh the page reload: function() { var source = document.getElementById('source'); var reloaded = document.getElementById('reload-time'); @@ -92,6 +105,8 @@ var Tabs = { }; +// Bind things to the window +window.Tabs = Tabs; setInterval(function() { window.gd = Tabs.getGraph() || Tabs.fresh(); window.fullLayout = window.gd._fullLayout; @@ -100,10 +115,19 @@ setInterval(function() { // Mocks search and plotting -var f = new window.Fuse(window.MOCKS, { keys: ['name'] }); +var f = new Fuse(mocks, { + keys: [{ + name: 'name', + weight: 0.7 + }, { + name: 'keywords', + weight: 0.3 + }] +}); var searchBar = document.getElementById('mocks-search'); var mocksList = document.getElementById('mocks-list'); + searchBar.addEventListener('keyup', function(e) { // Clear results. @@ -120,10 +144,10 @@ searchBar.addEventListener('keyup', function(e) { result.innerText = r.name; result.addEventListener('click', function() { + // Clear plots and plot selected. Tabs.purge(); Tabs.plotMock(r.file.slice(0, -5)); - console.warn('Plotting:', r.file); // Clear results. while(mocksList.firstChild) { diff --git a/devtools/test_dashboard/index.html b/devtools/test_dashboard/index.html index 20410f98f7b..1972b481951 100644 --- a/devtools/test_dashboard/index.html +++ b/devtools/test_dashboard/index.html @@ -1,53 +1,25 @@ + - + Plotly.js Devtools + +
+ + -
-
-
-
+ +
- - - - - - - - - - - - +
+
+
+
+
+ + + diff --git a/devtools/test_dashboard/server.js b/devtools/test_dashboard/server.js index 98d5aeb4c3a..202fdb5259b 100644 --- a/devtools/test_dashboard/server.js +++ b/devtools/test_dashboard/server.js @@ -1,56 +1,161 @@ var fs = require('fs'); -var http = require('http'); var path = require('path'); - -var browserify = require('browserify'); +var http = require('http'); var ecstatic = require('ecstatic'); -var _open = require('open'); +var open = require('open'); +var browserify = require('browserify'); +var watchify = require('watchify'); -var makeWatchifiedBundle = require('../../tasks/util/make_watchified_bundle'); -var shortcutPaths = require('../../tasks/util/shortcut_paths'); var constants = require('../../tasks/util/constants'); +var compress = require('../../tasks/util/compress_attributes'); +var PORT = process.argv[2] || 3000; -// TODO make this an optional argument -var PORT = '8080'; -var testFile; -switch(process.argv[2]) { - case 'cartesian': - testFile = 'test_cartesian'; - break; - case 'geo': - testFile = 'test_geo'; - break; - case 'gl3d': - testFile = 'test_gl3d'; - break; - default: - testFile = 'test_gl2d'; -} - -console.log('Using ' + testFile); -console.log('Listening on :' + PORT + '\n'); +// Create server +var server = http.createServer(ecstatic({ + root: constants.pathToRoot, + cache: 0, + gzip: true +})); -// watch plotly.js -var watchifiedBundle = makeWatchifiedBundle(function onFirstBundleCallback() { - _open('http://localhost:' + PORT + '/devtools/test_dashboard'); +// Bundle development source code +var b = browserify(constants.pathToPlotlyIndex, { + debug: true, + standalone: 'Plotly', + transform: [compress], + cache: {}, + packageCache: {}, + plugin: [watchify] }); -watchifiedBundle(); - -// build the test examples -fs.unlink(constants.pathToTestDashboardBundle, function() { - browserify(path.join(__dirname, testFile), { - debug: true, - transform: [shortcutPaths] - }) - .bundle(function(err) { - if(err) throw err; - }) - .pipe(fs.createWriteStream(constants.pathToTestDashboardBundle)); +b.on('update', bundleDevtools); + +// Bundle devtools code +var devtoolsPath = path.join(constants.pathToRoot, 'devtools/test_dashboard'); +var devtools = browserify(path.join(devtoolsPath, 'devtools.js'), { + transform: [compress] }); -// boot up server -http.createServer( - ecstatic({ root: constants.pathToRoot }) -).listen(PORT); +var firstBundle = true; + + +// Start the server up! +server.listen(PORT); + +// Build and bundle all the things! +console.log('Building the first bundle. This might take a little while...\n'); +getMockFiles() + .then(readFiles) + .then(createMocksList) + .then(saveToFile) + .then(bundleDevtools) + .then(bundlePlotly); + + +function getMockFiles() { + return new Promise(function(resolve, reject) { + fs.readdir(constants.pathToTestImageMocks, function(err, files) { + if(err) { + reject(err); + } else { + resolve(files); + } + }); + }); +} + +function readFiles(files) { + var promises = files.map(function(file) { + var filePath = path.join(constants.pathToTestImageMocks, file); + return readFilePromise(filePath); + }); + + return Promise.all(promises); +} + +function createMocksList(files) { + var mocksList = files.map(function(file, i) { + var contents = JSON.parse(file.contents); + + // get plot type keywords from mocks + var types = contents.data.map(function(trace) { + return trace.type || 'scatter'; + }).reduce(function(acc, type, i, arr) { + if(arr.lastIndexOf(type) === i) { + acc.push(type); + } + return acc; + }, []); + + var filename = file.name.split('/').pop(); + + return { + name: filename.slice(0, -5), + file: filename, + keywords: types.join(', ') + }; + }); + + return mocksList; +} + +function saveToFile(mocksList) { + var filePath = path.join(constants.pathToRoot, 'devtools/test_dashboard/mocks.json'); + var content = JSON.stringify(mocksList, null, 4); + + return writeFilePromise(filePath, content); +} + +function readFilePromise(file) { + return new Promise(function(resolve, reject) { + fs.readFile(file, { encoding: 'utf-8' }, function(err, contents) { + if(err) { + reject(err); + } else { + resolve({ + name: file, + contents: contents + }); + } + }); + }); +} + +function writeFilePromise(path, contents) { + return new Promise(function(resolve, reject) { + fs.writeFile(path, contents, function(err) { + if(err) { + reject(err); + } else { + resolve(path); + } + }); + }); +} + +function bundlePlotly() { + b.bundle(function(err) { + if(err) { + console.error('Error while bundling!', err); + } + + if(firstBundle) { + open('http://localhost:' + PORT + '/devtools/test_dashboard'); + firstBundle = false; + } + console.log('Bundle updated at ' + new Date().toLocaleTimeString()); + }).pipe(fs.createWriteStream(constants.pathToPlotlyBuild)); +} + +function bundleDevtools() { + return new Promise(function(resolve, reject) { + devtools.bundle(function(err) { + if(err) { + console.error('Error while bundling!', err); + return reject(err); + } else { + return resolve(); + } + }).pipe(fs.createWriteStream(constants.pathToTestDashboardBundle)); + }); +} diff --git a/devtools/test_dashboard/style.css b/devtools/test_dashboard/style.css new file mode 100644 index 00000000000..71e49dcda70 --- /dev/null +++ b/devtools/test_dashboard/style.css @@ -0,0 +1,54 @@ +html, body{ + margin: 0; + padding: 0; + font-family: helvetica, arial, sans-serif; +} +header{ + height: 40px; + border-bottom: 1px solid #4983EC; +} +header img{ + height: 100%; + display: inline-block; + vertical-align: top; +} +header input{ + float: right; + background-color: none; + border: none; + border-bottom: 1px solid #ddd; + padding: 5px; + outline: none; + margin-top: 6px; + margin-right: 10px; +} +header span{ + color: #bbb; + font-size: 10px; + line-height: 40px; +} +#mocks-list{ + position: absolute; + right: 0px; + top: 40px; + z-index: 100000; + background-color: #fff; + border-left: 1px solid #4983EC; + border-bottom: 1px solid #4983EC; + border-top: 1px solid #4983EC; +} +.search-result{ + display: block; + margin-bottom: 2px; + padding: 5px 10px; + text-align: right; + font-size: 12px; +} +.search-result:hover{ + color: #fff; + background-color: #4983EC; +} +.dashboard-plot{ + margin-bottom: 30px; + max-width: 940px; +} diff --git a/devtools/test_dashboard/test_cartesian.js b/devtools/test_dashboard/test_cartesian.js deleted file mode 100644 index ec01fc98bb3..00000000000 --- a/devtools/test_dashboard/test_cartesian.js +++ /dev/null @@ -1,48 +0,0 @@ -/*eslint dot-notation: 0*/ - -var plotButtons = require('./buttons'); - -var figDir = '../../test/image/baselines/'; - -var plots = {}; - -plots['10'] = require('@mocks/10.json'); -plots['14'] = require('@mocks/14.json'); -plots['12'] = require('@mocks/12.json'); -plots['17'] = require('@mocks/17.json'); -plots['22'] = require('@mocks/22.json'); -plots['24'] = require('@mocks/24.json'); -plots['28'] = require('@mocks/28.json'); -plots['30'] = require('@mocks/30.json'); -plots['32'] = require('@mocks/32.json'); -plots['axes_booleans'] = require('@mocks/axes_booleans.json'); -plots['axes_labels'] = require('@mocks/axes_labels.json'); -plots['axes_lines'] = require('@mocks/axes_lines.json'); -plots['axes_range_manual'] = require('@mocks/axes_range_manual.json'); -plots['axes_range_type'] = require('@mocks/axes_range_type.json'); -plots['axes_range_mode'] = require('@mocks/axes_range_mode.json'); -plots['basic_error_bar'] = require('@mocks/basic_error_bar.json'); -plots['bubble_markersize0'] = require('@mocks/bubble_markersize0.json'); -plots['bubble_nonnumeric-sizes'] = require('@mocks/bubble_nonnumeric-sizes.json'); -plots['date_axes'] = require('@mocks/date_axes.json'); -plots['error_bar_asymmetric_array'] = require('@mocks/error_bar_asymmetric_array.json'); -plots['error_bar_asymmetric_constant'] = require('@mocks/error_bar_asymmetric_constant.json'); -plots['error_bar_horizontal'] = require('@mocks/error_bar_horizontal.json'); -plots['error_bar_style'] = require('@mocks/error_bar_style.json'); -plots['fonts'] = require('@mocks/fonts.json'); -plots['global_font'] = require('@mocks/global_font.json'); -plots['legend_inside'] = require('@mocks/legend_inside.json'); -plots['legend_labels'] = require('@mocks/legend_labels.json'); -plots['legend_outside'] = require('@mocks/legend_outside.json'); -plots['legend_style'] = require('@mocks/legend_style.json'); -plots['line_style'] = require('@mocks/line_style.json'); -plots['multiple_subplots'] = require('@mocks/multiple_subplots.json'); -plots['scatter-colorscale-colorbar'] = require('@mocks/scatter-colorscale-colorbar.json'); -plots['scatter-marker-line-colorscales'] = require('@mocks/scatter-marker-line-colorscales.json'); -plots['show_legend'] = require('@mocks/show_legend.json'); -plots['simple_inset'] = require('@mocks/simple_inset.json'); -plots['size_margins'] = require('@mocks/size_margins.json'); -plots['stacked_coupled_subplots'] = require('@mocks/stacked_coupled_subplots.json'); -plots['stacked_subplots'] = require('@mocks/stacked_subplots.json'); - -plotButtons(plots, figDir); diff --git a/devtools/test_dashboard/test_geo.js b/devtools/test_dashboard/test_geo.js deleted file mode 100644 index a9e3bd7075c..00000000000 --- a/devtools/test_dashboard/test_geo.js +++ /dev/null @@ -1,28 +0,0 @@ -/*eslint dot-notation: 0*/ - -var plotButtons = require('./buttons'); - -var figDir = '../../test/image/baselines/geo_'; - -var plots = {}; - -plots['first'] = require('@mocks/geo_first.json'); -plots['second'] = require('@mocks/geo_second.json'); -plots['kavrayskiy7'] = require('@mocks/geo_kavrayskiy7.json'); -plots['custom-colorscale'] = require('@mocks/geo_custom-colorscale.json'); -plots['scattergeo-locations'] = require('@mocks/geo_scattergeo-locations.json'); -plots['multi-geos'] = require('@mocks/geo_multi-geos.json'); -plots['usa-states'] = require('@mocks/geo_usa-states.json'); -plots['legendonly'] = require('@mocks/geo_legendonly.json'); -plots['europe-bubbles'] = require('@mocks/geo_europe-bubbles.json'); -plots['orthographic'] = require('@mocks/geo_orthographic.json'); -plots['big-frame'] = require('@mocks/geo_big-frame.json'); -plots['bg-color'] = require('@mocks/geo_bg-color.json'); -plots['canadian-cites'] = require('@mocks/geo_canadian-cites.json'); -plots['conic-conformal'] = require('@mocks/geo_conic-conformal.json'); -plots['stereographic'] = require('@mocks/geo_stereographic.json'); -plots['choropleth-text'] = require('@mocks/geo_choropleth-text.json'); -plots['choropleth-usa'] = require('@mocks/geo_choropleth-usa.json'); -plots['country-names'] = require('@mocks/geo_country-names.json'); - -plotButtons(plots, figDir); diff --git a/devtools/test_dashboard/test_gl2d.js b/devtools/test_dashboard/test_gl2d.js deleted file mode 100644 index d0e8f8a1501..00000000000 --- a/devtools/test_dashboard/test_gl2d.js +++ /dev/null @@ -1,48 +0,0 @@ -/*eslint dot-notation: 0*/ - -var plotButtons = require('./buttons'); - -var figDir = '../../test/image/baselines/gl2d_'; - -var plots = {}; - -plots['10'] = require('@mocks/gl2d_10.json'); -plots['14'] = require('@mocks/gl2d_14.json'); -plots['12'] = require('@mocks/gl2d_12.json'); -plots['17'] = require('@mocks/gl2d_17.json'); -plots['22'] = require('@mocks/gl2d_22.json'); -plots['24'] = require('@mocks/gl2d_24.json'); -plots['28'] = require('@mocks/gl2d_28.json'); -plots['30'] = require('@mocks/gl2d_30.json'); -plots['32'] = require('@mocks/gl2d_32.json'); -plots['axes_booleans'] = require('@mocks/gl2d_axes_booleans.json'); -plots['axes_labels'] = require('@mocks/gl2d_axes_labels.json'); -plots['axes_lines'] = require('@mocks/gl2d_axes_lines.json'); -plots['axes_range_manual'] = require('@mocks/gl2d_axes_range_manual.json'); -plots['axes_range_type'] = require('@mocks/gl2d_axes_range_type.json'); -plots['axes_range_mode'] = require('@mocks/gl2d_axes_range_mode.json'); -plots['basic_error_bar'] = require('@mocks/gl2d_basic_error_bar.json'); -plots['bubble_markersize0'] = require('@mocks/gl2d_bubble_markersize0.json'); -plots['bubble_nonnumeric-sizes'] = require('@mocks/gl2d_bubble_nonnumeric-sizes.json'); -plots['date_axes'] = require('@mocks/gl2d_date_axes.json'); -plots['error_bar_asymmetric_array'] = require('@mocks/gl2d_error_bar_asymmetric_array.json'); -plots['error_bar_asymmetric_constant'] = require('@mocks/gl2d_error_bar_asymmetric_constant.json'); -plots['error_bar_horizontal'] = require('@mocks/gl2d_error_bar_horizontal.json'); -plots['error_bar_style'] = require('@mocks/gl2d_error_bar_style.json'); -plots['fonts'] = require('@mocks/gl2d_fonts.json'); -plots['global_font'] = require('@mocks/gl2d_global_font.json'); -plots['legend_inside'] = require('@mocks/gl2d_legend_inside.json'); -plots['legend_labels'] = require('@mocks/gl2d_legend_labels.json'); -plots['legend_outside'] = require('@mocks/gl2d_legend_outside.json'); -plots['legend_style'] = require('@mocks/gl2d_legend_style.json'); -plots['line_style'] = require('@mocks/gl2d_line_style.json'); -plots['multiple_subplots'] = require('@mocks/gl2d_multiple_subplots.json'); -plots['scatter-colorscale-colorbar'] = require('@mocks/gl2d_scatter-colorscale-colorbar.json'); -plots['scatter-marker-line-colorscales'] = require('@mocks/gl2d_scatter-marker-line-colorscales.json'); -plots['show_legend'] = require('@mocks/gl2d_show_legend.json'); -plots['simple_inset'] = require('@mocks/gl2d_simple_inset.json'); -plots['size_margins'] = require('@mocks/gl2d_size_margins.json'); -plots['stacked_coupled_subplots'] = require('@mocks/gl2d_stacked_coupled_subplots.json'); -plots['stacked_subplots'] = require('@mocks/gl2d_stacked_subplots.json'); - -plotButtons(plots, figDir); diff --git a/devtools/test_dashboard/test_gl3d.js b/devtools/test_dashboard/test_gl3d.js deleted file mode 100644 index 7ae784ad2ea..00000000000 --- a/devtools/test_dashboard/test_gl3d.js +++ /dev/null @@ -1,42 +0,0 @@ -/*eslint dot-notation: 0*/ - -var plotButtons = require('./buttons'); - -var figDir = '../../test/image/baselines/gl3d_'; - -var plots = {}; - -plots['bunny-hull'] = require('@mocks/gl3d_bunny-hull.json'); -plots['ibm-plot'] = require('@mocks/gl3d_ibm-plot.json'); -plots['marker-color'] = require('@mocks/gl3d_marker-color.json'); -plots['log-axis-big'] = require('@mocks/gl3d_log-axis-big.json'); -plots['delaunay'] = require('@mocks/gl3d_delaunay.json'); -plots['log-axis'] = require('@mocks/gl3d_log-axis.json'); -plots['multi-scene'] = require('@mocks/gl3d_multi-scene.json'); -plots['surface-lighting'] = require('@mocks/gl3d_surface-lighting.json'); -plots['z-range'] = require('@mocks/gl3d_z-range.json'); -plots['mirror-ticks'] = require('@mocks/gl3d_mirror-ticks.json'); -plots['autorange-zero'] = require('@mocks/gl3d_autorange-zero.json'); -plots['contour-lines'] = require('@mocks/gl3d_contour-lines.json'); -plots['xy-defined-ticks'] = require('@mocks/gl3d_xy-defined-ticks.json'); -plots['opacity-surface'] = require('@mocks/gl3d_opacity-surface.json'); -plots['projection-traces'] = require('@mocks/gl3d_projection-traces.json'); -plots['opacity-scaling-spikes'] = require('@mocks/gl3d_opacity-scaling-spikes.json'); -plots['text-weirdness'] = require('@mocks/gl3d_text-weirdness.json'); -plots['wire-surface'] = require('@mocks/gl3d_wire-surface.json'); -plots['triangle'] = require('@mocks/gl3d_triangle.json'); -plots['snowden'] = require('@mocks/gl3d_snowden.json'); -plots['bunny'] = require('@mocks/gl3d_bunny.json'); -plots['ribbons'] = require('@mocks/gl3d_ribbons.json'); -plots['scatter-date'] = require('@mocks/gl3d_scatter-date.json'); -plots['cufflinks'] = require('@mocks/gl3d_cufflinks.json'); -plots['chrisp-nan-1'] = require('@mocks/gl3d_chrisp-nan-1.json'); -plots['marker-arrays'] = require('@mocks/gl3d_marker-arrays.json'); -plots['scatter3d-colorscale'] = require('@mocks/gl3d_scatter3d-colorscale.json'); -plots['autocolorscale'] = require('@mocks/gl3d_autocolorscale.json'); -plots['nan-holes'] = require('@mocks/gl3d_nan-holes.json'); -plots['scatter3d-connectgaps'] = require('@mocks/gl3d_scatter3d-connectgaps.json'); -plots['tet'] = require('@mocks/gl3d_tet.json'); -plots['surface_intensity'] = require('@mocks/gl3d_surface_intensity.json'); - -plotButtons(plots, figDir); diff --git a/devtools/test_dashboard_v2/fuse.min.js b/devtools/test_dashboard_v2/fuse.min.js deleted file mode 100644 index 6978762f599..00000000000 --- a/devtools/test_dashboard_v2/fuse.min.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @license - * Fuse - Lightweight fuzzy-search - * - * Copyright (c) 2012-2016 Kirollos Risk . - * All Rights Reserved. Apache Software License 2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License") - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -!function(t){"use strict";function e(){console.log.apply(console,arguments)}function s(t,e){var s,n,i,o;for(this.list=t,this.options=e=e||{},s=0,o=["sort","shouldSort","verbose","tokenize"],n=o.length;n>s;s++)i=o[s],this.options[i]=i in e?e[i]:h[i];for(s=0,o=["searchFn","sortFn","keys","getFn","include"],n=o.length;n>s;s++)i=o[s],this.options[i]=e[i]||h[i]}function n(t,e,s){var o,r,h,a,c,p;if(e){if(h=e.indexOf("."),-1!==h?(o=e.slice(0,h),r=e.slice(h+1)):o=e,a=t[o],null!==a&&void 0!==a)if(r||"string"!=typeof a&&"number"!=typeof a)if(i(a))for(c=0,p=a.length;p>c;c++)n(a[c],r,s);else r&&n(a,r,s);else s.push(a)}else s.push(t);return s}function i(t){return"[object Array]"===Object.prototype.toString.call(t)}function o(t,e){e=e||{},this.options=e,this.options.location=e.location||o.defaultOptions.location,this.options.distance="distance"in e?e.distance:o.defaultOptions.distance,this.options.threshold="threshold"in e?e.threshold:o.defaultOptions.threshold,this.options.maxPatternLength=e.maxPatternLength||o.defaultOptions.maxPatternLength,this.pattern=e.caseSensitive?t:t.toLowerCase(),this.patternLen=t.length,this.patternLen<=this.options.maxPatternLength&&(this.matchmask=1<i;i++)this.tokenSearchers.push(new s(n[i],t));this.fullSeacher=new s(e,t)},s.prototype._startSearch=function(){var t,e,s,n,i=this.options,o=i.getFn,r=this.list,h=r.length,a=this.options.keys,c=a.length,p=null;if("string"==typeof r[0])for(s=0;h>s;s++)this._analyze("",r[s],s,s);else for(this._keyMap={},s=0;h>s;s++)for(p=r[s],n=0;c>n;n++){if(t=a[n],"string"!=typeof t){if(e=1-t.weight||1,this._keyMap[t.name]={weight:e},t.weight<=0||t.weight>1)throw new Error("Key weight has to be > 0 and <= 1");t=t.name}else this._keyMap[t]={weight:1};this._analyze(t,o(p,t,[]),p,s)}},s.prototype._analyze=function(t,s,n,o){var h,a,c,p,l,u,f,d,g,m,y,v,b,S,k,_=this.options,M=!1;if(void 0!==s&&null!==s)if(a=[],"string"==typeof s){if(h=s.split(r),_.verbose&&e("---------\nKey:",t),_.verbose&&e("Record:",h),this.options.tokenize){for(c=this.tokenSearchers,p=c.length,S=0;SS;S++)u+=a[S];u/=d,_.verbose&&e("Token score average:",u)}g=this.fullSeacher.search(s),_.verbose&&e("Full text score:",g.score),f=g.score,void 0!==u&&(f=(f+u)/2),_.verbose&&e("Score average:",f),(M||g.isMatch)&&(l=this.resultMap[o],l?l.output.push({key:t,score:f,matchedIndices:g.matchedIndices}):(this.resultMap[o]={item:n,output:[{key:t,score:f,matchedIndices:g.matchedIndices}]},this.results.push(this.resultMap[o])))}else if(i(s))for(S=0;Ss;s++)r=i[s].score,h=p?p[i[s].key].weight:1,c=r*h,1!==h?a=Math.min(a,c):(n+=c,i[s].nScore=c);1===a?l[t].score=n/o:l[t].score=a,this.options.verbose&&e(l[t])}},s.prototype._sort=function(){var t=this.options;t.shouldSort&&(t.verbose&&e("\n\nSorting...."),this.results.sort(t.sortFn))},s.prototype._format=function(){var t,s,n,i,o,r=this.options,h=r.getFn,a=[],c=this.results,p=r.include;for(r.verbose&&e("\n\nOutput:\n\n",c),i=r.id?function(t){c[t].item=h(c[t].item,r.id,[])[0]}:function(){},o=function(t){var e,s,n,i,o,r=c[t];if(p.length>0){if(e={item:r.item},-1!==p.indexOf("matches"))for(n=r.output,e.matches=[],s=0;ss;s++)i(s),t=o(s),a.push(t);return a},o.defaultOptions={location:0,distance:100,threshold:.6,maxPatternLength:32},o.prototype._calculatePatternAlphabet=function(){var t={},e=0;for(e=0;eL.maxPatternLength){if(v=t.match(new RegExp(this.pattern.replace(r,"|"))),b=!!v)for(k=[],e=0,_=v.length;_>e;e++)M=v[e],k.push([t.indexOf(M),M.length-1]);return{isMatch:b,score:b?.5:1,matchedIndices:k}}for(i=L.location,n=t.length,o=L.threshold,h=t.indexOf(this.pattern,i),S=[],e=0;n>e;e++)S[e]=0;for(-1!=h&&(o=Math.min(this._bitapScore(0,h),o),h=t.lastIndexOf(this.pattern,i+this.patternLen),-1!=h&&(o=Math.min(this._bitapScore(0,h),o))),h=-1,m=1,y=[],p=this.patternLen+n,e=0;ea;)this._bitapScore(e,i+c)<=o?a=c:p=c,c=Math.floor((p-a)/2+a);for(p=c,l=Math.max(1,i-c+1),u=Math.min(i+c,n)+this.patternLen,f=Array(u+2),f[u+1]=(1<=l;s--)if(g=this.patternAlphabet[t.charAt(s-1)],g&&(S[s-1]=1),0===e?f[s]=(f[s+1]<<1|1)&g:f[s]=(f[s+1]<<1|1)&g|((d[s+1]|d[s])<<1|1)|d[s+1],f[s]&this.matchmask&&(m=this._bitapScore(e,s-1),o>=m)){if(o=m,h=s-1,y.push(h),!(h>i))break;l=Math.max(1,2*i-h)}if(this._bitapScore(e+1,i)>o)break;d=f}return k=this._getMatchedIndices(S),{isMatch:h>=0,score:0===m?.001:m,matchedIndices:k}},o.prototype._getMatchedIndices=function(t){for(var e,s=[],n=-1,i=-1,o=0,r=r=t.length;r>o;o++)e=t[o],e&&-1===n?n=o:e||-1===n||(i=o-1,s.push([n,i]),n=-1);return t[o-1]&&s.push([n,o-1]),s},"object"==typeof exports?module.exports=s:"function"==typeof define&&define.amd?define(function(){return s}):t.Fuse=s}(this); \ No newline at end of file diff --git a/devtools/test_dashboard_v2/index.html b/devtools/test_dashboard_v2/index.html deleted file mode 100644 index 166b573bb6a..00000000000 --- a/devtools/test_dashboard_v2/index.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - Plotly.js Devtools - - - -
- - - - -
- -
-
-
-
-
- - - - - - - - diff --git a/devtools/test_dashboard_v2/mocks.js b/devtools/test_dashboard_v2/mocks.js deleted file mode 100644 index 87a2de9087f..00000000000 --- a/devtools/test_dashboard_v2/mocks.js +++ /dev/null @@ -1,135 +0,0 @@ -var MOCKS = [ - // Cartesian - { name: 'cartesian - 10', file: '10.json' }, - { name: 'cartesian - 14', file: '14.json' }, - { name: 'cartesian - 12', file: '12.json' }, - { name: 'cartesian - 17', file: '17.json' }, - { name: 'cartesian - 22', file: '22.json' }, - { name: 'cartesian - 24', file: '24.json' }, - { name: 'cartesian - 28', file: '28.json' }, - { name: 'cartesian - 30', file: '30.json' }, - { name: 'cartesian - 32', file: '32.json' }, - { name: 'cartesian - axes booleans', file: 'axes_booleans.json' }, - { name: 'cartesian - axes labels', file: 'axes_labels.json' }, - { name: 'cartesian - axes lines', file: 'axes_lines.json' }, - { name: 'cartesian - axes range manual', file: 'axes_range_manual.json' }, - { name: 'cartesian - axes range type', file: 'axes_range_type.json' }, - { name: 'cartesian - axes range mode', file: 'axes_range_mode.json' }, - { name: 'cartesian - basic error bar', file: 'basic_error_bar.json' }, - { name: 'cartesian - bubble markersize', file: 'bubble_markersize0.json' }, - { name: 'cartesian - bubble nonnumeric sizes', file: 'bubble_nonnumeric-sizes.json' }, - { name: 'cartesian - date axes', file: 'date_axes.json' }, - { name: 'cartesian - error bar asymmetric array', file: 'error_bar_asymmetric_array.json' }, - { name: 'cartesian - error bar asymmetric constant', file: 'error_bar_asymmetric_constant.json' }, - { name: 'cartesian - error bar horizontal', file: 'error_bar_horizontal.json' }, - { name: 'cartesian - error bar style', file: 'error_bar_style.json' }, - { name: 'cartesian - fonts', file: 'fonts.json' }, - { name: 'cartesian - global font', file: 'global_font.json' }, - { name: 'cartesian - legend inside', file: 'legend_inside.json' }, - { name: 'cartesian - legend labels', file: 'legend_labels.json' }, - { name: 'cartesian - legend outside', file: 'legend_outside.json' }, - { name: 'cartesian - legend style', file: 'legend_style.json' }, - { name: 'cartesian - line style', file: 'line_style.json' }, - { name: 'cartesian - multiple subplots', file: 'multiple_subplots.json' }, - { name: 'cartesian - scatter colorscale colorbar', file: 'scatter-colorscale-colorbar.json' }, - { name: 'cartesian - scatter marker line colorscales', 'file': 'scatter-marker-line-colorscales.json' }, - { name: 'cartesian - show legend', file: 'show_legend.json' }, - { name: 'cartesian - simple inset', file: 'simple_inset.json' }, - { name: 'cartesian - size margins', file: 'size_margins.json' }, - { name: 'cartesian - stacked coupled subplots', file: 'stacked_coupled_subplots.json' }, - { name: 'cartesian - stacked subplots', file: 'stacked_subplots.json' }, - - // Geo - { name: 'geo - first', file: 'geo_first.json' }, - { name: 'geo - second', file: 'geo_second.json' }, - { name: 'geo - kavrayskiy7', file: 'geo_kavrayskiy7.json' }, - { name: 'geo - custom colorscale', file: 'geo_custom-colorscale.json' }, - { name: 'geo - scattergeo locations', file: 'geo_scattergeo-locations.json' }, - { name: 'geo - multi geos', file: 'geo_multi-geos.json' }, - { name: 'geo - usa states', file: 'geo_usa-states.json' }, - { name: 'geo - legend only', file: 'geo_legendonly.json' }, - { name: 'geo - europe bubbles', file: 'geo_europe-bubbles.json' }, - { name: 'geo - orthographic', file: 'geo_orthographic.json' }, - { name: 'geo - big frame', file: 'geo_big-frame.json' }, - { name: 'geo - background color', file: 'geo_bg-color.json' }, - { name: 'geo - canadian cities', file: 'geo_canadian-cites.json' }, - { name: 'geo - conic conformal', file: 'geo_conic-conformal.json' }, - { name: 'geo - stereograpic', file: 'geo_stereographic.json' }, - { name: 'geo - choropleth text', file: 'geo_choropleth-text.json' }, - { name: 'geo - choropleth usa', file: 'geo_choropleth-usa.json' }, - { name: 'geo - country names', file: 'geo_country-names.json' }, - - // gl2d - { name: 'gl2d - 10', file: 'gl2d_10.json' }, - { name: 'gl2d - 14', file: 'gl2d_14.json' }, - { name: 'gl2d - 12', file: 'gl2d_12.json' }, - { name: 'gl2d - 17', file: 'gl2d_17.json' }, - { name: 'gl2d - 22', file: 'gl2d_22.json' }, - { name: 'gl2d - 24', file: 'gl2d_24.json' }, - { name: 'gl2d - 28', file: 'gl2d_28.json' }, - { name: 'gl2d - 30', file: 'gl2d_30.json' }, - { name: 'gl2d - 32', file: 'gl2d_32.json' }, - { name: 'gl2d - axes booleans', file: 'gl2d_axes_booleans.json' }, - { name: 'gl2d - axes labels', file: 'gl2d_axes_labels.json' }, - { name: 'gl2d - axes lines', file: 'gl2d_axes_lines.json' }, - { name: 'gl2d - axes range_manual', file: 'gl2d_axes_range_manual.json' }, - { name: 'gl2d - axes range_type', file: 'gl2d_axes_range_type.json' }, - { name: 'gl2d - axes range_mode', file: 'gl2d_axes_range_mode.json' }, - { name: 'gl2d - basic error_bar', file: 'gl2d_basic_error_bar.json' }, - { name: 'gl2d - bubble markersize0', file: 'gl2d_bubble_markersize0.json' }, - { name: 'gl2d - bubble nonnumeric-sizes', file: 'gl2d_bubble_nonnumeric-sizes.json' }, - { name: 'gl2d - date axes', file: 'gl2d_date_axes.json' }, - { name: 'gl2d - error bar asymmetric array', file: 'gl2d_error_bar_asymmetric_array.json' }, - { name: 'gl2d - error bar asymmetric constant', file: 'gl2d_error_bar_asymmetric_constant.json' }, - { name: 'gl2d - error bar horizontal', file: 'gl2d_error_bar_horizontal.json' }, - { name: 'gl2d - error bar style', file: 'gl2d_error_bar_style.json' }, - { name: 'gl2d - fonts', file: 'gl2d_fonts.json' }, - { name: 'gl2d - global font', file: 'gl2d_global_font.json' }, - { name: 'gl2d - legend inside', file: 'gl2d_legend_inside.json' }, - { name: 'gl2d - legend labels', file: 'gl2d_legend_labels.json' }, - { name: 'gl2d - legend outside', file: 'gl2d_legend_outside.json' }, - { name: 'gl2d - legend style', file: 'gl2d_legend_style.json' }, - { name: 'gl2d - line style', file: 'gl2d_line_style.json' }, - { name: 'gl2d - multiple subplots', file: 'gl2d_multiple_subplots.json' }, - { name: 'gl2d - scatter colorscale colorbar', file: 'gl2d_scatter-colorscale-colorbar.json' }, - { name: 'gl2d - scatter marker line colorscales', file: 'gl2d_scatter-marker-line-colorscales.json' }, - { name: 'gl2d - show legend', file: 'gl2d_show_legend.json' }, - { name: 'gl2d - simple inset', file: 'gl2d_simple_inset.json' }, - { name: 'gl2d - size margins', file: 'gl2d_size_margins.json' }, - { name: 'gl2d - stacked coupled_subplots', file: 'gl2d_stacked_coupled_subplots.json' }, - { name: 'gl2d - stacked subplots', file: 'gl2d_stacked_subplots.json' }, - - // gl3d - { name: 'gl3d - bunny-hull', file: 'gl3d_bunny-hull.json' }, - { name: 'gl3d - ibm-plot', file: 'gl3d_ibm-plot.json' }, - { name: 'gl3d - marker-color', file: 'gl3d_marker-color.json' }, - { name: 'gl3d - log-axis-big', file: 'gl3d_log-axis-big.json' }, - { name: 'gl3d - delaunay', file: 'gl3d_delaunay.json' }, - { name: 'gl3d - log-axis', file: 'gl3d_log-axis.json' }, - { name: 'gl3d - multi-scene', file: 'gl3d_multi-scene.json' }, - { name: 'gl3d - surface-lighting', file: 'gl3d_surface-lighting.json' }, - { name: 'gl3d - z-range', file: 'gl3d_z-range.json' }, - { name: 'gl3d - mirror-ticks', file: 'gl3d_mirror-ticks.json' }, - { name: 'gl3d - autorange-zero', file: 'gl3d_autorange-zero.json' }, - { name: 'gl3d - contour-lines', file: 'gl3d_contour-lines.json' }, - { name: 'gl3d - xy-defined-ticks', file: 'gl3d_xy-defined-ticks.json' }, - { name: 'gl3d - opacity-surface', file: 'gl3d_opacity-surface.json' }, - { name: 'gl3d - projection-traces', file: 'gl3d_projection-traces.json' }, - { name: 'gl3d - opacity-scaling-spikes', file: 'gl3d_opacity-scaling-spikes.json' }, - { name: 'gl3d - text-weirdness', file: 'gl3d_text-weirdness.json' }, - { name: 'gl3d - wire-surface', file: 'gl3d_wire-surface.json' }, - { name: 'gl3d - triangle', file: 'gl3d_triangle.json' }, - { name: 'gl3d - snowden', file: 'gl3d_snowden.json' }, - { name: 'gl3d - bunny', file: 'gl3d_bunny.json' }, - { name: 'gl3d - ribbons', file: 'gl3d_ribbons.json' }, - { name: 'gl3d - scatter-date', file: 'gl3d_scatter-date.json' }, - { name: 'gl3d - cufflinks', file: 'gl3d_cufflinks.json' }, - { name: 'gl3d - chrisp-nan-1', file: 'gl3d_chrisp-nan-1.json' }, - { name: 'gl3d - marker-arrays', file: 'gl3d_marker-arrays.json' }, - { name: 'gl3d - scatter3d-colorscale', file: 'gl3d_scatter3d-colorscale.json' }, - { name: 'gl3d - autocolorscale', file: 'gl3d_autocolorscale.json' }, - { name: 'gl3d - nan-holes', file: 'gl3d_nan-holes.json' }, - { name: 'gl3d - scatter3d-connectgaps', file: 'gl3d_scatter3d-connectgaps.json' }, - { name: 'gl3d - tet', file: 'gl3d_tet.json' }, - { name: 'gl3d - surface_intensity', file: 'gl3d_surface_intensity.json' } -]; diff --git a/devtools/test_dashboard_v2/server.js b/devtools/test_dashboard_v2/server.js deleted file mode 100644 index 82e5e09d9a2..00000000000 --- a/devtools/test_dashboard_v2/server.js +++ /dev/null @@ -1,49 +0,0 @@ -var fs = require('fs'); -var http = require('http'); -var ecstatic = require('ecstatic'); -var open = require('open'); -var browserify = require('browserify'); -var watchify = require('watchify'); - -var constants = require('../../tasks/util/constants'); -var compress = require('../../tasks/util/compress_attributes'); - -var PORT = process.argv[2] || 3000; - -var server = http.createServer(ecstatic({ - root: constants.pathToRoot, - cache: 0, - gzip: true -})); - - -// Bundle development code -var b = browserify(constants.pathToPlotlyIndex, { - debug: true, - standalone: 'Plotly', - transform: [compress], - cache: {}, - packageCache: {}, - plugin: [watchify] -}); -b.on('update', bundle); - -var firstBundle = true; -function bundle() { - b.bundle(function(err) { - if(err) { - console.error('Error while bundling!', err); - } - - if(firstBundle) { - open('http://localhost:' + PORT + '/devtools/test_dashboard_v2'); - firstBundle = false; - } - console.log('Bundle updated at ' + new Date().toLocaleTimeString()); - }).pipe(fs.createWriteStream(constants.pathToPlotlyBuild)); -} - -bundle(); -server.listen(PORT); - -console.log('Building the first bundle. This might take a little while...\n'); diff --git a/package.json b/package.json index e7e4f37b441..7775eeda109 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "ecstatic": "^1.4.0", "eslint": "^2.1.0", "falafel": "^1.2.0", + "fuse.js": "^2.2.0", "glob": "^7.0.0", "jasmine-core": "^2.3.4", "karma": "^0.13.15", From bdb23a8e7cc1778c979090600dccc93c2aff922b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Tusz?= Date: Tue, 5 Apr 2016 12:42:00 -0400 Subject: [PATCH 4/7] Add `Promise`s to devtools eslintrc --- devtools/.eslintrc | 3 +++ devtools/test_dashboard/server.js | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/devtools/.eslintrc b/devtools/.eslintrc index aabacb13e13..78444da8aa0 100644 --- a/devtools/.eslintrc +++ b/devtools/.eslintrc @@ -3,5 +3,8 @@ "env": { "node": true, "browser": true + }, + "globals": { + "Promise": true } } diff --git a/devtools/test_dashboard/server.js b/devtools/test_dashboard/server.js index 202fdb5259b..c926105f735 100644 --- a/devtools/test_dashboard/server.js +++ b/devtools/test_dashboard/server.js @@ -74,7 +74,7 @@ function readFiles(files) { } function createMocksList(files) { - var mocksList = files.map(function(file, i) { + var mocksList = files.map(function(file) { var contents = JSON.parse(file.contents); // get plot type keywords from mocks From e4550a6e31c5c7e0c3789361eb41b0733ec22aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Tusz?= Date: Tue, 5 Apr 2016 17:44:32 -0400 Subject: [PATCH 5/7] Move test mocks.json file to build dir --- .gitignore | 2 -- devtools/test_dashboard/server.js | 8 +++----- tasks/util/constants.js | 1 + 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 8f830eca1b3..54d6c34020d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,4 @@ build/* !build/ploticon.js !build/README.md -devtools/test_dashboard/mocks.json - npm-debug.log* diff --git a/devtools/test_dashboard/server.js b/devtools/test_dashboard/server.js index c926105f735..e49d2513138 100644 --- a/devtools/test_dashboard/server.js +++ b/devtools/test_dashboard/server.js @@ -28,13 +28,11 @@ var b = browserify(constants.pathToPlotlyIndex, { packageCache: {}, plugin: [watchify] }); -b.on('update', bundleDevtools); +b.on('update', bundlePlotly); // Bundle devtools code var devtoolsPath = path.join(constants.pathToRoot, 'devtools/test_dashboard'); -var devtools = browserify(path.join(devtoolsPath, 'devtools.js'), { - transform: [compress] -}); +var devtools = browserify(path.join(devtoolsPath, 'devtools.js'), {}); var firstBundle = true; @@ -100,7 +98,7 @@ function createMocksList(files) { } function saveToFile(mocksList) { - var filePath = path.join(constants.pathToRoot, 'devtools/test_dashboard/mocks.json'); + var filePath = path.join(constants.pathToBuild, 'test_dashboard_mocks.json'); var content = JSON.stringify(mocksList, null, 4); return writeFilePromise(filePath, content); diff --git a/tasks/util/constants.js b/tasks/util/constants.js index 68ad619c9e6..fb78cc0c79b 100644 --- a/tasks/util/constants.js +++ b/tasks/util/constants.js @@ -19,6 +19,7 @@ module.exports = { pathToRoot: pathToRoot, pathToSrc: pathToSrc, pathToLib: pathToLib, + pathToBuild: pathToBuild, pathToPlotlyIndex: path.join(pathToLib, 'index.js'), pathToPlotlyCore: path.join(pathToSrc, 'core.js'), From 208fd0b348cd88735865411bf1b61ddf816ebdcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Tusz?= Date: Tue, 5 Apr 2016 17:44:58 -0400 Subject: [PATCH 6/7] Change search result panel to stay open until search cleared --- devtools/test_dashboard/devtools.js | 13 +++++-------- devtools/test_dashboard/style.css | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/devtools/test_dashboard/devtools.js b/devtools/test_dashboard/devtools.js index c68e39f5eb9..57752bb65aa 100644 --- a/devtools/test_dashboard/devtools.js +++ b/devtools/test_dashboard/devtools.js @@ -1,5 +1,5 @@ var Fuse = require('fuse.js'); -var mocks = require('./mocks.json'); +var mocks = require('../../build/test_dashboard_mocks.json'); // Our gracious testing object @@ -127,6 +127,7 @@ var f = new Fuse(mocks, { var searchBar = document.getElementById('mocks-search'); var mocksList = document.getElementById('mocks-list'); +var plotArea = document.getElementById('plots'); searchBar.addEventListener('keyup', function(e) { @@ -148,15 +149,11 @@ searchBar.addEventListener('keyup', function(e) { // Clear plots and plot selected. Tabs.purge(); Tabs.plotMock(r.file.slice(0, -5)); - - // Clear results. - while(mocksList.firstChild) { - mocksList.removeChild(mocksList.firstChild); - } - - e.target.value = ''; }); mocksList.appendChild(result); + + var listWidth = mocksList.getBoundingClientRect.width; + plotArea.setAttribute('width', window.innerWidth - listWidth); }); }); diff --git a/devtools/test_dashboard/style.css b/devtools/test_dashboard/style.css index 71e49dcda70..81616419151 100644 --- a/devtools/test_dashboard/style.css +++ b/devtools/test_dashboard/style.css @@ -1,11 +1,17 @@ html, body{ margin: 0; - padding: 0; + padding: 40px 0 0 0; font-family: helvetica, arial, sans-serif; + background-color: #fafafa; } header{ + position: fixed; + top: 0; height: 40px; + width: 100%; border-bottom: 1px solid #4983EC; + background-color: #ffffff; + z-index: 100000; } header img{ height: 100%; @@ -28,14 +34,16 @@ header span{ line-height: 40px; } #mocks-list{ - position: absolute; + position: fixed; right: 0px; top: 40px; + bottom: 0px; z-index: 100000; background-color: #fff; border-left: 1px solid #4983EC; border-bottom: 1px solid #4983EC; border-top: 1px solid #4983EC; + overflow: scroll; } .search-result{ display: block; @@ -48,6 +56,9 @@ header span{ color: #fff; background-color: #4983EC; } +#plots{ + width: 100%; +} .dashboard-plot{ margin-bottom: 30px; max-width: 940px; From 3cf0f55425a41e0b38b4678cd3278c6c81286358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Tusz?= Date: Wed, 6 Apr 2016 12:50:24 -0400 Subject: [PATCH 7/7] Add scrolling to dashboard plot-area div for oversized plots --- devtools/test_dashboard/devtools.js | 5 +++-- devtools/test_dashboard/style.css | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/devtools/test_dashboard/devtools.js b/devtools/test_dashboard/devtools.js index 57752bb65aa..089df205024 100644 --- a/devtools/test_dashboard/devtools.js +++ b/devtools/test_dashboard/devtools.js @@ -153,7 +153,8 @@ searchBar.addEventListener('keyup', function(e) { mocksList.appendChild(result); - var listWidth = mocksList.getBoundingClientRect.width; - plotArea.setAttribute('width', window.innerWidth - listWidth); + var listWidth = mocksList.getBoundingClientRect().width; + var plotAreaWidth = Math.floor(window.innerWidth - listWidth); + plotArea.setAttribute('style', 'width: ' + plotAreaWidth + 'px;'); }); }); diff --git a/devtools/test_dashboard/style.css b/devtools/test_dashboard/style.css index 81616419151..bd6f17f1270 100644 --- a/devtools/test_dashboard/style.css +++ b/devtools/test_dashboard/style.css @@ -57,9 +57,8 @@ header span{ background-color: #4983EC; } #plots{ - width: 100%; + overflow: scroll; } .dashboard-plot{ margin-bottom: 30px; - max-width: 940px; }