index.html 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <link rel="shortcut icon" type="image/x-icon" href="style/favicon.ico"/>
  6. <link href="style/style.css" rel="stylesheet" type="text/css" />
  7. <link href="style/bootstrap.min.css" rel="stylesheet" type="text/css" />
  8. <script src="js/jquery-3.5.1.min.js"></script>
  9. <script src="js/bootstrap.min.js"></script>
  10. <script src="js/gatling.js"></script>
  11. <script src="js/menu.js"></script>
  12. <script src="js/ellipsis.js"></script>
  13. <script src="js/all_sessions.js"></script>
  14. <script src="js/stats.js"></script>
  15. <script src="js/highstock.js"></script>
  16. <script src="js/highcharts-more.js"></script>
  17. <script src="js/theme.js"></script>
  18. <script src="js/unpack.js"></script>
  19. <title>Gatling Stats - Global Information</title>
  20. </head>
  21. <body>
  22. <script>
  23. const storedTheme = localStorage.getItem('theme') || (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
  24. if (storedTheme) document.documentElement.setAttribute('data-theme', storedTheme)
  25. function toggleTheme() {
  26. const currentTheme = document.documentElement.getAttribute("data-theme");
  27. const targetTheme = currentTheme === "light" ? "dark" : "light";
  28. document.documentElement.setAttribute('data-theme', targetTheme)
  29. localStorage.setItem('theme', targetTheme);
  30. };
  31. </script>
  32. <div class="app-container">
  33. <div class="frise"></div>
  34. <div class="head">
  35. <div class="gatling-open-source">
  36. <a class="gatling-logo gatling-logo-light" href="https://gatling.io" target="blank_" title="Gatling Home Page"><img alt="Gatling" src="style/logo-light.svg"/></a>
  37. <a class="gatling-logo gatling-logo-dark" href="https://gatling.io" target="blank_" title="Gatling Home Page"><img alt="Gatling" src="style/logo-dark.svg"/></a>
  38. <a class="gatling-documentation" href="https://gatling.io/docs/" target="_blank">Documentation</a>
  39. </div>
  40. <div class="nav spacer"></div>
  41. <a class="enterprise" href="https://gatling.io/enterprise/next-step/" target="_blank"><strong>Try</strong>
  42. <img class="logo-enterprise-light" alt="Gatling Enterprise" src="style/logo-enterprise-light.svg"/>
  43. <img class="logo-enterprise-dark" alt="Gatling Enterprise" src="style/logo-enterprise-dark.svg"/>
  44. </a>
  45. <button id="theme-toggle" class="theme-toggle" type="button" onclick="toggleTheme()" aria-label="Toggle user interface mode">
  46. <span class="toggle-dark"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg></span>
  47. <span class="toggle-light"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-sun"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg></span>
  48. </button>
  49. </div>
  50. <div class="container details">
  51. <div class="nav">
  52. <ul></ul>
  53. </div>
  54. <div class="cadre">
  55. <div class="content">
  56. <div class="content-header">
  57. <div class="onglet">
  58. WebSocketEchoSimulation
  59. </div>
  60. <div class="sous-menu" id="sousMenu">
  61. <div class="sous-menu-spacer">
  62. <div class="item ouvert"><a href="index.html">Global</a></div>
  63. <div class="item "><a id="details_link" href="#">Details</a></div>
  64. </div>
  65. </div>
  66. </div>
  67. <div class="content-in">
  68. <div class="container-article">
  69. <div class="article">
  70. <div class="schema-container">
  71. <div id="ranges" class="schema ranges">
  72. </div>
  73. <div class="schema polar">
  74. <div id="container_number_of_requests"></div>
  75. </div>
  76. <div class="simulation-card">
  77. <div class="simulation-version-information">
  78. <span class="simulation-information-title">Gatling Version</span>
  79. <span class="simulation-information-item">
  80. <span class="simulation-information-label">Version: </span>
  81. <span>3.10.5</span>
  82. </span>
  83. <span class="simulation-information-item">
  84. <span class="simulation-information-label">Released: </span>
  85. <span>2024-03-22</span>
  86. </span>
  87. </div>
  88. <div id="simulation-information" class="simulation-version-information">
  89. <span class="simulation-information-title">Run Information</span>
  90. <div class="simulation-information-container">
  91. <span class="simulation-information-item">
  92. <span class="simulation-information-label">Date: </span>
  93. <span>2025-06-03 14:47:04 GMT</span>
  94. </span>
  95. <span class="simulation-information-item">
  96. <span class="simulation-information-label">Duration: </span>
  97. <span>2s </span>
  98. </span>
  99. <span class="simulation-information-item">
  100. <span class="simulation-information-label">Description: </span>
  101. <span>&mdash;</span>
  102. </span>
  103. </div>
  104. </div>
  105. </div>
  106. </div>
  107. <div id="statistics_table_container">
  108. <div id="stats" class="statistics extensible-geant collapsed">
  109. <div class="title">
  110. <div id="statistics_title" class="title_base"><span class="title_base_stats">Stats</span><span class="expand-table">Fixed height</span><span id="toggle-stats" class="toggle-table"></span><span class="collapse-table">Full size</span></div>
  111. <div class="right">
  112. <button class="statistics-button expand-all-button">Expand all groups</button>
  113. <button class="statistics-button collapse-all-button">Collapse all groups</button>
  114. <button id="statistics_full_screen" class="statistics-button" onclick="openStatisticsTableModal()"><img alt="Fullscreen" src="style/fullscreen.svg"></button>
  115. </div>
  116. </div>
  117. <div class="scrollable">
  118. <table id="container_statistics_head" class="statistics-in extensible-geant">
  119. <thead>
  120. <tr>
  121. <th rowspan="2" id="col-1" class="header sortable sorted-up"><span>Requests</span></th>
  122. <th colspan="5" class="header"><span class="executions">Executions</span></th>
  123. <th colspan="8" class="header"><span class="response-time">Response Time (ms)</span></th>
  124. </tr>
  125. <tr>
  126. <th id="col-2" class="header sortable"><span>Total</span></th>
  127. <th id="col-3" class="header sortable"><span>OK</span></th>
  128. <th id="col-4" class="header sortable"><span>KO</span></th>
  129. <th id="col-5" class="header sortable"><span>% KO</span></th>
  130. <th id="col-6" class="header sortable"><span><abbr title="Count of events per second">Cnt/s</abbr></span></th>
  131. <th id="col-7" class="header sortable"><span>Min</span></th>
  132. <th id="col-8" class="header sortable"><span>50th pct</span></th>
  133. <th id="col-9" class="header sortable"><span>75th pct</span></th>
  134. <th id="col-10" class="header sortable"><span>95th pct</span></th>
  135. <th id="col-11" class="header sortable"><span>99th pct</span></th>
  136. <th id="col-12" class="header sortable"><span>Max</span></th>
  137. <th id="col-13" class="header sortable"><span>Mean</span></th>
  138. <th id="col-14" class="header sortable"><span><abbr title="Standard Deviation">Std Dev</abbr></span></th>
  139. </tr>
  140. </thead>
  141. <tbody></tbody>
  142. </table>
  143. <table id="container_statistics_body" class="statistics-in extensible-geant">
  144. <tbody></tbody>
  145. </table>
  146. </div>
  147. </div>
  148. </div>
  149. <dialog id="statistics_table_modal" class="statistics-table-modal">
  150. <div class="statistics-table-modal-header"><button class="button-modal" onclick="closeStatisticsTableModal()"><img alt="Close" src="style/close.svg"></button></div>
  151. <div class="statistics-table-modal-container">
  152. <div id="statistics_table_modal_content" class="statistics-table-modal-content"></div>
  153. </div>
  154. </dialog>
  155. <script>
  156. function openStatisticsTableModal () {
  157. const statsTable = document.getElementById("stats");
  158. const statsTableModal = document.getElementById("statistics_table_modal");
  159. const fullScreenButton = document.getElementById("statistics_full_screen");
  160. fullScreenButton.disabled = true;
  161. if (typeof statsTableModal.showModal === "function") {
  162. const statsTableModalContent = document.getElementById("statistics_table_modal_content");
  163. statsTableModalContent.innerHTML = "";
  164. statsTableModalContent.appendChild(statsTable);
  165. statsTableModal.showModal();
  166. statsTableModal.addEventListener("close", function () {
  167. const container = document.getElementById("statistics_table_container");
  168. container.appendChild(statsTable);
  169. fullScreenButton.disabled = false;
  170. });
  171. } else {
  172. const incompatibleBrowserVersionMessage = document.createElement("div");
  173. incompatibleBrowserVersionMessage.innerText = "Sorry, the <dialog> API is not supported by this browser.";
  174. statsTable.insertBefore(incompatibleBrowserVersionMessage, statsTable.children[0]);
  175. }
  176. }
  177. function closeStatisticsTableModal () {
  178. const statsTableModal = document.getElementById("statistics_table_modal");
  179. statsTableModal.close();
  180. }
  181. </script>
  182. <div class="statistics extensible-geant collapsed">
  183. <div class="title">
  184. Errors
  185. </div>
  186. <table id="container_errors" class="statistics-in extensible-geant">
  187. <thead>
  188. <tr>
  189. <th id="error-col-1" class="header sortable"><span>Error</span></th>
  190. <th id="error-col-2" class="header sortable"><span>Count</span></th>
  191. <th id="error-col-3" class="header sortable"><span>Percentage</span></th>
  192. </tr>
  193. </thead>
  194. <tbody>
  195. <tr>
  196. <td class="error-col-1 total ko">Client issued text frame but server has closed the WebSocket and max reconnects is reached<span class="value" style="display:none">0</span></td>
  197. <td class="value error-col-2 total ko">1</td>
  198. <td class="value error-col-3 total ko">33.333 %</td>
  199. </tr>
  200. <tr>
  201. <td class="error-col-1 total ko">Close Connection: Client issued close order but WebSocket was already crashed: i.n.h.c.h.w.WebSocketClientHandshakeException: Invalid handshake response getStatus: 503 Service Unavailable <span class="value" style="display:none">1</span></td>
  202. <td class="value error-col-2 total ko">1</td>
  203. <td class="value error-col-3 total ko">33.333 %</td>
  204. </tr>
  205. <tr>
  206. <td class="error-col-1 total ko">i.n.h.c.h.w.WebSocketClientHandshakeException: Invalid handshake response getStatus: 503 Service Unavailable<span class="value" style="display:none">2</span></td>
  207. <td class="value error-col-2 total ko">1</td>
  208. <td class="value error-col-3 total ko">33.333 %</td>
  209. </tr>
  210. </tbody>
  211. </table>
  212. </div>
  213. <div class="schema geant">
  214. <div id="active_users" class="geant"></div>
  215. </div>
  216. <div class="schema geant">
  217. <div id="responsetimeDistributionContainer" class="geant"></div>
  218. </div>
  219. <div class="schema geant">
  220. <div id="responsetimepercentilesovertimeokPercentilesContainer" class="geant"></div>
  221. </div>
  222. <div class="schema geant">
  223. <div id="requests" class="geant"></div>
  224. </div>
  225. <div class="schema geant">
  226. <div id="responses" class="geant"></div>
  227. </div>
  228. </div>
  229. </div>
  230. </div>
  231. </div>
  232. </div>
  233. </div>
  234. <script>
  235. var pageStats = stats.stats;
  236. $(document).ready(function() {
  237. $('.simulation-tooltip').popover({trigger:'hover', placement:'left'});
  238. setDetailsLinkUrl();
  239. setGlobalMenu();
  240. setActiveMenu();
  241. fillStats(pageStats);
  242. Highcharts.setOptions({
  243. global: { useUTC: false }
  244. });
  245. var rangesChart = new Highcharts.Chart({
  246. chart: {
  247. renderTo: 'ranges',
  248. marginRight: 100
  249. },
  250. credits: { enabled: false },
  251. legend: { enabled: false },
  252. title: { text: 'A title to let highcharts reserve the place for the title set later' },
  253. xAxis: {
  254. categories: [
  255. pageStats.group1.htmlName,
  256. pageStats.group2.htmlName,
  257. pageStats.group3.htmlName,
  258. pageStats.group4.htmlName
  259. ]
  260. },
  261. yAxis: {
  262. title: { text: 'Number of Requests' },
  263. reversedStacks: false
  264. },
  265. tooltip: {
  266. formatter: function() {
  267. var s;
  268. if (this.point.name) { // the pie chart
  269. s = ''+ this.point.name +': '+ this.y +'% requests';
  270. } else {
  271. s = ''+ this.y + ' requests';
  272. }
  273. return s;
  274. }
  275. },
  276. plotOptions: {
  277. series: {
  278. stacking: 'normal',
  279. shadow: true
  280. }
  281. },
  282. series: [
  283. {
  284. type: 'column',
  285. data: [{
  286. color: '#68b65c',
  287. y: pageStats.group1.count
  288. },
  289. {
  290. color: '#FFDD00',
  291. y: pageStats.group2.count
  292. },
  293. {
  294. color: '#FFA900',
  295. y: pageStats.group3.count
  296. },
  297. {
  298. color: '#f15b4f',
  299. y: pageStats.group4.count
  300. }]
  301. },
  302. {
  303. type: 'pie',
  304. name: 'Percentages',
  305. data: [
  306. {
  307. name: pageStats.group1.name,
  308. y: pageStats.group1.percentage,
  309. color: '#68b65c'
  310. },
  311. {
  312. name: pageStats.group2.name,
  313. y: pageStats.group2.percentage,
  314. color: '#FFDD00'
  315. },
  316. {
  317. name: pageStats.group3.name,
  318. y: pageStats.group3.percentage,
  319. color: '#FFA900'
  320. },
  321. {
  322. name: pageStats.group4.name,
  323. y: pageStats.group4.percentage,
  324. color: '#f15b4f'
  325. }
  326. ],
  327. center: [345, 0],
  328. size: 90,
  329. showInLegend: false,
  330. dataLabels: { enabled: false }
  331. }
  332. ]
  333. });
  334. rangesChart.setTitle({
  335. text: '<span class="chart_title">Response Time Ranges</span>',
  336. useHTML: true
  337. });
  338. function numberOfRequestsDataForGroup(group) {
  339. var data = {names: [], oks: [], kos: []};
  340. $.each(group.contents, function(contentName, content) {
  341. if (content.type == 'GROUP') {
  342. var result = numberOfRequestsDataForGroup(content);
  343. data.names = data.names.concat(result.names);
  344. data.oks = data.oks.concat(result.oks);
  345. data.kos = data.kos.concat(result.kos);
  346. }
  347. else if (content.type == 'REQUEST') {
  348. data.names.push(content.path);
  349. data.oks.push(parseInt(content.stats.numberOfRequests.ok));
  350. data.kos.push(parseInt(content.stats.numberOfRequests.ko));
  351. }
  352. });
  353. return data;
  354. }
  355. var numberOfRequestsData = numberOfRequestsDataForGroup(stats);
  356. var tickInterval = Math.ceil(numberOfRequestsData.names.length / 1000);
  357. new Highcharts.Chart({
  358. chart: {
  359. renderTo:'container_number_of_requests',
  360. polar:true,
  361. type:'column',
  362. height:330
  363. },
  364. credits:{
  365. enabled:false
  366. },
  367. title:{
  368. text:'<span class="chart_title">Number of requests</span>',
  369. useHTML: true,
  370. widthAdjust:-20
  371. },
  372. xAxis:{
  373. tickmarkPlacement:'on',
  374. tickInterval: tickInterval,
  375. categories:numberOfRequestsData.names,
  376. labels:{ enabled:false }
  377. },
  378. yAxis:{
  379. min:0,
  380. reversedStacks: false
  381. },
  382. plotOptions:{
  383. series:{
  384. stacking:'normal',
  385. groupPadding:0,
  386. pointPlacement:'on',
  387. shadow: true
  388. }
  389. },
  390. legend: {
  391. borderWidth: 0,
  392. itemStyle: { fontWeight: "normal" },
  393. symbolRadius: 0
  394. },
  395. series:[
  396. {
  397. name:'OK',
  398. data:numberOfRequestsData.oks,
  399. color:"#68b65c"
  400. },
  401. {
  402. name:'KO',
  403. data:numberOfRequestsData.kos,
  404. color:"#f15b4f"
  405. }
  406. ]
  407. });
  408. $('#container_exceptions').sortable('#container_exceptions');
  409. function generateHtmlRow(request, level, index, parent, group) {
  410. if (request.name == 'All Requests')
  411. var url = 'index.html';
  412. else
  413. var url = request.pathFormatted + '.html';
  414. if (group)
  415. var expandButtonStyle = '';
  416. else
  417. var expandButtonStyle = ' hidden';
  418. if (request.stats.numberOfRequests.total != 0)
  419. var koPercent = (request.stats.numberOfRequests.ko * 100 / request.stats.numberOfRequests.total).toFixed(0) + '%';
  420. else
  421. var koPercent = '-'
  422. return '<tr id="' + request.pathFormatted + '" data-parent=' + parent + '> \
  423. <td class="total col-1"> \
  424. <div class="expandable-container"> \
  425. <span id="' + request.pathFormatted + '" style="margin-left: ' + (level * 10) + 'px;" class="expand-button' + expandButtonStyle + '">&nbsp;</span> \
  426. <a href="' + url +'" class="withTooltip">' + ellipsedLabel({ name: request.name, parentClass: "table-cell-tooltip" }) + '</a><span class="value" style="display:none;">' + index + '</span> \
  427. </div> \
  428. </td> \
  429. <td class="value total col-2">' + request.stats.numberOfRequests.total + '</td> \
  430. <td class="value ok col-3">' + request.stats.numberOfRequests.ok + '</td> \
  431. <td class="value ko col-4">' + request.stats.numberOfRequests.ko + '</td> \
  432. <td class="value ko col-5">' + koPercent + '</td> \
  433. <td class="value total col-6">' + request.stats.meanNumberOfRequestsPerSecond.total + '</td> \
  434. <td class="value total col-7">' + request.stats.minResponseTime.total + '</td> \
  435. <td class="value total col-8">' + request.stats.percentiles1.total + '</td> \
  436. <td class="value total col-9">' + request.stats.percentiles2.total + '</td> \
  437. <td class="value total col-10">' + request.stats.percentiles3.total + '</td> \
  438. <td class="value total col-11">' + request.stats.percentiles4.total + '</td> \
  439. <td class="value total col-12">' + request.stats.maxResponseTime.total + '</td> \
  440. <td class="value total col-13">' + request.stats.meanResponseTime.total + '</td> \
  441. <td class="value total col-14">' + request.stats.standardDeviation.total + '</td> \
  442. </tr>';
  443. }
  444. function generateHtmlRowsForGroup(group, level, index, parent) {
  445. var buffer = '';
  446. if (!parent)
  447. parent = 'ROOT';
  448. else {
  449. buffer += generateHtmlRow(group, level - 1, index, parent, true);
  450. index++;
  451. parent = group.pathFormatted;
  452. }
  453. $.each(group.contents, function(contentName, content) {
  454. if (content.type == 'GROUP') {
  455. var result = generateHtmlRowsForGroup(content, level + 1, index, parent);
  456. buffer += result.html;
  457. index = result.index;
  458. }
  459. else if (content.type == 'REQUEST') {
  460. buffer += generateHtmlRow(content, level, index, parent);
  461. index++;
  462. }
  463. });
  464. return { html: buffer, index: index };
  465. }
  466. $('#container_statistics_head tbody').append(generateHtmlRow(stats, 0, 0));
  467. var lines = generateHtmlRowsForGroup(stats, 0, 0);
  468. $('#container_statistics_body tbody').append(lines.html);
  469. $('#container_statistics_head').sortable('#container_statistics_body');
  470. $('.statistics').expandable();
  471. if (lines.index < 30) {
  472. $('#statistics_title span').attr('style', 'display: none;');
  473. } else {
  474. $('#statistics_title').addClass('title_collapsed');
  475. $('#statistics_title').click(function() {
  476. $('#toggle-stats').toggleClass("off");
  477. $(this).toggleClass('title_collapsed').toggleClass('title_expanded');
  478. $('#container_statistics_body').parent().toggleClass('scrollable').toggleClass('');
  479. });
  480. }
  481. $('.table-cell-tooltip').popover({trigger:'hover'});
  482. $('#container_errors').sortable('#container_errors');
  483. allUsersData.yAxis = 0;
  484. var allUsersChart = new Highcharts.StockChart({
  485. chart: {
  486. renderTo: 'active_users',
  487. zoomType: 'x'
  488. },
  489. credits: { enabled: false },
  490. legend: {
  491. enabled: true,
  492. floating: true,
  493. align: 'right',
  494. verticalAlign: 'top',
  495. layout: 'vertical',
  496. borderWidth: 0,
  497. itemStyle: { fontWeight: "normal" },
  498. symbolRadius: 0
  499. },
  500. title: { text: 'A title to let highcharts reserve the place for the title set later' },
  501. navigator: {
  502. maskInside: false
  503. },
  504. rangeSelector: {
  505. buttonSpacing: 0,
  506. buttonTheme: {
  507. fill: '#CFC9C6',
  508. padding: 1,
  509. stroke: '#000000',
  510. 'stroke-width': 0.25,
  511. style: {
  512. color: '#000000',
  513. fontWeight: 'bold',
  514. },
  515. states: {
  516. stroke: '#000000',
  517. 'stroke-width': 0.25,
  518. hover: {
  519. fill: '#92918C',
  520. style: { color: 'black' }
  521. },
  522. select: {
  523. fill: '#FFA900',
  524. style: { color: 'white' }
  525. }
  526. }
  527. },
  528. buttons : [
  529. {
  530. type : 'minute',
  531. count : 1,
  532. text : '1m'
  533. }, {
  534. type : 'minute',
  535. count : 10,
  536. text : '10m'
  537. }, {
  538. type : 'hour',
  539. count : 1,
  540. text : '1h'
  541. }, {
  542. type : 'all',
  543. count : 1,
  544. text : 'All'
  545. }
  546. ],
  547. selected : 3,
  548. inputEnabled : false
  549. },
  550. xAxis: {
  551. type: 'datetime',
  552. ordinal: false,
  553. maxZoom: 10000 // three days
  554. },
  555. yAxis: {
  556. title: { text: 'Number of Active Users' },
  557. opposite: false,
  558. min: 0
  559. },
  560. series: [
  561. {
  562. color: '#5E7BE2',
  563. name: 'WebSocket Echo Test',
  564. data: [
  565. [1748962025000,1],[1748962026000,1],[1748962027000,1]
  566. ],
  567. tooltip: { yDecimals: 0, ySuffix: '', valueDecimals: 0 }},
  568. allUsersData
  569. ]
  570. });
  571. allUsersChart.setTitle({
  572. text: '<span class="chart_title">Active Users along the Simulation</span>',
  573. useHTML: true
  574. });
  575. allUsersData.yAxis = 1;
  576. var responsetimeDistributionChart = new Highcharts.Chart({
  577. chart: {
  578. renderTo: 'responsetimeDistributionContainer',
  579. type: 'column',
  580. marginBottom: 60
  581. },
  582. credits: { enabled: false },
  583. legend: {
  584. enabled: true,
  585. floating: true,
  586. y: 5,
  587. borderWidth: 0,
  588. itemStyle: { fontWeight: "normal" },
  589. symbolRadius: 0
  590. },
  591. title: { text: 'A title to let highcharts reserve the place for the title set later' },
  592. navigator: {
  593. maskInside: false
  594. },
  595. xAxis: {
  596. categories: ['3', '8', '13', '18', '24', '29', '34', '40', '45', '50', '55', '61', '66', '71', '76', '82', '87', '92', '97', '103', '108', '113', '119', '124', '129', '134', '140', '145', '150', '155', '161', '166', '171', '177', '182', '187', '192', '198', '203', '208', '213', '219', '224', '229', '235', '240', '245', '250', '256', '261', '266', '271', '277', '282', '287', '292', '298', '303', '308', '314', '319', '324', '329', '335', '340', '345', '350', '356', '361', '366', '372', '377', '382', '387', '393', '398', '403', '408', '414', '419', '424', '430', '435', '440', '445', '451', '456', '461', '466', '472', '477', '482', '487', '493', '498', '503', '509', '514', '519', '524', '530'],
  597. tickInterval: 20
  598. },
  599. yAxis: {
  600. min: 0,
  601. title: { text: 'Percentage of Requests' },
  602. reversedStacks: false
  603. },
  604. tooltip: {
  605. formatter: function() {
  606. return '<b>'+ this.x +' ms</b><br/>'+
  607. this.series.name +': '+ this.y +' %<br/>'+
  608. 'Total: '+ this.point.stackTotal + ' %';
  609. }
  610. },
  611. plotOptions: {
  612. series: {
  613. groupPadding: 0,
  614. stacking: 'normal',
  615. shadow: true
  616. }
  617. },
  618. series: [
  619. {
  620. type: 'column',
  621. color: '#68b65c',
  622. name: 'OK',
  623. data: [
  624. 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
  625. ],
  626. tooltip: { yDecimals: 0, ySuffix: 'ms' }
  627. },
  628. {
  629. type: 'column',
  630. color: '#f15b4f',
  631. name: 'KO',
  632. data: [
  633. 50.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,50.0,0.0
  634. ],
  635. tooltip: { yDecimals: 0, ySuffix: 'ms' }
  636. }
  637. ]
  638. });
  639. responsetimeDistributionChart.setTitle({
  640. text: '<span class="chart_title">Response Time Distribution</span>',
  641. useHTML: true
  642. });
  643. var responsetimepercentilesovertimeokPercentiles = unpack([[1748962025,null],[1748962026,null],[1748962027,null]]);
  644. var responsetimepercentilesovertimeokPercentilesChart = new Highcharts.StockChart({
  645. chart: {
  646. renderTo: 'responsetimepercentilesovertimeokPercentilesContainer',
  647. zoomType: 'x',
  648. marginBottom: 60
  649. },
  650. colors: ['#c4fd90', '#7ff77f', '#6ff2ad', '#61ede6', '#58c7e0', '#4ea1d4', '#487ad9', '#3f52cc', '#7335dc', '#c73905', '#FFA900'],
  651. credits: { enabled: false },
  652. legend: {
  653. enabled: true,
  654. floating: true,
  655. y: -65,
  656. borderWidth: 0,
  657. itemStyle: { fontWeight: "normal" },
  658. symbolRadius: 0
  659. },
  660. title: { text: 'A title to let highcharts reserve the place for the title set later' },
  661. navigator: {
  662. maskInside: false,
  663. baseSeries: 9
  664. },
  665. rangeSelector: {
  666. rangeSelector: { align: "left" },
  667. buttonSpacing: 0,
  668. buttonTheme: {
  669. fill: '#CFC9C6',
  670. padding: 1,
  671. stroke: '#000000',
  672. 'stroke-width': 0.25,
  673. style: {
  674. color: '#000000',
  675. fontWeight: 'bold',
  676. },
  677. states: {
  678. stroke: '#92918C',
  679. 'stroke-width': 0.25,
  680. hover: {
  681. fill: '#92918C',
  682. style: { color: 'black' }
  683. },
  684. select: {
  685. fill: '#FFA900',
  686. style: { color: 'white' }
  687. }
  688. }
  689. },
  690. buttons : [
  691. {
  692. type : 'minute',
  693. count : 1,
  694. text : '1m'
  695. }, {
  696. type : 'minute',
  697. count : 10,
  698. text : '10m'
  699. }, {
  700. type : 'hour',
  701. count : 1,
  702. text : '1h'
  703. }, {
  704. type : 'all',
  705. count : 1,
  706. text : 'All'
  707. }
  708. ],
  709. selected : 3,
  710. inputEnabled : false
  711. },
  712. xAxis: {
  713. type: 'datetime',
  714. ordinal: false,
  715. maxZoom: 10000 // three days
  716. },
  717. yAxis:[
  718. {
  719. min: 0,
  720. title: { text: 'Response Time (ms)' },
  721. opposite: false
  722. }, {
  723. min: 0,
  724. title: {
  725. text: 'Active Users',
  726. style: { color: '#FFA900' }
  727. },
  728. opposite: true
  729. }
  730. ],
  731. plotOptions: {
  732. arearange: { lineWidth: 1 },
  733. series: {
  734. dataGrouping: { enabled: false }
  735. }
  736. },
  737. series: [
  738. {
  739. pointInterval: 1000,
  740. name: 'min',
  741. data: responsetimepercentilesovertimeokPercentiles[0],
  742. tooltip: { yDecimals: 0, ySuffix: 'ms' },
  743. type : 'area',
  744. yAxis: 0,
  745. zIndex: 10
  746. },
  747. {
  748. pointInterval: 1000,
  749. name: '25%',
  750. data: responsetimepercentilesovertimeokPercentiles[1],
  751. tooltip: { yDecimals: 0, ySuffix: 'ms' },
  752. type : 'area',
  753. yAxis: 0,
  754. zIndex: 9
  755. },
  756. {
  757. pointInterval: 1000,
  758. name: '50%',
  759. data: responsetimepercentilesovertimeokPercentiles[2],
  760. tooltip: { yDecimals: 0, ySuffix: 'ms' },
  761. type : 'area',
  762. yAxis: 0,
  763. zIndex: 8
  764. },
  765. {
  766. pointInterval: 1000,
  767. name: '75%',
  768. data: responsetimepercentilesovertimeokPercentiles[3],
  769. tooltip: { yDecimals: 0, ySuffix: 'ms' },
  770. type : 'area',
  771. yAxis: 0,
  772. zIndex: 7
  773. },
  774. {
  775. pointInterval: 1000,
  776. name: '80%',
  777. data: responsetimepercentilesovertimeokPercentiles[4],
  778. tooltip: { yDecimals: 0, ySuffix: 'ms' },
  779. type : 'area',
  780. yAxis: 0,
  781. zIndex: 6
  782. },
  783. {
  784. pointInterval: 1000,
  785. name: '85%',
  786. data: responsetimepercentilesovertimeokPercentiles[5],
  787. tooltip: { yDecimals: 0, ySuffix: 'ms' },
  788. type : 'area',
  789. yAxis: 0,
  790. zIndex: 5
  791. },
  792. {
  793. pointInterval: 1000,
  794. name: '90%',
  795. data: responsetimepercentilesovertimeokPercentiles[6],
  796. tooltip: { yDecimals: 0, ySuffix: 'ms' },
  797. type : 'area',
  798. yAxis: 0,
  799. zIndex: 4
  800. },
  801. {
  802. pointInterval: 1000,
  803. name: '95%',
  804. data: responsetimepercentilesovertimeokPercentiles[7],
  805. tooltip: { yDecimals: 0, ySuffix: 'ms' },
  806. type : 'area',
  807. yAxis: 0,
  808. zIndex: 3
  809. },
  810. {
  811. pointInterval: 1000,
  812. name: '99%',
  813. data: responsetimepercentilesovertimeokPercentiles[8],
  814. tooltip: { yDecimals: 0, ySuffix: 'ms' },
  815. type : 'area',
  816. yAxis: 0,
  817. zIndex: 2
  818. },
  819. {
  820. pointInterval: 1000,
  821. name: 'max',
  822. data: responsetimepercentilesovertimeokPercentiles[9],
  823. tooltip: { yDecimals: 0, ySuffix: 'ms' },
  824. type : 'area',
  825. yAxis: 0,
  826. zIndex: 1
  827. },
  828. allUsersData
  829. ]
  830. });
  831. responsetimepercentilesovertimeokPercentilesChart.setTitle({
  832. text: '<span class="chart_title chart_title_">Response Time Percentiles over Time (OK)</span>',
  833. useHTML: true
  834. });
  835. var requests = unpack([[1748962025,[1,0,1]],[1748962026,[0,0,0]],[1748962027,[1,0,1]]]);
  836. var requestsChart = new Highcharts.StockChart({
  837. chart: {
  838. renderTo: 'requests',
  839. zoomType: 'x',
  840. marginBottom: 60
  841. },
  842. credits: { enabled: false },
  843. legend: {
  844. enabled: true,
  845. floating: true,
  846. y: -65,
  847. borderWidth: 0,
  848. itemStyle: { fontWeight: "normal" },
  849. symbolRadius: 0
  850. },
  851. title: { text: 'A title to let highcharts reserve the place for the title set later' },
  852. navigator: {
  853. maskInside: false
  854. },
  855. rangeSelector: {
  856. buttonSpacing: 0,
  857. buttonTheme: {
  858. fill: '#CFC9C6',
  859. padding: 1,
  860. stroke: '#000000',
  861. 'stroke-width': 0.25,
  862. style: {
  863. color: '#000000',
  864. fontWeight: 'bold',
  865. },
  866. states: {
  867. stroke: '#000000',
  868. 'stroke-width': 0.25,
  869. hover: {
  870. fill: '#92918C',
  871. style: { color: 'black' }
  872. },
  873. select: {
  874. fill: '#FFA900',
  875. style: { color: 'white' }
  876. }
  877. }
  878. },
  879. buttons : [
  880. {
  881. type : 'minute',
  882. count : 1,
  883. text : '1m'
  884. }, {
  885. type : 'minute',
  886. count : 10,
  887. text : '10m'
  888. }, {
  889. type : 'hour',
  890. count : 1,
  891. text : '1h'
  892. }, {
  893. type : 'all',
  894. count : 1,
  895. text : 'All'
  896. }
  897. ],
  898. selected : 3,
  899. inputEnabled : false
  900. },
  901. plotOptions: {
  902. series: {
  903. dataGrouping: { enabled: false }
  904. },
  905. area: {
  906. stacking: 'normal'
  907. }
  908. },
  909. xAxis: {
  910. type: 'datetime',
  911. ordinal: false,
  912. maxZoom: 10000 // three days
  913. },
  914. yAxis:[
  915. {
  916. min: 0,
  917. title: { text: 'Number of requests' },
  918. opposite: false,
  919. reversedStacks: false
  920. }, {
  921. min: 0,
  922. title: {
  923. text: 'Active Users',
  924. style: { color: '#FFA900' }
  925. },
  926. opposite: true
  927. }
  928. ],
  929. series: [
  930. {
  931. color: '#5E7BE2',
  932. name: 'All',
  933. data: requests[0],
  934. tooltip: { yDecimals: 0, ySuffix: '', valueDecimals: 0 }
  935. ,type: 'area'},
  936. allUsersData
  937. ]
  938. });
  939. requestsChart.setTitle({
  940. text: '<span class="chart_title">Number of requests per second</span>',
  941. useHTML: true
  942. });
  943. var responses = unpack([[1748962025,[0,0,0]],[1748962026,[1,0,1]],[1748962027,[1,0,1]]]);
  944. var requestsChart = new Highcharts.StockChart({
  945. chart: {
  946. renderTo: 'responses',
  947. zoomType: 'x',
  948. marginBottom: 60
  949. },
  950. credits: { enabled: false },
  951. legend: {
  952. enabled: true,
  953. floating: true,
  954. y: -65,
  955. borderWidth: 0,
  956. itemStyle: { fontWeight: "normal" },
  957. symbolRadius: 0
  958. },
  959. title: { text: 'A title to let highcharts reserve the place for the title set later' },
  960. navigator: {
  961. maskInside: false
  962. },
  963. rangeSelector: {
  964. buttonSpacing: 0,
  965. buttonTheme: {
  966. fill: '#CFC9C6',
  967. padding: 1,
  968. stroke: '#000000',
  969. 'stroke-width': 0.25,
  970. style: {
  971. color: '#000000',
  972. fontWeight: 'bold',
  973. },
  974. states: {
  975. stroke: '#000000',
  976. 'stroke-width': 0.25,
  977. hover: {
  978. fill: '#92918C',
  979. style: { color: 'black' }
  980. },
  981. select: {
  982. fill: '#FFA900',
  983. style: { color: 'white' }
  984. }
  985. }
  986. },
  987. buttons : [
  988. {
  989. type : 'minute',
  990. count : 1,
  991. text : '1m'
  992. }, {
  993. type : 'minute',
  994. count : 10,
  995. text : '10m'
  996. }, {
  997. type : 'hour',
  998. count : 1,
  999. text : '1h'
  1000. }, {
  1001. type : 'all',
  1002. count : 1,
  1003. text : 'All'
  1004. }
  1005. ],
  1006. selected : 3,
  1007. inputEnabled : false
  1008. },
  1009. plotOptions: {
  1010. series: {
  1011. dataGrouping: { enabled: false }
  1012. },
  1013. area: {
  1014. stacking: 'normal'
  1015. }
  1016. },
  1017. xAxis: {
  1018. type: 'datetime',
  1019. ordinal: false,
  1020. maxZoom: 10000 // three days
  1021. },
  1022. yAxis:[
  1023. {
  1024. min: 0,
  1025. title: { text: 'Number of responses' },
  1026. opposite: false,
  1027. reversedStacks: false
  1028. }, {
  1029. min: 0,
  1030. title: {
  1031. text: 'Active Users',
  1032. style: { color: '#FFA900' }
  1033. },
  1034. opposite: true
  1035. }
  1036. ],
  1037. series: [
  1038. {
  1039. color: '#5E7BE2',
  1040. name: 'All',
  1041. data: responses[0],
  1042. tooltip: { yDecimals: 0, ySuffix: '', valueDecimals: 0 }
  1043. },
  1044. {
  1045. color: '#68b65c',
  1046. name: 'OK',
  1047. data: responses[1],
  1048. tooltip: { yDecimals: 0, ySuffix: '', valueDecimals: 0 }
  1049. ,type: 'area'},
  1050. {
  1051. color: '#f15b4f',
  1052. name: 'KO',
  1053. data: responses[2],
  1054. tooltip: { yDecimals: 0, ySuffix: '', valueDecimals: 0 }
  1055. ,type: 'area'},
  1056. allUsersData,
  1057. {
  1058. type: 'pie',
  1059. name: 'Distribution',
  1060. data: [
  1061. {name: 'OK', y: 0.0, color: '#68b65c'},{name: 'KO', y: 2.0, color: '#f15b4f'}
  1062. ],
  1063. center: [775, -40],
  1064. size: 70,
  1065. showInLegend: false,
  1066. dataLabels: { enabled: false },
  1067. dataGrouping: { enabled: false }
  1068. }
  1069. ]
  1070. });
  1071. requestsChart.setTitle({
  1072. text: '<span class="chart_title">Number of responses per second</span>',
  1073. useHTML: true
  1074. });
  1075. });
  1076. </script>
  1077. </div>
  1078. </body>
  1079. </html>