diff --git a/ENV.js b/ENV.js index cc70ba87..ca1657ec 100644 --- a/ENV.js +++ b/ENV.js @@ -1,211 +1,225 @@ -var ENV = ENV || (function() { +var ENV = + ENV || + (function() { + var first = true; + var counter = 0; + var data; + var _base; + (_base = String.prototype).lpad || + (_base.lpad = function(padding, toLength) { + return padding + .repeat((toLength - this.length) / padding.length) + .concat(this); + }); - var first = true; - var counter = 0; - var data; - var _base; - (_base = String.prototype).lpad || (_base.lpad = function(padding, toLength) { - return padding.repeat((toLength - this.length) / padding.length).concat(this); - }); - - function formatElapsed(value) { - var str = parseFloat(value).toFixed(2); - if (value > 60) { - minutes = Math.floor(value / 60); - comps = (value % 60).toFixed(2).split('.'); - seconds = comps[0].lpad('0', 2); - ms = comps[1]; - str = minutes + ":" + seconds + "." + ms; + function formatElapsed(value) { + var str = parseFloat(value).toFixed(2); + if (value > 60) { + minutes = Math.floor(value / 60); + comps = (value % 60).toFixed(2).split("."); + seconds = comps[0].lpad("0", 2); + ms = comps[1]; + str = minutes + ":" + seconds + "." + ms; + } + return str; } - return str; - } - function getElapsedClassName(elapsed) { - var className = 'Query elapsed'; - if (elapsed >= 10.0) { - className += ' warn_long'; - } - else if (elapsed >= 1.0) { - className += ' warn'; - } - else { - className += ' short'; + function getElapsedClassName(elapsed) { + var className = "Query elapsed"; + if (elapsed >= 10.0) { + className += " warn_long"; + } else if (elapsed >= 1.0) { + className += " warn"; + } else { + className += " short"; + } + return className; } - return className; - } - function countClassName(queries) { - var countClassName = "label"; - if (queries >= 20) { - countClassName += " label-important"; - } - else if (queries >= 10) { - countClassName += " label-warning"; - } - else { - countClassName += " label-success"; + function countClassName(queries) { + var countClassName = "label"; + if (queries >= 20) { + countClassName += " label-important"; + } else if (queries >= 10) { + countClassName += " label-warning"; + } else { + countClassName += " label-success"; + } + return countClassName; } - return countClassName; - } - function updateQuery(object) { - if (!object) { - object = {}; - } - var elapsed = Math.random() * 15; - object.elapsed = elapsed; - object.formatElapsed = formatElapsed(elapsed); - object.elapsedClassName = getElapsedClassName(elapsed); - object.query = "SELECT blah FROM something"; - object.waiting = Math.random() < 0.5; - if (Math.random() < 0.2) { - object.query = " in transaction"; - } - if (Math.random() < 0.1) { - object.query = "vacuum"; + function updateQuery(object) { + if (!object) { + object = {}; + } + var elapsed = Math.random() * 15; + object.elapsed = elapsed; + object.formatElapsed = formatElapsed(elapsed); + object.elapsedClassName = getElapsedClassName(elapsed); + object.query = "SELECT blah FROM something"; + object.waiting = Math.random() < 0.5; + if (Math.random() < 0.2) { + object.query = " in transaction"; + } + if (Math.random() < 0.1) { + object.query = "vacuum"; + } + return object; } - return object; - } - function cleanQuery(value) { - if (value) { - value.formatElapsed = ""; - value.elapsedClassName = ""; - value.query = ""; - value.elapsed = null; - value.waiting = null; - } else { - return { - query: "***", - formatElapsed: "", - elapsedClassName: "" - }; + function cleanQuery(value) { + if (value) { + value.formatElapsed = ""; + value.elapsedClassName = ""; + value.query = ""; + value.elapsed = null; + value.waiting = null; + } else { + return { + query: "***", + formatElapsed: "", + elapsedClassName: "" + }; + } } - } - function generateRow(object, keepIdentity, counter) { - var nbQueries = Math.floor((Math.random() * 10) + 1); - if (!object) { - object = {}; - } - object.lastMutationId = counter; - object.nbQueries = nbQueries; - if (!object.lastSample) { - object.lastSample = {}; - } - if (!object.lastSample.topFiveQueries) { - object.lastSample.topFiveQueries = []; - } - if (keepIdentity) { - // for Angular optimization - if (!object.lastSample.queries) { - object.lastSample.queries = []; - for (var l = 0; l < 12; l++) { - object.lastSample.queries[l] = cleanQuery(); - } + function generateRow(object, keepIdentity, counter) { + var nbQueries = Math.floor(Math.random() * 10 + 1); + if (!object) { + object = {}; } - for (var j in object.lastSample.queries) { - var value = object.lastSample.queries[j]; - if (j <= nbQueries) { - updateQuery(value); - } else { - cleanQuery(value); - } + object.lastMutationId = counter; + object.nbQueries = nbQueries; + if (!object.lastSample) { + object.lastSample = {}; } - } else { - object.lastSample.queries = []; - for (var j = 0; j < 12; j++) { - if (j < nbQueries) { - var value = updateQuery(cleanQuery()); - object.lastSample.queries.push(value); - } else { - object.lastSample.queries.push(cleanQuery()); + if (!object.lastSample.topFiveQueries) { + object.lastSample.topFiveQueries = []; + } + if (keepIdentity) { + // for Angular optimization + if (!object.lastSample.queries) { + object.lastSample.queries = []; + for (var l = 0; l < 12; l++) { + object.lastSample.queries[l] = cleanQuery(); + } + } + for (var j in object.lastSample.queries) { + var value = object.lastSample.queries[j]; + if (j <= nbQueries) { + updateQuery(value); + } else { + cleanQuery(value); + } + } + } else { + object.lastSample.queries = []; + for (var j = 0; j < 12; j++) { + if (j < nbQueries) { + var value = updateQuery(cleanQuery()); + object.lastSample.queries.push(value); + } else { + object.lastSample.queries.push(cleanQuery()); + } } } + for (var i = 0; i < 5; i++) { + var source = object.lastSample.queries[i]; + object.lastSample.topFiveQueries[i] = source; + } + object.lastSample.nbQueries = nbQueries; + object.lastSample.countClassName = countClassName(nbQueries); + return object; } - for (var i = 0; i < 5; i++) { - var source = object.lastSample.queries[i]; - object.lastSample.topFiveQueries[i] = source; - } - object.lastSample.nbQueries = nbQueries; - object.lastSample.countClassName = countClassName(nbQueries); - return object; - } - function getData(keepIdentity) { - var oldData = data; - if (!keepIdentity) { // reset for each tick when !keepIdentity - data = []; - for (var i = 1; i <= ENV.rows; i++) { - data.push({ dbname: 'cluster' + i, query: "", formatElapsed: "", elapsedClassName: "" }); - data.push({ dbname: 'cluster' + i + ' slave', query: "", formatElapsed: "", elapsedClassName: "" }); + function getData(keepIdentity) { + var oldData = data; + if (!keepIdentity) { + // reset for each tick when !keepIdentity + data = []; + for (var i = 1; i <= ENV.rows; i++) { + data.push({ + dbname: "cluster" + i, + query: "", + formatElapsed: "", + elapsedClassName: "" + }); + data.push({ + dbname: "cluster" + i + " slave", + query: "", + formatElapsed: "", + elapsedClassName: "" + }); + } } - } - if (!data) { // first init when keepIdentity - data = []; - for (var i = 1; i <= ENV.rows; i++) { - data.push({ dbname: 'cluster' + i }); - data.push({ dbname: 'cluster' + i + ' slave' }); + if (!data) { + // first init when keepIdentity + data = []; + for (var i = 1; i <= ENV.rows; i++) { + data.push({ dbname: "cluster" + i }); + data.push({ dbname: "cluster" + i + " slave" }); + } + oldData = data; } - oldData = data; - } - for (var i in data) { - var row = data[i]; - if (!keepIdentity && oldData && oldData[i]) { - row.lastSample = oldData[i].lastSample; - } - if (!row.lastSample || Math.random() < ENV.mutations()) { - counter = counter + 1; - if (!keepIdentity) { - row.lastSample = null; + for (var i in data) { + var row = data[i]; + if (!keepIdentity && oldData && oldData[i]) { + row.lastSample = oldData[i].lastSample; + } + if (!row.lastSample || Math.random() < ENV.mutations()) { + counter = counter + 1; + if (!keepIdentity) { + row.lastSample = null; + } + generateRow(row, keepIdentity, counter); + } else { + data[i] = oldData[i]; } - generateRow(row, keepIdentity, counter); - } else { - data[i] = oldData[i]; } + first = false; + return { + toArray: function() { + return data; + } + }; } - first = false; - return { - toArray: function() { - return data; - } - }; - } - var mutationsValue = 0.5; + var mutationsValue = 0.5; - function mutations(value) { - if (value) { - mutationsValue = value; - document.querySelector('#ratioval').innerHTML = 'mutations : ' + (mutationsValue * 100).toFixed(0) + '%'; - return mutationsValue; - } else { - return mutationsValue; + function mutations(value) { + if (value) { + mutationsValue = value; + document.querySelector("#ratioval").innerHTML = + "mutations : " + (mutationsValue * 100).toFixed(0) + "%"; + return mutationsValue; + } else { + return mutationsValue; + } } - } - var body = document.querySelector('body'); - var theFirstChild = body.firstChild; + var body = document.querySelector("body"); + var theFirstChild = body.firstChild; - var sliderContainer = document.createElement('div'); - sliderContainer.style.cssText = "display: flex"; - var slider = document.createElement('input'); - var text = document.createElement('label'); - text.innerHTML = 'mutations : ' + (mutationsValue * 100).toFixed(0) + '%'; - text.id = "ratioval"; - slider.setAttribute("type", "range"); - slider.style.cssText = 'margin-bottom: 10px; margin-top: 5px'; - slider.addEventListener('change', function(e) { - ENV.mutations(e.target.value / 100); - }); - sliderContainer.appendChild(text); - sliderContainer.appendChild(slider); - body.insertBefore(sliderContainer, theFirstChild); + var sliderContainer = document.createElement("div"); + sliderContainer.style.cssText = "display: flex"; + var slider = document.createElement("input"); + var text = document.createElement("label"); + text.innerHTML = "mutations : " + (mutationsValue * 100).toFixed(0) + "%"; + text.id = "ratioval"; + text.className = "mutation-ratio"; + slider.setAttribute("type", "range"); + slider.style.cssText = "margin-bottom: 10px; margin-top: 5px"; + slider.addEventListener("change", function(e) { + ENV.mutations(e.target.value / 100); + }); + sliderContainer.appendChild(text); + sliderContainer.appendChild(slider); + body.insertBefore(sliderContainer, theFirstChild); - return { - generateData: getData, - rows: 50, - timeout: 0, - mutations: mutations - }; -})(); + return { + generateData: getData, + rows: 50, + timeout: 0, + mutations: mutations + }; + })(); diff --git a/lib/memory-stats.js b/lib/memory-stats.js index e621d25d..46ed6a90 100644 --- a/lib/memory-stats.js +++ b/lib/memory-stats.js @@ -3,103 +3,105 @@ * @author jetienne / http://jetienne.com/ * @author paulirish / http://paulirish.com/ */ -var MemoryStats = function (){ - - var msMin = 100; - var msMax = 0; - - var container = document.createElement( 'div' ); - container.id = 'stats'; - container.style.cssText = 'width:80px;opacity:0.9;cursor:pointer'; - - var msDiv = document.createElement( 'div' ); - msDiv.id = 'ms'; - msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;'; - container.appendChild( msDiv ); - - var msText = document.createElement( 'div' ); - msText.id = 'msText'; - msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px'; - msText.innerHTML= 'Memory'; - msDiv.appendChild( msText ); - - var msGraph = document.createElement( 'div' ); - msGraph.id = 'msGraph'; - msGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0f0'; - msDiv.appendChild( msGraph ); - - while ( msGraph.children.length < 74 ) { - - var bar = document.createElement( 'span' ); - bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#131'; - msGraph.appendChild( bar ); - - } - - var updateGraph = function ( dom, height, color ) { - - var child = dom.appendChild( dom.firstChild ); - child.style.height = height + 'px'; - if( color ) child.style.backgroundColor = color; - - } - - var perf = window.performance || {}; - // polyfill usedJSHeapSize - if (!perf && !perf.memory){ - perf.memory = { usedJSHeapSize : 0 }; - } - if (perf && !perf.memory){ - perf.memory = { usedJSHeapSize : 0 }; - } - - // support of the API? - if( perf.memory.totalJSHeapSize === 0 ){ - console.warn('totalJSHeapSize === 0... performance.memory is only available in Chrome .') - } - - // TODO, add a sanity check to see if values are bucketed. - // If so, reminde user to adopt the --enable-precise-memory-info flag. - // open -a "/Applications/Google Chrome.app" --args --enable-precise-memory-info - - var self = this; - var memory = 0; - var lastTime = Date.now(); - var lastUsedHeap= perf.memory.usedJSHeapSize; - return { - domElement: container, - - update: function () { - - // refresh only 30time per second - if( Date.now() - lastTime < 1000/30 ) return; - lastTime = Date.now() - - var delta = perf.memory.usedJSHeapSize - lastUsedHeap; - lastUsedHeap = perf.memory.usedJSHeapSize; - var color = delta < 0 ? '#830' : '#131'; - - var ms = perf.memory.usedJSHeapSize; - msMin = Math.min( msMin, ms ); - msMax = Math.max( msMax, ms ); - - self.memory = bytesToSize(ms, 2); - msText.textContent = "Mem: " + self.memory; - - var normValue = ms / (30*1024*1024); - var height = Math.min( 30, 30 - normValue * 30 ); - updateGraph( msGraph, height, color); - - function bytesToSize( bytes, nFractDigit ){ - var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; - if (bytes == 0) return 'n/a'; - nFractDigit = nFractDigit !== undefined ? nFractDigit : 0; - var precision = Math.pow(10, nFractDigit); - var i = Math.floor(Math.log(bytes) / Math.log(1024)); - return Math.round(bytes*precision / Math.pow(1024, i))/precision + ' ' + sizes[i]; - }; - } - - } - +var MemoryStats = function() { + var msMin = 100; + var msMax = 0; + + var container = document.createElement("div"); + container.id = "stats"; + container.style.cssText = "width:80px;opacity:0.9;cursor:pointer"; + + var msDiv = document.createElement("div"); + msDiv.id = "ms"; + msDiv.style.cssText = + "padding:0 0 3px 3px;text-align:left;background-color:#020;"; + container.appendChild(msDiv); + + var msText = document.createElement("div"); + msText.id = "msText"; + msText.style.cssText = + "color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px"; + msText.innerHTML = "Memory"; + msDiv.appendChild(msText); + + var msGraph = document.createElement("div"); + msGraph.id = "msGraph"; + msGraph.style.cssText = + "position:relative;width:74px;height:30px;background-color:#0f0"; + msDiv.appendChild(msGraph); + + while (msGraph.children.length < 74) { + var bar = document.createElement("span"); + bar.style.cssText = + "width:1px;height:30px;float:left;background-color:#131"; + msGraph.appendChild(bar); + } + + var updateGraph = function(dom, height, color) { + var child = dom.appendChild(dom.firstChild); + child.style.height = height + "px"; + if (color) child.style.backgroundColor = color; + }; + + var perf = window.performance || {}; + // polyfill usedJSHeapSize + if (!perf && !perf.memory) { + perf.memory = { usedJSHeapSize: 0 }; + } + if (perf && !perf.memory) { + perf.memory = { usedJSHeapSize: 0 }; + } + + // support of the API? + if (perf.memory.totalJSHeapSize === 0) { + console.warn( + "totalJSHeapSize === 0... performance.memory is only available in Chrome ." + ); + } + + // TODO, add a sanity check to see if values are bucketed. + // If so, reminde user to adopt the --enable-precise-memory-info flag. + // open -a "/Applications/Google Chrome.app" --args --enable-precise-memory-info + + var self = this; + var memory = 0; + var lastTime = Date.now(); + var lastUsedHeap = perf.memory.usedJSHeapSize; + return { + domElement: container, + + update: function() { + // refresh only 30time per second + if (Date.now() - lastTime < 1000 / 30) return; + lastTime = Date.now(); + + var delta = perf.memory.usedJSHeapSize - lastUsedHeap; + lastUsedHeap = perf.memory.usedJSHeapSize; + var color = delta < 0 ? "#830" : "#131"; + + var ms = perf.memory.usedJSHeapSize; + msMin = Math.min(msMin, ms); + msMax = Math.max(msMax, ms); + + self.memory = bytesToSize(ms, 2); + msText.textContent = "Mem: " + self.memory; + + var normValue = ms / (30 * 1024 * 1024); + var height = Math.min(30, 30 - normValue * 30); + updateGraph(msGraph, height, color); + + function bytesToSize(bytes, nFractDigit) { + var sizes = ["Bytes", "KB", "MB", "GB", "TB"]; + if (bytes == 0) return "n/a"; + nFractDigit = nFractDigit !== undefined ? nFractDigit : 0; + var precision = Math.pow(10, nFractDigit); + var i = Math.floor(Math.log(bytes) / Math.log(1024)); + return ( + Math.round((bytes * precision) / Math.pow(1024, i)) / precision + + " " + + sizes[i] + ); + } + } + }; }; diff --git a/lib/monitor.js b/lib/monitor.js index 57d0f032..e9ab8045 100644 --- a/lib/monitor.js +++ b/lib/monitor.js @@ -1,69 +1,107 @@ -var Monitoring = Monitoring || (function() { - - var stats = new MemoryStats(); - stats.domElement.style.position = 'fixed'; - stats.domElement.style.right = '0px'; - stats.domElement.style.bottom = '0px'; - document.body.appendChild( stats.domElement ); - requestAnimationFrame(function rAFloop(){ +var Monitoring = + Monitoring || + (function() { + var stats = new MemoryStats(); + stats.domElement.style.position = "fixed"; + stats.domElement.style.right = "0px"; + stats.domElement.style.bottom = "0px"; + document.body.appendChild(stats.domElement); + requestAnimationFrame(function rAFloop() { stats.update(); requestAnimationFrame(rAFloop); - }); + }); - var RenderRate = function () { - var container = document.createElement( 'div' ); - container.id = 'stats'; - container.style.cssText = 'width:150px;opacity:0.9;cursor:pointer;position:fixed;right:80px;bottom:0px;'; + var RenderRate = function() { + var container = document.createElement("div"); + container.id = "stats"; + container.style.cssText = + "width:150px;opacity:0.9;cursor:pointer;position:fixed;right:80px;bottom:0px;"; - var msDiv = document.createElement( 'div' ); - msDiv.id = 'ms'; - msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;'; - container.appendChild( msDiv ); + var msDiv = document.createElement("div"); + msDiv.id = "ms"; + msDiv.style.cssText = + "padding:0 0 3px 3px;text-align:left;background-color:#020;"; + container.appendChild(msDiv); - var msText = document.createElement( 'div' ); - msText.id = 'msText'; - msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px'; - msText.innerHTML= 'Repaint rate: 0/sec'; - msDiv.appendChild( msText ); + var msText = document.createElement("div"); + msText.id = "msText"; + msText.style.cssText = + "color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px"; + msText.innerHTML = "Repaint rate: 0/sec"; + msDiv.appendChild(msText); - var self = this; - var rate = 0; - var bucketSize = 20; - var bucket = []; - var lastTime = Date.now(); - return { - domElement: container, - ping: function () { - var start = lastTime; - var stop = Date.now(); - var rate = 1000 / (stop - start); - if (rate == Infinity) { - return; - } - bucket.push(rate); - if (bucket.length > bucketSize) { - bucket.shift(); + var self = this; + var rate = 0; + var bucketSize = 200; + var bucket = []; + var lastTime = performance ? performance.now() : Date.now(); + return { + domElement: container, + ping: function() { + var start = lastTime; + var stop = performance ? performance.now() : Date.now(); + var rate = 1000 / (stop - start); + if (rate == Infinity) { + return; + } + bucket.push(rate); + if (bucket.length > bucketSize) { + bucket.shift(); + } + var sum = 0; + const tmp = sma(bucket, Math.floor(bucketSize / 10), Number); + for (var i = 0; i < tmp.length; i++) { + sum = sum + tmp[i]; + } + self.rate = sum / tmp.length; + if (isNaN(self.rate) === false) { + msText.textContent = + "Repaint rate: " + self.rate.toFixed(2) + "/sec"; + } + lastTime = stop; + }, + rate: function() { + return self.rate; } - var sum = 0; - for (var i = 0; i < bucket.length; i++) { - sum = sum + bucket[i]; - } - self.rate = (sum / bucket.length); - msText.textContent = "Repaint rate: " + self.rate.toFixed(2) + "/sec"; - lastTime = stop; - }, - rate: function () { - return self.rate; - } - } - }; + }; + }; + + var renderRate = new RenderRate(); + document.body.appendChild(renderRate.domElement); + + return { + memoryStats: stats, + renderRate: renderRate + }; + })(); + +//The MIT License (MIT) +// Copyright (c) 2017 Brian Woodward +// https://github.com/doowb/sma/blob/master/LICENSE + +// simple moving average +function sma(arr, range, format) { + if (!Array.isArray(arr)) { + throw TypeError("expected first argument to be an array"); + } - var renderRate = new RenderRate(); - document.body.appendChild( renderRate.domElement ); + var num = range || arr.length; + var res = []; + var len = arr.length + 1; + var idx = num - 1; + while (++idx < len) { + res.push(avg(arr, idx, num)); + } + return res; +} - return { - memoryStats: stats, - renderRate: renderRate - }; +function avg(arr, idx, range) { + return sum(arr.slice(idx - range, idx)) / range; +} -})(); +function sum(arr) { + var len = arr.length; + var num = 0; + while (len--) num += Number(arr[len]); + return num; +} diff --git a/list.js b/list.js index 937f86b3..6bc0f8b2 100644 --- a/list.js +++ b/list.js @@ -1,74 +1,75 @@ -var List =[ - { type: 'naive', id: 'aurelia', label: 'DBMON Aurelia', url: './aurelia' }, - { type: 'optimized', id: 'aurelia', label: 'DBMON Aurelia', url: './aurelia-optimized' }, - { type: 'naive', id: 'cycle', label: 'DBMON Cycle.js', url: './cycle'}, - { type: 'naive', id: 'ember', url: './ember', label: 'DBMON Ember' }, - { type: 'naive', id: 'angular', url: './angular', label: 'DBMON Angular' }, - { type: 'naive', id: 'angular-light', url: './angular-light', label: 'DBMON Angular Light' }, - { type: 'naive', id: 'angular2', url: './angular2', label: 'DBMON Angular 2.0 Alpha' }, - { type: 'naive', id: 'react', url: './react', label: 'DBMON React' }, - { type: 'naive', id: 'magjs', url: './magjs', label: 'DBMON MagJS' }, - { type: 'naive', id: 'mol', url: './mol/index.html', label: 'DBMON $mol'}, - { type: 'naive', id: 'elem', url: './elem', label: 'DBMON elem' }, - { type: 'naive', id: 'elem-vdom', url: './elem-vdom', label: 'DBMON elem-vdom' }, - { type: 'naive', id: 'elm', url: './elm', label: 'DBMON elm' }, - { type: 'naive', id: 'ractive', url: './ractive', label: 'DBMON Ractive' }, - { type: 'naive', id: 'mithril', url: './mithril', label: 'DBMON Mithril' }, - { type: 'naive', id: 'citot7', url: './cito+t7-precompiled', label: 'DBMON Cito+t7' }, - { type: 'naive', id: 'inferno', url: './inferno', label: 'DBMON Inferno' }, - { type: 'naive', id: 'riot', url: './riot', label: 'DBMON Riot.js' }, - { type: 'optimized', id: 'riot', url: './riot/no-reorder.html', label: 'DBMON Riot.js ( no-reorder )' }, - { type: 'naive', id: 'polymer', url: './polymer', label: 'DBMON Polymer 1.8' }, - { type: 'naive', id: 'polymer2', url: './polymer2', label: 'DBMON Polymer 2.0 (rc.2, pure ES6)' }, - { type: 'naive', id: 'vanilla', url: './vanilla-simple', label: 'DBMON vanilla' }, - { type: 'naive', id: 'dott', url: './dotT', label: 'DBMON dotT' }, - { type: 'naive', id: 'canvas', url: './canvas', label: 'DBMON canvas' }, - { type: 'naive', id: 'react-canvas', url: './react-canvas', label: 'DBMON react-canvas' }, - { type: 'naive', id: 'sammy', url: './sammy', label: 'DBMON sammy' }, - { type: 'naive', id: 'vue', url: './vue', label: 'DBMON Vue.js' }, - { type: 'naive', id: 'vue2', url: './vue2', label: 'DBMON vue2.js' }, - { type: 'naive', id: 'backbone', url: './backbone', label: 'DBMON Backbone' }, - { type: 'naive', id: 'backbone-marionette', url: './marionette', label: 'DBMON Backbone Marionette' }, - { type: 'optimized', id: 'backbone-marionette', url: './marionette/opt.html', label: 'DBMON Backbone Marionette' }, - { type: 'naive', id: 'knockout', url: './knockout', label: 'DBMON Knockout' }, - { type: 'naive', id: 'regularjs', url: './regularjs', label: 'DBMON Regularjs' }, - { type: 'naive', id: 'maskjs', url: './mask/index.html', label: 'DBMON MaskJS' }, - { type: 'naive', id: 'matreshkajs', url: './matreshka/index.html', label: 'DBMON Matreshka.js' }, - { type: 'naive', id: 'rotorjs', url: './rotorjs/index.html', label: 'DBMON RotorJS' }, - { type: 'optimized', id: "cycle + snabbdom", label: "DBMON Cycle.js + Snabbdom", url: "./cycle-snabbdom"}, - { type: 'optimized', id: 'motorcycle', label: 'DBMON Motorcycle.js', url: './motorcycle'}, - { type: 'naive', id: 'domvm', url: './domvm/index.html', label: 'DBMON domvm' }, - { type: 'optimized', id: 'domvm-optimized', url: './domvm-optimized/index.html', label: 'DBMON domvm' }, - { type: 'naive', id: 'once', url: './once/index.html', label: 'DBMON once' }, - { type: 'naive', id: 'ripple', url: './ripple/index.html', label: 'DBMON ripple' }, - { type: 'naive', id: 'diffhtml', url: './diffhtml/index.html', label: 'DBMON diffHTML' }, - { type: 'optimized', id: 'react', url: './react/opt.html', label: 'DBMON React' }, - { type: 'optimized', id: 'preact', url: './preact', label: 'DBMON Preact' }, - { type: 'naive', id: 'preact-functional', url: './preact/functional.html', label: 'DBMON Preact (Functional)' }, - { type: 'optimized', id: 'angular', url: './angular/opt.html', label: 'DBMON Angular' }, - { type: 'optimized', id: 'angular-light', url: './angular-light/opt.html', label: 'DBMON Angular Light' }, - { type: 'optimized', id: 'angular2', url: './angular2/opt.html', label: 'DBMON Angular 2.0 Alpha' }, - { type: 'optimized', id: 'angular-track-by', url: './angular-track-by', label: 'DBMON Angular (track by $index)' }, - { type: 'optimized', id: 'elem', url: './elm/opt.html', label: 'DBMON elm' }, - { type: 'optimized', id: 'vanilla', url: './vanilla-optimized', label: 'DBMON vanilla' }, - { type: 'optimized', id: 'maskjs', url: './mask/index_opt.html', label: 'DBMON MaskJS' }, - { type: 'optimized', id: 'vue', url: './vue/opt.html', label: 'DBMON Vue.js' }, - { type: 'optimized', id: 'vue2', url: './vue2/opt.html', label: 'DBMON vue2.js' }, - { type: 'optimized', id: 'rotorjs', url: './rotorjs/with_thunks.html', label: 'DBMON RotorJS (with using VnodeImmutableThunk)' }, - { type: 'naive', id: 're-frame', url: './re-frame/index.html', label: 're-frame (Reagent)' }, - { type: 'naive', id: 'd3', url: './d3/index.html', label: 'DBMON D3' }, - { type: 'naive', id: 'morphdom', url: './morphdom/index.html', label: 'DBMON Morphdom' }, - { type: 'optimized', id: 'frzr', url: './frzr/index.html', label: 'DBMON FRZR' }, - { type: 'naive', id: 'vidom', url: './vidom/index.html', label: 'DBMON vidom' }, - { type: 'optimized', id: 'cycle + xstream', label: 'DBMON Cycle.js + xstream', url: './cycle-xstream' }, - { type: 'naive', id: 'rionite', url: './rionite', label: 'DBMON Rionite' }, - { type: 'naive', id: 'monkberry', url: './monkberry/index.html', label: 'DBMON Monkberry' }, - { type: 'naive', id: 'simulacra', url: './simulacra/index.html', label: 'DBMON Simulacra' }, - { type: 'optimized', id: 'simulacra', url: './simulacra/opt.html', label: 'DBMON Simulacra' }, - { type: 'optimized', id: 'dio', url: './dio/index.html', label: 'DBMON DIO.js' }, - { type: 'optimized', id: 'redom', url: './redom/index.html', label: 'DBMON RE:DOM' }, - { type: 'naive', id: 'hyperapp', url: './hyperapp', label: 'DBMON HyperApp' }, - { type: 'naive', id: 'stemjs', url: './stemjs/index.html', label: 'DBMON StemJS'}, - { type: 'optimized', id: 'stemjs', url: './stemjs-optimized', label: 'DBMON StemJS'}, - { type: 'naive', id: 'stencil', url: './stencil/index.html', label: 'DBMON Stencil' }, - ]; +var List = [ + { type: 'naive', id: 'aurelia', label: 'DBMON Aurelia', url: './aurelia/' }, + { type: 'optimized', id: 'aurelia', label: 'DBMON Aurelia', url: './aurelia-optimized/' }, + { type: 'naive', id: 'cycle', label: 'DBMON Cycle.js', url: './cycle/' }, + { type: 'naive', id: 'ember', url: './ember/', label: 'DBMON Ember' }, + { type: 'naive', id: 'angular', url: './angular/', label: 'DBMON Angular' }, + { type: 'naive', id: 'angular-light', url: './angular-light/', label: 'DBMON Angular Light' }, + { type: 'naive', id: 'angular2', url: './angular2/', label: 'DBMON Angular 2.0 Alpha' }, + { type: 'naive', id: 'react', url: './react/', label: 'DBMON React' }, + { type: 'naive', id: 'magjs', url: './magjs/', label: 'DBMON MagJS' }, + { type: 'naive', id: 'mol', url: './mol/', label: 'DBMON $mol' }, + { type: 'naive', id: 'elem', url: './elem/', label: 'DBMON elem' }, + { type: 'naive', id: 'elem-vdom', url: './elem-vdom', label: 'DBMON elem-vdom' }, + { type: 'naive', id: 'elm', url: './elm/', label: 'DBMON elm' }, + { type: 'naive', id: 'ractive', url: './ractive/', label: 'DBMON Ractive' }, + { type: 'naive', id: 'mithril', url: './mithril/', label: 'DBMON Mithril' }, + { type: 'naive', id: 'citot7', url: './cito+t7-precompiled', label: 'DBMON Cito+t7' }, + { type: 'naive', id: 'inferno', url: './inferno/', label: 'DBMON Inferno' }, + { type: 'naive', id: 'riot', url: './riot/', label: 'DBMON Riot.js' }, + { type: 'optimized', id: 'riot', url: './riot/no-reorder.html', label: 'DBMON Riot.js ( no-reorder )' }, + { type: 'naive', id: 'polymer', url: './polymer/', label: 'DBMON Polymer 1.8' }, + { type: 'naive', id: 'polymer2', url: './polymer2/', label: 'DBMON Polymer 2.0 (rc.2, pure ES6)' }, + { type: 'naive', id: 'vanilla', url: './vanilla-simple/', label: 'DBMON vanilla' }, + { type: 'naive', id: 'dott', url: './dotT/', label: 'DBMON dotT' }, + { type: 'naive', id: 'canvas', url: './canvas/', label: 'DBMON canvas' }, + { type: 'naive', id: 'react-canvas', url: './react-canvas/', label: 'DBMON react-canvas' }, + { type: 'naive', id: 'sammy', url: './sammy/', label: 'DBMON sammy' }, + { type: 'naive', id: 'vue', url: './vue/', label: 'DBMON Vue.js' }, + { type: 'naive', id: 'vue2', url: './vue2/', label: 'DBMON vue2.js' }, + { type: 'naive', id: 'backbone', url: './backbone/', label: 'DBMON Backbone' }, + { type: 'naive', id: 'backbone-marionette', url: './marionette/', label: 'DBMON Backbone Marionette' }, + { type: 'optimized', id: 'backbone-marionette', url: './marionette/opt.html', label: 'DBMON Backbone Marionette' }, + { type: 'naive', id: 'knockout', url: './knockout/', label: 'DBMON Knockout' }, + { type: 'naive', id: 'regularjs', url: './regularjs/', label: 'DBMON Regularjs' }, + { type: 'naive', id: 'maskjs', url: './mask/', label: 'DBMON MaskJS' }, + { type: 'naive', id: 'matreshkajs', url: './matreshka/', label: 'DBMON Matreshka.js' }, + { type: 'naive', id: 'rotorjs', url: './rotorjs/', label: 'DBMON RotorJS' }, + { type: 'optimized', id: "cycle + snabbdom", label: "DBMON Cycle.js + Snabbdom", url: "./cycle-snabbdom" }, + { type: 'optimized', id: 'motorcycle', label: 'DBMON Motorcycle.js', url: './motorcycle/' }, + { type: 'naive', id: 'domvm', url: './domvm/', label: 'DBMON domvm' }, + { type: 'optimized', id: 'domvm-optimized', url: './domvm-optimized/', label: 'DBMON domvm' }, + { type: 'naive', id: 'once', url: './once/', label: 'DBMON once' }, + { type: 'naive', id: 'ripple', url: './ripple/', label: 'DBMON ripple' }, + { type: 'naive', id: 'diffhtml', url: './diffhtml/', label: 'DBMON diffHTML' }, + { type: 'optimized', id: 'react', url: './react/opt.html', label: 'DBMON React' }, + { type: 'optimized', id: 'preact', url: './preact/', label: 'DBMON Preact' }, + { type: 'naive', id: 'preact-functional', url: './preact/functional.html', label: 'DBMON Preact (Functional)' }, + { type: 'optimized', id: 'angular', url: './angular/opt.html', label: 'DBMON Angular' }, + { type: 'optimized', id: 'angular-light', url: './angular-light/opt.html', label: 'DBMON Angular Light' }, + { type: 'optimized', id: 'angular2', url: './angular2/opt.html', label: 'DBMON Angular 2.0 Alpha' }, + { type: 'optimized', id: 'angular-track-by', url: './angular-track-by/', label: 'DBMON Angular (track by $index)' }, + { type: 'optimized', id: 'elem', url: './elm/opt.html', label: 'DBMON elm' }, + { type: 'optimized', id: 'vanilla', url: './vanilla-optimized', label: 'DBMON vanilla' }, + { type: 'optimized', id: 'maskjs', url: './mask/index_opt.html', label: 'DBMON MaskJS' }, + { type: 'optimized', id: 'vue', url: './vue/opt.html', label: 'DBMON Vue.js' }, + { type: 'optimized', id: 'vue2', url: './vue2/opt.html', label: 'DBMON vue2.js' }, + { type: 'optimized', id: 'rotorjs', url: './rotorjs/with_thunks.html', label: 'DBMON RotorJS (with using VnodeImmutableThunk)' }, + { type: 'naive', id: 're-frame', url: './re-frame/', label: 're-frame (Reagent)' }, + { type: 'naive', id: 'd3', url: './d3/', label: 'DBMON D3' }, + { type: 'naive', id: 'morphdom', url: './morphdom/', label: 'DBMON Morphdom' }, + { type: 'optimized', id: 'frzr', url: './frzr/', label: 'DBMON FRZR' }, + { type: 'naive', id: 'vidom', url: './vidom/', label: 'DBMON vidom' }, + { type: 'optimized', id: 'cycle + xstream', label: 'DBMON Cycle.js + xstream', url: './cycle-xstream/' }, + { type: 'naive', id: 'rionite', url: './rionite', label: 'DBMON Rionite' }, + { type: 'naive', id: 'monkberry', url: './monkberry/', label: 'DBMON Monkberry' }, + { type: 'naive', id: 'simulacra', url: './simulacra/', label: 'DBMON Simulacra' }, + { type: 'optimized', id: 'simulacra', url: './simulacra/opt.html', label: 'DBMON Simulacra' }, + { type: 'optimized', id: 'dio', url: './dio/', label: 'DBMON DIO.js' }, + { type: 'optimized', id: 'redom', url: './redom/', label: 'DBMON RE:DOM' }, + { type: 'naive', id: 'hyperapp', url: './hyperapp/', label: 'DBMON HyperApp' }, + { type: 'naive', id: 'stemjs', url: './stemjs/', label: 'DBMON StemJS' }, + { type: 'optimized', id: 'stemjs', url: './stemjs-optimized/', label: 'DBMON StemJS' }, + { type: 'naive', id: 'stencil', url: './stencil/', label: 'DBMON Stencil' }, + { type: 'naive', id: 'totes', url: './totes/', label: 'DBMON totes' }, +]; diff --git a/styles.css b/styles.css index 0ecbbbff..fb564dce 100644 --- a/styles.css +++ b/styles.css @@ -1,27 +1,130 @@ -body {color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;margin:0;} -label {display:inline-block;font-weight:700;margin-bottom:5px;} -input[type=range] {display:block;width:100%;} -table {border-collapse:collapse;border-spacing:0;} -:before,:after {box-sizing: border-box;} +body { + color: #333; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + margin: 0; +} +label { + display: inline-block; + font-weight: 700; + margin-bottom: 5px; +} +input[type="range"] { + display: block; + width: 100%; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +:before, +:after { + box-sizing: border-box; +} -.table > thead > tr > th,.table > tbody > tr > th,.table > tfoot > tr > th,.table > thead > tr > td,.table > tbody > tr > td,.table > tfoot > tr > td {border-top:1px solid #ddd;line-height:1.42857143;padding:8px;vertical-align:top;} -.table {width:100%;} -.table-striped > tbody > tr:nth-child(odd) > td,.table-striped > tbody > tr:nth-child(odd) > th {background:#f9f9f9;} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + border-top: 1px solid #ddd; + line-height: 1.42857143; + padding: 8px; + vertical-align: top; +} +.table { + width: 100%; +} +.table-striped > tbody > tr:nth-child(odd) > td, +.table-striped > tbody > tr:nth-child(odd) > th { + background: #f9f9f9; +} -.label {border-radius:.25em;color:#fff;display:inline;font-size:75%;font-weight:700;line-height:1;padding:.2em .6em .3em;text-align:center;vertical-align:baseline;white-space:nowrap;} -.label-success {background-color:#5cb85c;} -.label-warning {background-color:#f0ad4e;} +.label { + border-radius: 0.25em; + color: #fff; + display: inline; + font-size: 75%; + font-weight: 700; + line-height: 1; + padding: 0.2em 0.6em 0.3em; + text-align: center; + vertical-align: baseline; + white-space: nowrap; +} +.label-success { + background-color: #5cb85c; +} +.label-warning { + background-color: #f0ad4e; +} -.popover {background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 5px 10px rgba(0,0,0,.2);display:none;left:0;max-width:276px;padding:1px;position:absolute;text-align:left;top:0;white-space:normal;z-index:1010;} -.popover>.arrow:after {border-width:10px;content:"";} -.popover.left {margin-left:-10px;} -.popover.left > .arrow {border-right-width:0;border-left-color:rgba(0,0,0,.25);margin-top:-11px;right:-11px;top:50%;} -.popover.left > .arrow:after {border-left-color:#fff;border-right-width:0;bottom:-10px;content:" ";right:1px;} -.popover > .arrow {border-width:11px;} -.popover > .arrow,.popover>.arrow:after {border-color:transparent;border-style:solid;display:block;height:0;position:absolute;width:0;} +.popover { + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + display: none; + left: 0; + max-width: 276px; + padding: 1px; + position: absolute; + text-align: left; + top: 0; + white-space: normal; + z-index: 1010; +} +.popover > .arrow:after { + border-width: 10px; + content: ""; +} +.popover.left { + margin-left: -10px; +} +.popover.left > .arrow { + border-right-width: 0; + border-left-color: rgba(0, 0, 0, 0.25); + margin-top: -11px; + right: -11px; + top: 50%; +} +.popover.left > .arrow:after { + border-left-color: #fff; + border-right-width: 0; + bottom: -10px; + content: " "; + right: 1px; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow, +.popover > .arrow:after { + border-color: transparent; + border-style: solid; + display: block; + height: 0; + position: absolute; + width: 0; +} -.popover-content {padding:9px 14px;} +.popover-content { + padding: 9px 14px; +} -.Query {position:relative;} -.Query:hover .popover {display:block;left:-100%;width:100%;} +.Query { + position: relative; +} +.Query:hover .popover { + display: block; + left: -100%; + width: 100%; +} +.mutation-ratio { + white-space: nowrap; +} diff --git a/totes/elements/app.js b/totes/elements/app.js new file mode 100644 index 00000000..2b4e338e --- /dev/null +++ b/totes/elements/app.js @@ -0,0 +1,58 @@ +import { html, Component } from "https://unpkg.com/@aaronshaf/totes@1/index.js"; +import "./database.js"; // + +const styles = html` + +`; + +class App extends Component { + constructor() { + super(); + this.shadow = true; + this.state = { + samples: [] + }; + this.loadDatabases(); + } + + loadDatabases() { + this.setState({ + databases: ENV.generateData().toArray() + }); + Monitoring.renderRate.ping(); + setTimeout(this.loadDatabases.bind(this), ENV.timeout); + } + + render() { + const databases = this.state.databases.map(database => { + return html``; + }); + return html` + ${styles} +
+ + + ${databases} + +
+
`; + } +} + +customElements.define("dbmon-app", App); diff --git a/totes/elements/database.js b/totes/elements/database.js new file mode 100644 index 00000000..d181d609 --- /dev/null +++ b/totes/elements/database.js @@ -0,0 +1,71 @@ +import { html, Component } from "https://unpkg.com/@aaronshaf/totes@1/index.js"; +import "./query.js"; // + +const styles = html` + +`; + +class Database extends Component { + static get observedProperties() { + return ["lastMutationId", "dbname", "samples", "lastSample"]; + } + constructor() { + super(); + this.shadow = true; + } + render() { + const queries = this.props.lastSample.topFiveQueries.map(query => { + return html``; + }); + return html` + ${styles} + + ${this.props.dbname} + + + + ${this.props.lastSample.nbQueries} + + + ${queries}`; + } +} + +customElements.define("dbmon-database", Database); diff --git a/totes/elements/popover.js b/totes/elements/popover.js new file mode 100644 index 00000000..bb52b5a4 --- /dev/null +++ b/totes/elements/popover.js @@ -0,0 +1,92 @@ +import { html, Component } from "https://unpkg.com/@aaronshaf/totes@1/index.js"; + +const styles = html` + +`; + +class Popover extends Component { + static get observedProperties() { + return ["query"]; + } + constructor() { + super(); + this.shadow = true; + } + render() { + return html` + ${styles} +
+
${this.props.query}
+
+
`; + } +} + +customElements.define("dbmon-popover", Popover); diff --git a/totes/elements/query.js b/totes/elements/query.js new file mode 100644 index 00000000..26d02b2a --- /dev/null +++ b/totes/elements/query.js @@ -0,0 +1,41 @@ +import { html, Component } from "https://unpkg.com/@aaronshaf/totes@1/index.js"; +import "./popover.js"; // + +const styles = html` + +`; + +class Query extends Component { + static get observedProperties() { + return ["query", "elapsed", "formatElapsed", "elapsedClassName"]; + } + constructor() { + super(); + this.shadow = true; + } + render() { + this.className = "Query " + this.props.elapsedClassName; + return html` + ${styles} ${this.props.formatElapsed || " "} + `; + } +} + +customElements.define("dbmon-query", Query); diff --git a/totes/index.html b/totes/index.html new file mode 100644 index 00000000..4f8c0212 --- /dev/null +++ b/totes/index.html @@ -0,0 +1,19 @@ + + + + + + + dbmon (totes) + + + + + + + + + + + + \ No newline at end of file