From 8b99eb5b7d39b02fb5876e29e754dd286850bf51 Mon Sep 17 00:00:00 2001 From: Gabe Terrell Date: Mon, 12 Feb 2018 15:47:27 -0600 Subject: [PATCH] Adding missing `.js` files These files are required for usage in `swiftmetrics` and the upcoming `pymetrics` repo. --- js/envTable.js | 142 +++++++++++++++++++++++++++++++ js/httpTop5.js | 226 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 368 insertions(+) create mode 100755 js/envTable.js create mode 100755 js/httpTop5.js diff --git a/js/envTable.js b/js/envTable.js new file mode 100755 index 0000000..001b932 --- /dev/null +++ b/js/envTable.js @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright 2017 IBM Corp. + * + * 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. + ******************************************************************************/ + +// Table for displaying environment parameters + +// Width of environment div +var envDivCanvasWidth = $('#envDiv').width() - 8; + +var tableRowHeight = 30; +var tableRowWidth = 170; + +// Define the environment chart space +var envSVG = d3.select('#envDiv') + .append('svg') + .attr('width', envDivCanvasWidth) + .attr('height', canvasHeight) + .attr('class', 'envData'); + +var envTitleBox = envSVG.append('rect') + .attr('width', envDivCanvasWidth) + .attr('height', 30) + .attr('class', 'titlebox'); + +envSVG.append('text') + .attr('x', 7) + .attr('y', 15) + .attr('dominant-baseline', 'central') + .style('font-size', '18px') + .text(localizedStrings.envTitle); + +var paragraph = envSVG.append('g') + .attr('class', 'envGroup') + .attr('transform', + 'translate(' + 20 + ',' + (margin.top + 10) + ')'); + +var envTableIsFullScreen = false; + +// Add the maximise button +var envResize = envSVG.append('image') + .attr('x', envDivCanvasWidth - 30) + .attr('y', 4) + .attr('width', 24) + .attr('height', 24) + .attr('xlink:href', 'graphmetrics/images/maximize_24_grey.png') + .attr('class', 'maximize') + .on('click', function(){ + envTableIsFullScreen = !envTableIsFullScreen; + d3.selectAll('.hideable').classed('invisible', envTableIsFullScreen); + d3.select('#envDiv') + .classed('fullscreen', envTableIsFullScreen) + .classed('invisible', false); // remove invisible from this chart + if (envTableIsFullScreen) { + d3.select('.envData .maximize') + .attr('xlink:href', 'graphmetrics/images/minimize_24_grey.png'); + // Redraw this chart only + resizeEnvTable(); + } else { + d3.select('.envData .maximize') + .attr('xlink:href', 'graphmetrics/images/maximize_24_grey.png'); + canvasHeight = 250; + // Redraw all + resize(); + } + }) + .on('mouseover', function() { + if (envTableIsFullScreen) { + d3.select('.envData .maximize') + .attr('xlink:href', 'graphmetrics/images/minimize_24.png'); + } else { + d3.select('.envData .maximize') + .attr('xlink:href', 'graphmetrics/images/maximize_24.png'); + } + }) + .on('mouseout', function() { + if (envTableIsFullScreen) { + d3.select('.envData .maximize') + .attr('xlink:href', 'graphmetrics/images/minimize_24_grey.png'); + } else { + d3.select('.envData .maximize') + .attr('xlink:href', 'graphmetrics/images/maximize_24_grey.png'); + } + }); + +function populateEnvTable(envRequestData) { + var envData = JSON.parse(envRequestData); + if (envData == null) return; + function tabulate(data) { + // create a row for each object in the data + var rows = paragraph.selectAll('text') + .data(data) + .enter() + .append('text') + .style('font-size', '14px') + .attr('transform', function(d, i) { + return 'translate(0,' + (i * tableRowHeight) + ')'; + }); + + // create a cell in each row for each column + rows.selectAll('tspan') + .data(function(row) { + return ['Parameter', 'Value'].map(function(column) { + return {column: column, value: row[column]}; + }); + }) + .enter() + .append('tspan') + .attr('x', function(d, i) { + return i * tableRowWidth; // indent second element for each row + }) + .text(function(d) { return d.value; }); + } + // render the table(s) + tabulate(envData); // 2 column table +} + +function resizeEnvTable() { + envDivCanvasWidth = $('#envDiv').width() - 8; // -8 for margins and borders + if (envTableIsFullScreen) { + canvasHeight = $('#envDiv').height() - 100; + } + envResize + .attr('x', envDivCanvasWidth - 30) + .attr('y', 4); + envSVG + .attr('width', envDivCanvasWidth) + .attr('height', canvasHeight); + envTitleBox + .attr('width', envDivCanvasWidth); +} diff --git a/js/httpTop5.js b/js/httpTop5.js new file mode 100755 index 0000000..cbb73e1 --- /dev/null +++ b/js/httpTop5.js @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright 2017 IBM Corp. + * + * 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. + ******************************************************************************/ + +// Bar chart for top 5 URLs by average request time +var httpTop5Data = []; +let httpTop5options = {}; + +var httpTop5_barHeight = tallerGraphHeight / 5; +var httpDiv3CanvasWidth = $('#httpDiv3').width() - 8; // -8 for margin and border +var httpDiv3GraphWidth = httpDiv3CanvasWidth - margin.left - margin.right; +var httpTop5_xScale = d3.scale.linear().range([0, httpDiv3GraphWidth]); + +var httpTop5SVG = d3.select('#httpDiv3') + .append('svg') + .attr('width', httpDiv3CanvasWidth) + .attr('height', canvasHeight) + .attr('class', 'httpTop5Chart'); + +var httpTop5TitleBox = httpTop5SVG.append('rect') + .attr('width', httpDiv3CanvasWidth) + .attr('height', 30) + .attr('class', 'titlebox'); + +var httpTop5Chart = httpTop5SVG.append('g') + .attr('transform', + 'translate(' + margin.left + ',' + margin.top + ')'); + +// Add the title +httpTop5Chart.append('text') + .attr('x', 7 - margin.left) + .attr('y', 15 - margin.top) + .attr('dominant-baseline', 'central') + .style('font-size', '18px') + .text(localizedStrings.httpTop5Title); + +// Add the placeholder text +var httpTop5ChartPlaceholder = httpTop5Chart.append('text') + .attr('x', httpDiv3GraphWidth / 2) + .attr('y', graphHeight / 2) + .attr('text-anchor', 'middle') + .style('font-size', '18px') + .text(localizedStrings.NoDataMsg); + +function convertURL(url, httpDiv3GraphWidth) { + var stringToDisplay = url.toString(); + if (stringToDisplay.startsWith('http://' + httpTop5options.host)) { + stringToDisplay = stringToDisplay.substring(httpTop5options.host.length + 7); + } + // Do a rough calculation to find out whether the URL will need more space than is available and truncate if it does + var stringLength = stringToDisplay.length; + var charSpaceAvailable = Math.floor(httpDiv3GraphWidth / 8); // allow 8 pixels per character (higher than needed but allows space for the time at the end) + if (stringLength > charSpaceAvailable) { + stringToDisplay = '...' + stringToDisplay.substring(stringLength - charSpaceAvailable - 3); + } + return stringToDisplay; +} + +var httpTop5ChartIsFullScreen = false; + +// Add the maximise button +var httpTop5Resize = httpTop5SVG.append('image') + .attr('x', httpDiv3CanvasWidth - 30) + .attr('y', 4) + .attr('width', 24) + .attr('height', 24) + .attr('xlink:href', 'graphmetrics/images/maximize_24_grey.png') + .attr('class', 'maximize') + .on('click', function(){ + httpTop5ChartIsFullScreen = !httpTop5ChartIsFullScreen; + d3.selectAll('.hideable') + .classed('invisible', httpTop5ChartIsFullScreen); + d3.select('#httpDiv3') + .classed('fullscreen', httpTop5ChartIsFullScreen) + .classed('invisible', false); // remove invisible from this chart + if (httpTop5ChartIsFullScreen) { + d3.select('.httpTop5Chart .maximize') + .attr('xlink:href', 'graphmetrics/images/minimize_24_grey.png'); + // Redraw this chart only + resizeHttpTop5Chart(); + } else { + httpDiv3CanvasWidth = $('#httpDiv3').width() - 8; // -8 for margins and borders + httpDiv3GraphWidth = httpDiv3CanvasWidth - margin.left - margin.right; + d3.select('.httpTop5Chart .maximize') + .attr('xlink:href', 'graphmetrics/images/maximize_24_grey.png'); + canvasHeight = 250; + graphHeight = canvasHeight - margin.top - margin.bottom; + // Redraw all + resize(); + } + }) + .on('mouseover', function() { + if (httpTop5ChartIsFullScreen) { + d3.select('.httpTop5Chart .maximize') + .attr('xlink:href', 'graphmetrics/images/minimize_24.png'); + } else { + d3.select('.httpTop5Chart .maximize') + .attr('xlink:href', 'graphmetrics/images/maximize_24.png'); + } + }) + .on('mouseout', function() { + if (httpTop5ChartIsFullScreen) { + d3.select('.httpTop5Chart .maximize') + .attr('xlink:href', 'graphmetrics/images/minimize_24_grey.png'); + } else { + d3.select('.httpTop5Chart .maximize') + .attr('xlink:href', 'graphmetrics/images/maximize_24_grey.png'); + } + }); + +function updateChart() { + httpTop5_xScale.domain([0, d3.max(httpTop5Data, function(d) { + return d.averageResponseTime; + })]); + d3.select('.httpTop5Chart').selectAll('.bar') + .remove(); + var bar = d3.select('.httpTop5Chart').selectAll('.bar') + .data(httpTop5Data) + .enter().append('g') + .attr('class', 'bar') + .attr('transform', function(d, i) { + return 'translate(50,' + (margin.top + i * httpTop5_barHeight) + ')'; + }); + // Background + bar.append('rect') + .attr('width', httpDiv3GraphWidth) + .attr('height', httpTop5_barHeight - 4) + .style('fill', '#9fa7a7'); + bar.append('rect') + .attr('width', function(d) { + return httpTop5_xScale(d.averageResponseTime); + }) + .attr('height', httpTop5_barHeight - 4); + bar.append('text') + .attr('x', 2) + .attr('y', httpTop5_barHeight / 2) + .attr('dy', '.35em') + .attr('fill', 'white') + .text(function(d) { + return convertURL(d.url, httpDiv3GraphWidth); + }); + bar.append('text') + .attr('x', httpDiv3GraphWidth - 2) + .attr('y', httpTop5_barHeight / 2) + .attr('text-anchor', 'end') + .attr('fill', 'white') + .attr('dy', '.35em') + .text(function(d) { + return d3.format(',.2f')(d.averageResponseTime) + 'ms'; + }); + // Tooltip + bar.append('svg:title') + .text(function(d) { return d.url; }); +} + +updateChart(); + +function updateHttpAverages(workingData) { + httpTop5Data = workingData.sort(function(a, b) { + if (a.averageResponseTime > b.averageResponseTime) { + return -1; + } + if (a.averageResponseTime < b.averageResponseTime) { + return 1; + } + // a must be equal to b + return 0; + }); + if (httpTop5options['filteredPath']) { + httpTop5Data = httpTop5Data.filter((d) => { + return !((d.url == httpTop5options.filteredPath) || + d.url.startsWith(httpTop5options.filteredPath + '/')); + }); + } + if (httpTop5Data.length > 5) { + httpTop5Data = httpTop5Data.slice(0, 5); + } + updateChart(); +} + +// Sets the hostname to hide and +// and path to filter from the top 5. +// (The path to the dashboard.) +function setHttpTop5Options(options) { + httpTop5options = options; +} + +function updateURLData(data) { + if (httpTop5Data.length == 0) { + // first data - remove "No Data Available" label + httpTop5ChartPlaceholder.attr('visibility', 'hidden'); + } + var httpTop5RequestData = JSON.parse(data); // parses the data into a JSON array + updateHttpAverages(httpTop5RequestData); +} + +function resizeHttpTop5Chart() { + if (httpTop5ChartIsFullScreen) { + canvasHeight = $('#httpDiv3').height() - 100; + } + httpDiv3CanvasWidth = $('#httpDiv3').width() - 8; + httpTop5Resize + .attr('x', httpDiv3CanvasWidth - 30) + .attr('y', 4); + httpDiv3GraphWidth = httpDiv3CanvasWidth - margin.left - margin.right; + httpTop5_xScale = d3.scale.linear().range([0, httpDiv3GraphWidth]); + var chart = d3.select('.httpTop5Chart'); + chart + .attr('width', httpDiv3CanvasWidth) + .attr('height', canvasHeight); + httpTop5TitleBox + .attr('width', httpDiv3CanvasWidth); + updateChart(); +}