jmeter/bin/report-template/content/js/graph.js.fmkr

1429 lines
40 KiB
Plaintext
Raw Normal View History

/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
*/
$(document).ready(function() {
$(".click-title").mouseenter( function( e){
e.preventDefault();
this.style.cursor="pointer";
});
$(".click-title").mousedown( function(event){
event.preventDefault();
});
// Ugly code while this script is shared among several pages
try{
refreshHitsPerSecond();
} catch(e){}
try{
refreshBytesThroughputOverTime();
} catch(e){}
try{
refreshResponseTimePercentiles();
} catch(e){}
$(".portlet-header").css("cursor", "auto");
});
var percentileThreshold = 0;
var showControllersOnly = ${showControllersOnly?c!"false"};
var seriesFilter = ${seriesFilter!"undefined"};
var filtersOnlySampleSeries = ${filtersOnlySampleSeries?c!"false"};
// Fixes time stamps
function fixTimeStamps(series, offset){
$.each(series, function(index, item) {
$.each(item.data, function(index, coord) {
coord[0] += offset;
});
});
}
// Check if the specified jquery object is a graph
function isGraph(object){
return object.data('plot') !== undefined;
}
// Override the specified graph options to fit the requirements of an overview
function prepareOverviewOptions(graphOptions){
var overviewOptions = {
series: {
shadowSize: 0,
lines: {
lineWidth: 1
},
points: {
// Show points on overview only when linked graph does not show
// lines
show: getProperty('series.lines.show', graphOptions) == false,
radius : 1
}
},
xaxis: {
ticks: 2,
axisLabel: null
},
yaxis: {
ticks: 2,
axisLabel: null
},
legend: {
show: false,
container: null
},
grid: {
hoverable: false
},
tooltip: false
};
return $.extend(true, {}, graphOptions, overviewOptions);
}
// Force axes boundaries using graph extra options
function prepareOptions(options, data){
var extraOptions = data.extraOptions;
if(extraOptions !== undefined){
var xOffset = options.xaxis.mode === "time" ? ${(timeZoneOffset?c)!0} : 0;
var yOffset = options.yaxis.mode === "time" ? ${(timeZoneOffset?c)!0} : 0;
var minX = extraOptions.minX;
if(minX !== undefined)
options.xaxis.min = minX + xOffset;
var maxX = extraOptions.maxX;
if(maxX !== undefined)
options.xaxis.max = maxX + xOffset;
var minY = extraOptions.minY;
if(minY !== undefined)
options.yaxis.min = minY + yOffset;
var maxY = extraOptions.maxY;
if(maxY !== undefined)
options.yaxis.max = maxY + yOffset;
}
}
// Filter, mark series and sort data
function prepareSeries(data){
var result = data.result;
// Keep only series when needed
if(seriesFilter && (!filtersOnlySampleSeries || result.supportsControllersDiscrimination)){
// Insensitive case matching
var regexp = new RegExp(seriesFilter, 'i');
result.series = $.grep(result.series, function(series, index){
return regexp.test(series.label);
});
}
// Keep only controllers series when supported and needed
if(result.supportsControllersDiscrimination && showControllersOnly){
result.series = $.grep(result.series, function(series, index){
return series.isController;
});
}
// Sort data and mark series
$.each(result.series, function(index, series) {
series.data.sort(compareByXCoordinate);
series.color = index;
});
}
// Set the zoom on the specified plot object
function zoomPlot(plot, xmin, xmax, ymin, ymax){
var axes = plot.getAxes();
// Override axes min and max options
$.extend(true, axes, {
xaxis: {
options : { min: xmin, max: xmax }
},
yaxis: {
options : { min: ymin, max: ymax }
}
});
// Redraw the plot
plot.setupGrid();
plot.draw();
}
// Prepares DOM items to add zoom function on the specified graph
function setGraphZoomable(graphSelector, overviewSelector){
var graph = $(graphSelector);
var overview = $(overviewSelector);
// Ignore mouse down event
graph.bind("mousedown", function() { return false; });
overview.bind("mousedown", function() { return false; });
// Zoom on selection
graph.bind("plotselected", function (event, ranges) {
// clamp the zooming to prevent infinite zoom
if (ranges.xaxis.to - ranges.xaxis.from < 0.00001) {
ranges.xaxis.to = ranges.xaxis.from + 0.00001;
}
if (ranges.yaxis.to - ranges.yaxis.from < 0.00001) {
ranges.yaxis.to = ranges.yaxis.from + 0.00001;
}
// Do the zooming
var plot = graph.data('plot');
zoomPlot(plot, ranges.xaxis.from, ranges.xaxis.to, ranges.yaxis.from, ranges.yaxis.to);
plot.clearSelection();
// Synchronize overview selection
overview.data('plot').setSelection(ranges, true);
});
// Zoom linked graph on overview selection
overview.bind("plotselected", function (event, ranges) {
graph.data('plot').setSelection(ranges);
});
// Reset linked graph zoom when reseting overview selection
overview.bind("plotunselected", function () {
var overviewAxes = overview.data('plot').getAxes();
zoomPlot(graph.data('plot'), overviewAxes.xaxis.min, overviewAxes.xaxis.max, overviewAxes.yaxis.min, overviewAxes.yaxis.max);
});
}
var responseTimePercentilesInfos = {
data: ${responseTimePercentiles!"{}"},
getOptions: function() {
return {
series: {
points: { show: false }
},
legend: {
noColumns: 2,
show: true,
container: '#legendResponseTimePercentiles'
},
xaxis: {
tickDecimals: 1,
axisLabel: "Percentiles",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Percentile value in ms",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to
// work
},
tooltip: true,
tooltipOpts: {
content: "%s for %x.2 was %y"
},
selection: { mode: "xy" },
};
},
createGraph: function() {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesResponseTimePercentiles"), function(series){
series.curvedLines = {apply: true, tension: 1};
series.threshold = {
below: percentileThreshold,
color: $("#slider-vertical").children("div").css("background-color")
};
});
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotResponseTimesPercentiles"), dataset, options);
// setup overview
$.plot($("#overviewResponseTimesPercentiles"), dataset, prepareOverviewOptions(options));
}
};
// Response times percentiles
function refreshResponseTimePercentiles() {
var infos = responseTimePercentilesInfos;
prepareSeries(infos.data);
if (isGraph($("#flotResponseTimesPercentiles"))){
infos.createGraph();
} else {
var choiceContainer = $("#choicesResponseTimePercentiles");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotResponseTimesPercentiles", "#overviewResponseTimesPercentiles");
$('#bodyResponseTimePercentiles .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
}
var responseTimeDistributionInfos = {
data: ${responseTimeDistribution!"{}"},
getOptions: function() {
var granularity = this.data.result.granularity;
return {
legend: {
noColumns: 2,
show: true,
container: '#legendResponseTimeDistribution'
},
xaxis:{
axisLabel: "Response times in ms",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Number of responses",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
bars : {
show: true,
barWidth: this.data.result.granularity
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to
// work
},
tooltip: true,
tooltipOpts: {
content: function(label, xval, yval, flotItem){
return yval + " responses for " + label + " were between " + xval + " and " + (xval + granularity) + " ms";
}
}
};
},
createGraph: function() {
var data = this.data;
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotResponseTimeDistribution"), prepareData(data.result.series, $("#choicesResponseTimeDistribution")), options);
}
};
// Response time distribution
function refreshResponseTimeDistribution() {
var infos = responseTimeDistributionInfos;
prepareSeries(infos.data);
if (isGraph($("#flotResponseTimeDistribution"))){
infos.createGraph();
}else{
var choiceContainer = $("#choicesResponseTimeDistribution");
createLegend(choiceContainer, infos);
infos.createGraph();
$('#footerResponseTimeDistribution .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
};
var activeThreadsOverTimeInfos = {
data: ${activeThreadsOverTime!"{}"},
getOptions: function() {
return {
series: {
lines: {
show: true
},
points: {
show: true
}
},
xaxis: {
mode: "time",
timeformat: "%H:%M:%S",
axisLabel: getElapsedTimeLabel(this.data.result.granularity),
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Number of active threads",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20
},
legend: {
noColumns: 6,
show: true,
container: '#legendActiveThreadsOverTime'
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to
// work
},
selection: {
mode: 'xy'
},
tooltip: true,
tooltipOpts: {
content: "%s for %x was %y"
}
};
},
createGraph: function() {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesActiveThreadsOverTime"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotActiveThreadsOverTime"), dataset, options);
// setup overview
$.plot($("#overviewActiveThreadsOverTime"), dataset, prepareOverviewOptions(options));
}
};
// Active Threads Over Time
function refreshActiveThreadsOverTime() {
var infos = activeThreadsOverTimeInfos;
prepareSeries(infos.data);
fixTimeStamps(infos.data.result.series, ${(timeZoneOffset?c)!0});
if(isGraph($("#flotActiveThreadsOverTime"))) {
infos.createGraph();
}else{
var choiceContainer = $("#choicesActiveThreadsOverTime");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotActiveThreadsOverTime", "#overviewActiveThreadsOverTime");
$('#footerActiveThreadsOverTime .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
};
var responseTimePerSampleInfos = {
data: ${responseTimePerSample!"{}"},
getOptions: function() {
var ticks = [];
$.each(this.data.result.sampleNames, function(index, item){
ticks.push([index, item]);
});
return {
series: {
bars: {
show: true
}
},
bars: {
align: "center",
barWidth: 0.5,
horizontal: true,
fillColor: { colors: [{ opacity: 0.5 }, { opacity: 1}] },
lineWidth: 1
},
xaxis: {
axisLabel: "Response Time in ms",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
tickColor: "white",
tickFormatter: function (v, axis) {
return $.formatNumber(v, { format: "#,###", locale: "us" });
},
color: "black"
},
yaxis: {
tickColor: "white",
ticks: ticks,
color: "black"
},
legend: {
noColumns: 0,
labelBoxBorderColor: "#858585",
container: '#legendHorizontalBar'
},
grid: {
hoverable: true,
borderWidth: 2,
backgroundColor: { colors: ["white", "white"] }
}
};
},
createGraph: function() {
var data = this.data;
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotResponseTimePerSample"), prepareData(data.result.series, $("#choicesResponseTimePerSample")), options);
}
};
// Response Time Per Sample
function refreshResponseTimePerSample() {
var infos = responseTimePerSampleInfos;
prepareSeries(infos.data);
if (isGraph($("#flotResponseTimePerSample"))){
infos.createGraph();
} else {
var choiceContainer = $("#choicesResponseTimePerSample");
createLegend(choiceContainer, infos);
infos.createGraph();
$('#footerResponseTimePerSample .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
var previousPoint = null, previousLabel = null;
$.fn.UseTooltip = function () {
$(this).bind("plothover", function (event, pos, item) {
if (item) {
if ((previousLabel != item.series.label) ||
(previousPoint != item.dataIndex)) {
previousPoint = item.dataIndex;
previousLabel = item.series.label;
$("#tooltip").remove();
var x = item.datapoint[0];
var y = item.datapoint[1];
var color = item.series.color;
showTooltip(item.pageX,
item.pageY,
color,
"<strong>" + item.series.label + "</strong><br>" + item.series.yaxis.ticks[y].label +
" : <strong>" + $.formatNumber(x, { format: "#,###", locale: "us" }) + "</strong> ms");
}
} else {
$("#tooltip").remove();
previousPoint = null;
}
});
};
function showTooltip(x, y, color, contents) {
$('<div id="tooltip">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y - 10,
left: x + 10,
border: '2px solid ' + color,
padding: '3px',
'font-size': '9px',
'border-radius': '5px',
'background-color': '#fff',
'font-family': 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
opacity: 0.9
}).appendTo("body").fadeIn(200);
}
$("#flotResponseTimePerSample").UseTooltip();
};
var timeVsThreadsInfos = {
data: ${timeVsThreads!"{}"},
getOptions: function() {
return {
series: {
lines: {
show: true
},
points: {
show: true
}
},
xaxis: {
axisLabel: "Number of active threads",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Average response times in ms",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20
},
legend: { noColumns: 2,show: true, container: '#legendTimeVsThreads' },
selection: {
mode: 'xy'
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to work
},
tooltip: true,
tooltipOpts: {
content: "%s for %x.2 was %y.2"
}
};
},
createGraph: function() {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesTimeVsThreads"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotTimesVsThreads"), dataset, options);
// setup overview
$.plot($("#overviewTimesVsThreads"), dataset, prepareOverviewOptions(options));
}
};
// Time vs threads
function refreshTimeVsThreads(){
var infos = timeVsThreadsInfos;
prepareSeries(infos.data);
if(isGraph($("#flotTimesVsThreads"))){
infos.createGraph();
}else{
var choiceContainer = $("#choicesTimeVsThreads");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotTimesVsThreads", "#overviewTimesVsThreads");
$('#footerTimeVsThreads .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
};
var bytesThroughputOverTimeInfos = {
data : ${bytesThroughputOverTime!"{}"},
getOptions : function(){
return {
series: {
lines: {
show: true
},
points: {
show: true
}
},
xaxis: {
mode: "time",
timeformat: "%H:%M:%S",
axisLabel: getElapsedTimeLabel(this.data.result.granularity) ,
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Bytes/sec",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
legend: {
noColumns: 2,
show: true,
container: '#legendBytesThroughputOverTime'
},
selection: {
mode: "xy"
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to
// work
},
tooltip: true,
tooltipOpts: {
content: "%s for %x was %y"
}
};
},
createGraph : function() {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesBytesThroughputOverTime"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotBytesThroughputOverTime"), dataset, options);
// setup overview
$.plot($("#overviewBytesThroughputOverTime"), dataset, prepareOverviewOptions(options));
}
};
// Bytes throughput Over Time
function refreshBytesThroughputOverTime() {
var infos = bytesThroughputOverTimeInfos;
prepareSeries(infos.data);
fixTimeStamps(infos.data.result.series, ${(timeZoneOffset?c)!0});
if(isGraph($("#flotBytesThroughputOverTime"))){
infos.createGraph();
}else{
var choiceContainer = $("#choicesBytesThroughputOverTime");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotBytesThroughputOverTime", "#overviewBytesThroughputOverTime");
$('#footerBytesThroughputOverTime .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
}
var responseTimesOverTimeInfos = {
data: ${responseTimesOverTime!"{}"},
getOptions: function(){
return {
series: {
lines: {
show: true
},
points: {
show: true
}
},
xaxis: {
mode: "time",
timeformat: "%H:%M:%S",
axisLabel: getElapsedTimeLabel(this.data.result.granularity),
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Response time in ms",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
legend: {
noColumns: 2,
show: true,
container: '#legendResponseTimesOverTime'
},
selection: {
mode: 'xy'
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to
// work
},
tooltip: true,
tooltipOpts: {
content: "%s for %x was %y"
}
};
},
createGraph: function() {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesResponseTimesOverTime"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotResponseTimesOverTime"), dataset, options);
// setup overview
$.plot($("#overviewResponseTimesOverTime"), dataset, prepareOverviewOptions(options));
}
};
// Response Times Over Time
function refreshResponseTimeOverTime() {
var infos = responseTimesOverTimeInfos;
prepareSeries(infos.data);
fixTimeStamps(infos.data.result.series, ${(timeZoneOffset?c)!0});
if(isGraph($("#flotResponseTimesOverTime"))){
infos.createGraph();
}else{
var choiceContainer = $("#choicesResponseTimesOverTime");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotResponseTimesOverTime", "#overviewResponseTimesOverTime");
$('#footerResponseTimesOverTime .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
};
var latenciesOverTimeInfos = {
data: ${latenciesOverTime!"{}"},
getOptions: function() {
return {
series: {
lines: {
show: true
},
points: {
show: true
}
},
xaxis: {
mode: "time",
timeformat: "%H:%M:%S",
axisLabel: getElapsedTimeLabel(this.data.result.granularity),
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Response latencies in ms",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
legend: {
noColumns: 2,
show: true,
container: '#legendLatenciesOverTime'
},
selection: {
mode: 'xy'
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to
// work
},
tooltip: true,
tooltipOpts: {
content: "%s for %x was %y"
}
};
},
createGraph: function () {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesLatenciesOverTime"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotLatenciesOverTime"), dataset, options);
// setup overview
$.plot($("#overviewLatenciesOverTime"), dataset, prepareOverviewOptions(options));
}
};
// Latencies Over Time
function refreshLatenciesOverTime() {
var infos = latenciesOverTimeInfos;
prepareSeries(infos.data);
fixTimeStamps(infos.data.result.series, ${(timeZoneOffset?c)!0});
if(isGraph($("#flotLatenciesOverTime"))) {
infos.createGraph();
}else {
var choiceContainer = $("#choicesLatenciesOverTime");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotLatenciesOverTime", "#overviewLatenciesOverTime");
$('#footerLatenciesOverTime .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
};
var responseTimeVsRequestInfos = {
data: ${responseTimeVsRequest!"{}"},
getOptions: function() {
return {
series: {
lines: {
show: false
},
points: {
show: true
}
},
xaxis: {
axisLabel: "Global number of requests per second",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Median Response Time",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
legend: {
noColumns: 2,
show: true,
container: '#legendResponseTimeVsRequest'
},
selection: {
mode: 'xy'
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to work
},
tooltip: true,
tooltipOpts: {
content: "%s for %x was %y"
}
};
},
createGraph: function () {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesResponseTimeVsRequest"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotResponseTimeVsRequest"), dataset, options);
// setup overview
$.plot($("#overviewResponseTimeVsRequest"), dataset, prepareOverviewOptions(options));
}
};
// Response Time vs Request
function refreshResponseTimeVsRequest() {
var infos = responseTimeVsRequestInfos;
prepareSeries(infos.data);
if (isGraph($("#flotResponseTimeVsRequest"))){
infos.create();
}else{
var choiceContainer = $("#choicesResponseTimeVsRequest");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotResponseTimeVsRequest", "#overviewResponseTimeVsRequest");
$('#footerResponseRimeVsRequest .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
};
var latenciesVsRequestInfos = {
data: ${latencyVsRequest!"{}"},
getOptions: function() {
return{
series: {
lines: {
show: false
},
points: {
show: true
}
},
xaxis: {
axisLabel: "Global number of requests per second",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Median Latency",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
legend: { noColumns: 2,show: true, container: '#legendLatencyVsRequest' },
selection: {
mode: 'xy'
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to work
},
tooltip: true,
tooltipOpts: {
content: "%s for %x was %y"
}
};
},
createGraph: function () {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesLatencyVsRequest"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotLatenciesVsRequest"), dataset, options);
// setup overview
$.plot($("#overviewLatenciesVsRequest"), dataset, prepareOverviewOptions(options));
}
};
// Latencies vs Request
function refreshLatenciesVsRequest() {
var infos = latenciesVsRequestInfos;
prepareSeries(infos.data);
if(isGraph($("#flotLatenciesVsRequest"))){
infos.createGraph();
}else{
var choiceContainer = $("#choicesLatencyVsRequest");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotLatenciesVsRequest", "#overviewLatenciesVsRequest");
$('#footerLatenciesVsRequest .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
};
var hitsPerSecondInfos = {
data: ${hitsPerSecond!"{}"},
getOptions: function() {
return {
series: {
lines: {
show: true
},
points: {
show: true
}
},
xaxis: {
mode: "time",
timeformat: "%H:%M:%S",
axisLabel: getElapsedTimeLabel(this.data.result.granularity),
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Number of hits / sec",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20
},
legend: {
noColumns: 2,
show: true,
container: "#legendHitsPerSecond"
},
selection: {
mode : 'xy'
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to
// work
},
tooltip: true,
tooltipOpts: {
content: "%s for %x was %y.2"
}
};
},
createGraph: function createGraph() {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesHitsPerSecond"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotHitsPerSecond"), dataset, options);
// setup overview
$.plot($("#overviewHitsPerSecond"), dataset, prepareOverviewOptions(options));
}
};
// Hits per second
function refreshHitsPerSecond() {
var infos = hitsPerSecondInfos;
prepareSeries(infos.data);
fixTimeStamps(infos.data.result.series, ${(timeZoneOffset?c)!0});
if (isGraph($("#flotHitsPerSecond"))){
infos.createGraph();
}else{
var choiceContainer = $("#choicesHitsPerSecond");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotHitsPerSecond", "#overviewHitsPerSecond");
$('#footerHitsPerSecond .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
}
var codesPerSecondInfos = {
data: ${codesPerSecond!"{}"},
getOptions: function(){
return {
series: {
lines: {
show: true
},
points: {
show: true
}
},
xaxis: {
mode: "time",
timeformat: "%H:%M:%S",
axisLabel: getElapsedTimeLabel(this.data.result.granularity),
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Number of responses/sec",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
legend: {
noColumns: 2,
show: true,
container: "#legendCodesPerSecond"
},
selection: {
mode: 'xy'
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to
// work
},
tooltip: true,
tooltipOpts: {
content: "%s for %x was %y.2"
}
};
},
createGraph: function() {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesCodesPerSecond"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotCodesPerSecond"), dataset, options);
// setup overview
$.plot($("#overviewCodesPerSecond"), dataset, prepareOverviewOptions(options));
}
};
// Codes per second
function refreshCodesPerSecond() {
var infos = codesPerSecondInfos;
prepareSeries(infos.data);
fixTimeStamps(infos.data.result.series, ${(timeZoneOffset?c)!0});
if(isGraph($("#flotCodesPerSecond"))){
infos.createGraph();
}else{
var choiceContainer = $("#choicesCodesPerSecond");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotCodesPerSecond", "#overviewCodesPerSecond");
$('#footerCodesPerSecond .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
};
var transactionsPerSecondInfos = {
data: ${transactionsPerSecond!"{}"},
getOptions: function(){
return {
series: {
lines: {
show: true
},
points: {
show: true
}
},
xaxis: {
mode: "time",
timeformat: "%H:%M:%S",
axisLabel: getElapsedTimeLabel(this.data.result.granularity),
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Number of transactions / sec",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20
},
legend: {
noColumns: 2,
show: true,
container: "#legendTransactionsPerSecond"
},
selection: {
mode: 'xy'
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to
// work
},
tooltip: true,
tooltipOpts: {
content: "%s for %x was %y"
}
};
},
createGraph: function () {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesTransactionsPerSecond"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotTransactionsPerSecond"), dataset, options);
// setup overview
$.plot($("#overviewTransactionsPerSecond"), dataset, prepareOverviewOptions(options));
}
};
// Transactions per second
function refreshTransactionsPerSecond() {
var infos = transactionsPerSecondInfos;
prepareSeries(infos.data);
fixTimeStamps(infos.data.result.series, ${(timeZoneOffset?c)!0});
if(isGraph($("#flotTransactionsPerSecond"))){
infos.createGraph();
}else{
var choiceContainer = $("#choicesTransactionsPerSecond");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotTransactionsPerSecond", "#overviewTransactionsPerSecond");
$('#footerTransactionsPerSecond .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
};
// Collapse the graph matching the specified DOM element depending the collapsed
// status
function collapse(elem, collapsed){
if(collapsed){
$(elem).parent().find(".fa-chevron-up").removeClass("fa-chevron-up").addClass("fa-chevron-down");
} else {
$(elem).parent().find(".fa-chevron-down").removeClass("fa-chevron-down").addClass("fa-chevron-up");
if (elem.id == "bodyResponseTimeOverTime") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshResponseTimeOverTime();
}
document.location.href="#responseTimesOverTime";
} else if (elem.id == "bodyLantenciesOverTime") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshLatenciesOverTime();
}
document.location.href="#latenciesOverTime";
} else if (elem.id == "bodyResponseTimeDistribution") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshResponseTimeDistribution();
}
document.location.href="#responseTimeDistribution" ;
} else if (elem.id == "bodyActiveThreadsOverTime") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshActiveThreadsOverTime();
}
document.location.href="#activeThreadsOverTime";
} else if (elem.id == "bodyResponseTimePerSample") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshResponseTimePerSample();
}
document.location.href="#responseTimePerSample" ;
} else if (elem.id == "bodyTimeVsThreads") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshTimeVsThreads();
}
document.location.href="#timeVsThreads" ;
} else if (elem.id == "bodyCodesPerSecond") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshCodesPerSecond();
}
document.location.href="#codesPerSecond";
} else if (elem.id == "bodyTransactionsPerSecond") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshTransactionsPerSecond();
}
document.location.href="#transactionsPerSecond";
} else if (elem.id == "bodyResponseTimeVsRequest") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshResponseTimeVsRequest();
}
document.location.href="#responseTimeVsRequest";
} else if (elem.id == "bodyLatenciesVsRequest") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshLatenciesVsRequest();
}
document.location.href="#latencyVsRequest";
}
}
}
// Collapse
$(function() {
$('.collapse').on('shown.bs.collapse', function(){
collapse(this, false);
}).on('hidden.bs.collapse', function(){
collapse(this, true);
});
});
$(function() {
$(".glyphicon").mousedown( function(event){
var tmp = $('.in:not(ul)');
tmp.parent().parent().parent().find(".fa-chevron-up").removeClass("fa-chevron-down").addClass("fa-chevron-down");
tmp.removeClass("in");
tmp.addClass("out");
});
});
/*
* Activates or deactivates all series of the specified graph (represented by id parameter)
* depending on checked argument.
*/
function toggleAll(id, checked){
var placeholder = document.getElementById(id);
var cases = $(placeholder).find(':checkbox');
cases.attr('checked', checked);
$(cases).parent().children().children().toggleClass("legend-disabled", !checked);
var choiceContainer;
if ( id == "choicesBytesThroughputOverTime"){
choiceContainer = $("#choicesBytesThroughputOverTime");
refreshBytesThroughputOverTime();
} else if(id == "choicesResponseTimesOverTime"){
choiceContainer = $("#choicesResponseTimesOverTime");
refreshResponseTimeOverTime();
} else if ( id == "choicesLatenciesOverTime"){
choiceContainer = $("#choicesLatenciesOverTime");
refreshLatenciesOverTime();
} else if ( id == "choicesResponseTimePercentiles"){
choiceContainer = $("#choicesResponseTimePercentiles");
refreshResponseTimePercentiles();
} else if(id == "choicesActiveThreadsOverTime"){
choiceContainer = $("#choicesActiveThreadsOverTime");
refreshActiveThreadsOverTime();
} else if ( id == "choicesTimeVsThreads"){
choiceContainer = $("#choicesTimeVsThreads");
refreshTimeVsThreads();
} else if ( id == "choicesResponseTimeDistribution"){
choiceContainer = $("#choicesResponseTimeDistribution");
refreshResponseTimeDistribution();
} else if ( id == "choicesResponseTimePerSample"){
choiceContainer = $("#choicesResponseTimePerSample");
refreshResponseTimePerSample();
} else if ( id == "choicesHitsPerSecond"){
choiceContainer = $("#choicesHitsPerSecond");
refreshHitsPerSecond();
} else if(id == "choicesCodesPerSecond"){
choiceContainer = $("#choicesCodesPerSecond");
refreshCodesPerSecond();
} else if ( id == "choicesTransactionsPerSecond"){
choiceContainer = $("#choicesTransactionsPerSecond");
refreshTransactionsPerSecond();
} else if ( id == "choicesResponseTimeVsRequest"){
choiceContainer = $("#choicesResponseTimeVsRequest");
refreshResponseTimeVsRequest();
} else if ( id == "choicesLatencyVsRequest"){
choiceContainer = $("#choicesLatencyVsRequest");
refreshLatenciesVsRequest();
}
var color = checked ? "black" : "#818181";
choiceContainer.find("label").each(function(){
this.style.color = color;
});
}
// Unchecks all boxes for "Hide all samples" functionality
function uncheckAll(id){
toggleAll(id, false);
}
// Checks all boxes for "Show all samples" functionality
function checkAll(id){
toggleAll(id, true);
}
// Prepares data to be consumed by plot plugins
function prepareData(series, choiceContainer, customizeSeries){
var datasets = [];
// Add only selected series to the data set
choiceContainer.find("input:checked").each(function (index, item) {
var key = $(item).attr("name");
var i = 0;
var size = series.length;
while(i < size && series[i].label != key)
i++;
if(i < size){
var currentSeries = series[i];
datasets.push(currentSeries);
if(customizeSeries)
customizeSeries(currentSeries);
}
});
return datasets;
}
// create slider
$(function() {
$( "#slider-vertical" ).slider({
orientation: "vertical",
range: "min",
min: responseTimePercentilesInfos.data.result.minY,
max: responseTimePercentilesInfos.data.result.maxY,
value: 0,
stop: function(event, ui ) {
percentileThreshold= ui.value;
refreshResponseTimePercentiles();
$("#amount").val(percentileThreshold);
}
});
$("#amount" ).val( $( "#slider-vertical" ).slider( "value" ) );
$("#slider-vertical").children("div").css("background-color","purple");
$("#amount" ).css("color", $("#slider-vertical").children("div").css("background-color"));
$("#slider-vertical").children("div").css("opacity","0.3");
});
/*
* Ignore case comparator
*/
function sortAlphaCaseless(a,b){
return a.toLowerCase() > b.toLowerCase() ? 1 : -1;
};
/*
* Creates a legend in the specified element with graph information
*/
function createLegend(choiceContainer, infos) {
// Sort series by name
var keys = [];
$.each(infos.data.result.series, function(index, series){
keys.push(series.label);
});
keys.sort(sortAlphaCaseless);
// Create list of series with support of activation/deactivation
$.each(keys, function(index, key) {
var id = choiceContainer.attr('id') + index;
$('<li />')
.append($('<input id="' + id + '" name="' + key + '" type="checkbox" checked="checked" hidden />'))
.append($('<label />', { 'text': key , 'for': id }))
.appendTo(choiceContainer);
});
choiceContainer.find("label").click( function(){
if (this.style.color !== "rgb(129, 129, 129)" ){
this.style.color="#818181";
}else {
this.style.color="black";
}
$(this).parent().children().children().toggleClass("legend-disabled");
});
choiceContainer.find("label").mousedown( function(event){
event.preventDefault();
});
choiceContainer.find("label").mouseenter(function(){
this.style.cursor="pointer";
});
// Recreate graphe on series activation toggle
choiceContainer.find("input").click(function(){
infos.createGraph();
});
}