This is an automated email from the ASF dual-hosted git repository. dpavlov pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git
The following commit(s) were added to refs/heads/master by this push: new 94cdf9a IGNITE-9805 Add link to the build's page on TC server, add modal window for 'old' build - Fixes #30. 94cdf9a is described below commit 94cdf9ac4f8f796dd38798566cd96f9b6d3a82f8 Author: Nikolai Kulagin <zzzadruga....@gmail.com> AuthorDate: Wed Oct 10 14:54:52 2018 +0300 IGNITE-9805 Add link to the build's page on TC server, add modal window for 'old' build - Fixes #30. Signed-off-by: Dmitriy Pavlov <dpav...@apache.org> --- .../src/main/webapp/comparison.html | 165 ++++++++++++++++----- .../src/main/webapp/css/style-1.5.css | 47 ++++++ ignite-tc-helper-web/src/main/webapp/img/tc.svg | 65 ++++++++ 3 files changed, 238 insertions(+), 39 deletions(-) diff --git a/ignite-tc-helper-web/src/main/webapp/comparison.html b/ignite-tc-helper-web/src/main/webapp/comparison.html index 7868f64..bc24084 100644 --- a/ignite-tc-helper-web/src/main/webapp/comparison.html +++ b/ignite-tc-helper-web/src/main/webapp/comparison.html @@ -4,12 +4,13 @@ <meta charset="UTF-8"> <title>Ignite Teamcity - comparison master's branch in the date interval</title> <link rel="icon" href="img/leaf-icon-png-7066.png"> - <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> - <link rel="stylesheet" href="css/style-1.5.css"> - <script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script> + <script src="https://code.jquery.com/jquery-1.12.4.js"></script> + <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" /> + <link rel="stylesheet" href="css/style-1.5.css"> + <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="js/common-1.6.js"></script> <script src="https://d3js.org/d3.v4.min.js"></script> </head> @@ -182,6 +183,7 @@ let statistics = {}; let dates = []; + let buildIds = []; for (let i = 0; i < prOcc.length; i++) { statistics[prOcc[i]] = []; @@ -190,6 +192,7 @@ for (let j = 0; j < map.length; j++) { dates[j] = parseTime(map[j].startDate); + buildIds[j] = map[j].buildId; for (let i = 0; i < prOcc.length; i++) { statistics[prOcc[i]][j] = map[j].totalProblems[prOcc[i]]; @@ -221,19 +224,19 @@ $('.title' + num).html('min - median - max'); for (let i = 0; i < prOcc.length; i++) { - fillCellWithStatistics(prOcc[i], num, statistics, dates); - fillCellWithStatistics(tOcc[i], num, statistics, dates); + fillCellWithStatistics(prOcc[i], num, statistics, dates, buildIds); + fillCellWithStatistics(tOcc[i], num, statistics, dates, buildIds); } } - function fillCellWithStatistics(prefix, num, statistics, dates) { + function fillCellWithStatistics(prefix, num, statistics, dates, buildIds) { let result = getMinMaxMedian(statistics[prefix]); $('#' + prefix + num).html(result.min + " - " + result.median + " - " + result.max); compareAndHighlight(prefix, num, result.median); - drawGraph(prefix, num, dates, statistics[prefix], prefix); + drawGraph(prefix, num, dates, statistics[prefix], buildIds); } function compareAndHighlight(prefix, thisNum, thisMedian){ @@ -346,49 +349,58 @@ }); } - function drawGraph(prefix, num, dates, counts, text) { + function drawGraph(prefix, num, dates, counts, buildIds) { let data = []; for (let i = 0; i < dates.length; i++) { data[i] = {}; data[i].date = dates[i]; - data[i].count = counts[i]; + data[i].value = counts[i]; + data[i].buildId = buildIds[i]; } - svg = d3.select("#graph" + prefix + num).append("svg:svg"); - margin = {top: 20, right: 20, bottom: 30, left: 50}; - width = +500 - margin.left - margin.right; - height = +200 - margin.top - margin.bottom; - g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - x = d3.scaleTime().range([0, width]); - y = d3.scaleLinear().range([height, 0]); + let svg = d3.select("#graph" + prefix + num).append("svg:svg"); + let margin = {top: 20, right: 20, bottom: 30, left: 50}; + let width = +500 - margin.left - margin.right; + let height = +200 - margin.top - margin.bottom; + let g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - line = d3.line() - .curve(d3.curveBasis) - .x(function(d) { return x(d.date); }) - .y(function(d) { return y(d.count); }); + let div = d3.select("body").append("div") + .attr("class", "tooltip") + .style("opacity", 0); + + let formatTime = d3.timeFormat("%d-%m-%Y %H:%M:%S"); + let max = d3.max(data, function(d){return parseInt(d.value)}); + let y = d3.scaleLinear() + .domain([0, max]) + .range([height, 0]); + let x = d3.scaleTime() + .rangeRound([0, width]); x.domain(d3.extent(data, function(d) { return d.date; })); - y.domain(d3.extent(data, function(d) { return d.count; })); - - g.append("svg:g") - .attr("transform", "translate(0," + height + ")") - .call(d3.axisBottom(x)) - .select(".domain") - .remove(); - - g.append("svg:g") - .call(d3.axisLeft(y)) - .append("text") - .attr("fill", "#000") - .attr("transform", "rotate(-90)") - .attr("y", 6) - .attr("dy", "0.71em") - .attr("text-anchor", "end") - .text(text); - - g.append("svg:path") + + let line = d3.line() + .x(function(d) { return x(d.date); }) + .y(function(d) { return y(d.value); }); + + g.append("g") + .attr("transform", "translate(0," + (height) + ")") + .call(d3.axisBottom(x)); + + g.append("g") + .call(d3.axisLeft(y)); + + let svg_aline = g.append("line") + .attr("class", "line") + .style("stroke-dasharray", ("3, 10")) + .attr("x1",100) + .attr("x2",400) + .attr("y1",200) + .attr("y2",200) + .style("display", "None"); + + g.append("path") .datum(data) .attr("fill", "none") .attr("stroke", "steelblue") @@ -396,7 +408,82 @@ .attr("stroke-linecap", "round") .attr("stroke-width", 1.5) .attr("d", line); + + g.selectAll("dot").data(data) + .enter() + .append("circle") + .attr("r", 3) + .attr("cx", function(d){return x(d.date); }) + .attr("cy", function(d){return y(d.value); }) + .attr("class", "dot") + .on("mouseover", function(d) { + d3.select(this).transition().duration(100) + .style("fill", "green") + .attr("r", 5) + .attr("onclick", "checkAvailable(" + d.buildId + "," + d.date.getTime() + ");" + + "return false;"); + div.transition() + .duration(200) + .style("opacity", .8); + + let graphTd = document.getElementById("graph" + prefix + num).getBoundingClientRect(); + let scrollTop = window.pageYOffset || document.documentElement.scrollTop; + + div .html(formatTime(d.date)) + .style("left", graphTd.left + x(d.date) + (x(d.date) > (500 - 150) ? -150 : 0) + "px") + .style("top", scrollTop + graphTd.top - 10 + "px" ); + svg_aline.transition().duration(10) + .style("display", "block") + .attr("x1", x(d.date)) + .attr("y1", y(d.value)) + .attr("x2", x(d.date)) + .attr("y2", height) + }) + + .on("mouseout", function(d) { + d3.select(this).transition().duration(100) + .style("fill", "grey") + .attr("r", 3); + div.transition() + .duration(500) + .style("opacity", 0); + svg_aline.style("display","None") + }); + } + + function getBuildLink(buildId) { return "https://ci.ignite.apache.org/viewLog.html?buildId=" + buildId + + "&tab=buildResultsDiv&buildTypeId=IgniteTests24Java8_RunAll"; } + + function checkAvailable(buildId, date) { + let dateDiff = moment().diff(moment(date), 'days'); + + if (dateDiff <= 14) { + window.open(getBuildLink(buildId), '_blank'); + return; + } + + let message = "<p style='text-align:center;opacity: 0.7;'><img src='img/tc.svg' width='100' height='100'></p>" + + "<br>The results «Run All» for <b>build [" + buildId + "]</b> is <b>not available</b> on " + + "the TeamCity server.<br><br><span style='color:grey;font-size:smaller'><hr>TeamCity server stores data " + + "for the last ~14 days. Since the launch of the build " + dateDiff + " days have passed</span>"; + + let modalDialog = $("#modalDialog"); + + modalDialog.html(message); + modalDialog.dialog({ + modal: true, + buttons: { + "Go anyway": function () { + $(this).dialog("close"); + window.open(getBuildLink(buildId), '_blank'); + }, + "Cancel": function () { + $(this).dialog("close"); + } + } + }); } </script> +<div style="visibility:hidden"><div id="modalDialog" title="Information"></div></div> </body> </html> diff --git a/ignite-tc-helper-web/src/main/webapp/css/style-1.5.css b/ignite-tc-helper-web/src/main/webapp/css/style-1.5.css index d670800..a95ca77 100644 --- a/ignite-tc-helper-web/src/main/webapp/css/style-1.5.css +++ b/ignite-tc-helper-web/src/main/webapp/css/style-1.5.css @@ -220,3 +220,50 @@ form li:after .compare tr:nth-child(4n-1) { background-color: #fafaff; } + +rect { + fill: red; + stroke: black; + stroke-width: 0; +} + +.dot { + opacity: 0.5; + fill: grey; +} + +line { + fill: none; + stroke: green; + stroke-width: 1; + shape-rendering: crispEdges; +} + +.axis path, +.axis line { + fill: none; + stroke: grey; + stroke-width: 1; + shape-rendering: crispEdges; +} + +div.tooltip { + position: absolute; + text-align: center; + width: 150px; + height: 15px; + padding: 2px; + margin-left: 50px; + margin-top: 5px; + font: 14px sans-serif; + background: #12AD5E; + border: 1px; + border-radius: 8px; + pointer-events: none; + color: white; +} + +.ui-dialog button{ + height: auto; +} + diff --git a/ignite-tc-helper-web/src/main/webapp/img/tc.svg b/ignite-tc-helper-web/src/main/webapp/img/tc.svg new file mode 100644 index 0000000..6083e57 --- /dev/null +++ b/ignite-tc-helper-web/src/main/webapp/img/tc.svg @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="70px" height="70px" viewBox="0 0 70 70" style="enable-background:new 0 0 70 70;" xml:space="preserve"> +<g> + <g> + <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="1.7738" y1="31.2729" x2="40.1662" y2="31.2729"> + <stop offset="0" style="stop-color:#905CFB"/> + <stop offset="6.772543e-002" style="stop-color:#776CF9"/> + <stop offset="0.1729" style="stop-color:#5681F7"/> + <stop offset="0.2865" style="stop-color:#3B92F5"/> + <stop offset="0.4097" style="stop-color:#269FF4"/> + <stop offset="0.5474" style="stop-color:#17A9F3"/> + <stop offset="0.7111" style="stop-color:#0FAEF2"/> + <stop offset="0.9677" style="stop-color:#0CB0F2"/> + </linearGradient> + <path style="fill:url(#SVGID_1_);" d="M39.7,47.9l-6.1-34c-0.4-2.4-1.2-4.8-2.7-7.1c-2-3.2-5.2-5.4-8.8-6.3 + C7.9-2.9-2.6,11.3,3.6,23.9c0,0,0,0,0,0l14.8,31.7c0.4,1,1,2,1.7,2.9c1.2,1.6,2.8,2.8,4.7,3.4C34.4,64.9,42.1,56.4,39.7,47.9z"/> + <linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="5.3113" y1="9.6691" x2="69.2278" y2="43.8664"> + <stop offset="0" style="stop-color:#905CFB"/> + <stop offset="6.772543e-002" style="stop-color:#776CF9"/> + <stop offset="0.1729" style="stop-color:#5681F7"/> + <stop offset="0.2865" style="stop-color:#3B92F5"/> + <stop offset="0.4097" style="stop-color:#269FF4"/> + <stop offset="0.5474" style="stop-color:#17A9F3"/> + <stop offset="0.7111" style="stop-color:#0FAEF2"/> + <stop offset="0.9677" style="stop-color:#0CB0F2"/> + </linearGradient> + <path style="fill:url(#SVGID_2_);" d="M67.4,26.5c-1.4-2.2-3.4-3.9-5.7-4.9L25.5,1.7l0,0c-1-0.5-2.1-1-3.3-1.3 + C6.7-3.2-4.4,13.8,5.5,27c1.5,2,3.6,3.6,6,4.5L48,47.9c0.8,0.5,1.6,0.8,2.5,1.1C64.5,53.4,75.1,38.6,67.4,26.5z"/> + <linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="-19.2836" y1="70.8198" x2="55.9833" y2="33.1863"> + <stop offset="0" style="stop-color:#3BEA62"/> + <stop offset="0.117" style="stop-color:#31DE80"/> + <stop offset="0.3025" style="stop-color:#24CEA8"/> + <stop offset="0.4844" style="stop-color:#1AC1C9"/> + <stop offset="0.6592" style="stop-color:#12B7DF"/> + <stop offset="0.8238" style="stop-color:#0EB2ED"/> + <stop offset="0.9677" style="stop-color:#0CB0F2"/> + </linearGradient> + <path style="fill:url(#SVGID_3_);" d="M67.4,26.5c-1.8-2.8-4.6-4.8-7.9-5.6c-3.5-0.8-6.8-0.5-9.6,0.7L11.4,36.1 + c0,0-0.2,0.1-0.6,0.4C0.9,40.4-4,53.3,4,64c1.8,2.4,4.3,4.2,7.1,5c5.3,1.6,10.1,1,14-1.1c0,0,0.1,0,0.1,0l37.6-20.1 + c0,0,0,0,0.1-0.1C69.5,43.9,72.6,34.6,67.4,26.5z"/> + <linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="38.9439" y1="5.8503" x2="5.4232" y2="77.5093"> + <stop offset="0" style="stop-color:#3BEA62"/> + <stop offset="9.397750e-002" style="stop-color:#2FDB87"/> + <stop offset="0.196" style="stop-color:#24CEA8"/> + <stop offset="0.3063" style="stop-color:#1BC3C3"/> + <stop offset="0.4259" style="stop-color:#14BAD8"/> + <stop offset="0.5596" style="stop-color:#10B5E7"/> + <stop offset="0.7185" style="stop-color:#0DB1EF"/> + <stop offset="0.9677" style="stop-color:#0CB0F2"/> + </linearGradient> + <path style="fill:url(#SVGID_4_);" d="M50.3,12.8c1.2-2.7,1.1-6-0.9-9c-1.1-1.8-2.9-3-4.9-3.5c-4.5-1.1-8.3,1-10.1,4.2L3.5,42 + c0,0,0,0,0,0.1C-0.9,47.9-1.6,56.5,4,64c1.8,2.4,4.3,4.2,7.1,5c10.5,3.3,19.3-2.5,22.1-10.8L50.3,12.8z"/> + </g> + <g> + <rect x="13.4" y="13.4" style="fill:#000000;" width="43.2" height="43.2"/> + <rect x="17.5" y="48.5" style="fill:#FFFFFF;" width="16.2" height="2.7"/> + <polygon style="fill:#FFFFFF;" points="22.9,22.7 17.5,22.7 17.5,19.1 32.3,19.1 32.3,22.7 26.8,22.7 26.8,37 22.9,37 "/> + <path style="fill:#FFFFFF;" d="M32.5,28.1L32.5,28.1c0-5.1,3.8-9.3,9.3-9.3c3.4,0,5.4,1.1,7.1,2.8l-2.5,2.9c-1.4-1.3-2.8-2-4.6-2 + c-3,0-5.2,2.5-5.2,5.6V28c0,3.1,2.1,5.6,5.2,5.6c2,0,3.3-0.8,4.7-2.1l2.5,2.5c-1.8,2-3.9,3.2-7.3,3.2 + C36.4,37.3,32.5,33.2,32.5,28.1"/> + </g> +</g> +</svg>