From e82d17a09c35f37b89104716f59c7f9ff9f79291 Mon Sep 17 00:00:00 2001 From: Silvano Ravotto Date: Wed, 19 May 2021 14:17:41 -0400 Subject: [PATCH 1/5] wip --- ui/css/style.css | 124 ++++++++++++++++++++++------------------------- ui/qv.js | 47 ++++++++++++------ 2 files changed, 90 insertions(+), 81 deletions(-) diff --git a/ui/css/style.css b/ui/css/style.css index 7041a61..cae8789 100644 --- a/ui/css/style.css +++ b/ui/css/style.css @@ -145,85 +145,77 @@ table.node-inner-table > * > td:last-child { max-width: 500px; position: absolute; text-align: left; - word-wrap: break-word; - padding: 2px; + word-wrap: break-word; font-size: 12px; font-family: monospace; - background:lightgoldenrodyellow; - border: 1px solid goldenrod; - border-radius: 8px; + background:white; + + border-radius: 10px; + pointer-events: none; - z-index: 5 + z-index: 5; + box-shadow: gray 5px 5px; } -.tooltip table { +.tooltip-main { + border-radius: 10px; border-collapse: collapse; white-space: pre-wrap; font-size: 1em; } -.tooltip table > tr > * { - border: 1px solid goldenrod; +.tooltip-main tbody> tr > * { + border-bottom: 1px solid #F0F0F0; + text-align: right; + margin: 0px; + padding-left: 5px; + padding-right: 5px; + border-top-left-radius: 0px; + border-top-right-radius: 0px; } -.tooltip table > tr:first-child > * { - border-top: 0; + +.tooltip-main tbody>tr:first-child > *:first-child { + border-top-left-radius: 10px; } -.tooltip table > tr > *:first-child { - border-left: 0; +.tooltip-main tbody>tr:last-child > *:first-child { + border-bottom: 0px; + border-bottom-left-radius: 10px; } -.tooltip table > tr:last-child > * { - border-bottom: 0; +.tooltip-main tbody>tr > *:first-child { + background: #F0F0F0; + text-align: left; } -.tooltip table > * > td:last-child { - border-right: 0; + +.tooltip-main tbody > tr:last-child > * { + border-bottom: 0px; +} + +.tooltip-inner { + white-space: pre-wrap; + font-size: 1em; + padding: 0px; +} + +.tooltip-inner tbody> tr > *:first-child { + border-right: 1px solid #E0E0E0; + background:white; + text-align: left; +} + + +.tooltip-inner tbody > tr > *:last-child { + + background:white; + text-align: right; + width:100% + } +.tooltip-inner tr > * { + border-bottom: 1px solid #F0F0F0; + border-left: 0px; +} + +.tooltip-inner tbody > tr:last-child > *{ + border-bottom: 0; +} -/* .banner { */ -/* stroke-width: 0px; */ -/* } */ - -/* .node--internal text { */ -/* text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff; */ -/* } */ - -/* pre { */ -/* white-space: pre-wrap; */ -/* font-size: .80em; */ -/* } */ - -/* table.plantable { */ -/* background-color: #FFFFFF; */ -/* border-collapse: collapse; */ -/* border-width: 1px; */ -/* border-color: steelblue; */ -/* border-style: solid; */ -/* color: #000000; */ -/* } */ - -/* table.plantable td, table.plantable th { */ -/* border-width: 1px; */ -/* border-color: steelblue; */ -/* border-style: solid; */ -/* padding: 5px; */ -/* } */ - -/* table.plantable thead { */ -/* background-color: whitesmoke; */ -/* } */ - -/* table.criteria td, table.criteria th { */ -/* padding: 5px; */ -/* } */ - -/* .qv-tabs { */ -/* height: 34px; */ -/* } */ -/* .qv-banner { */ -/* height: 100%; */ -/* } */ - -/* .qv-vertical-center { */ -/* margin: 0; */ -/* position: absolute; */ -/* top: 70px; */ -/* } */ diff --git a/ui/qv.js b/ui/qv.js index 5dea210..b49bfa5 100644 --- a/ui/qv.js +++ b/ui/qv.js @@ -268,6 +268,14 @@ function qv_tooltipEvents(element, tooltip, doFilter) { }); } +function qv_tooltipValue (key, value) { + if (key == null) return qv_decode(value) + else if (key === "id" || key.endsWith("-id") || key === "statusCode") return value + else if (key === "lmem" || key === "rmem") return (Math.round(value / 1024 ) + " KB") + else if (key === "ltime" || key === "time") return (Math.round(value) + " ms") + else if (typeof value === "number") return value.toExponential(2) + else return qv_decode(value) +} function qv_tooltipTableRow(table, key, value) { if(Array.isArray(value)) { value.forEach((v) => qv_tooltipTableRow(table,key,v)); @@ -275,13 +283,18 @@ function qv_tooltipTableRow(table, key, value) { else if(value!==null && typeof(value)==="object") { var tr = table.append("tr"); if(key!==null) tr.append("th").text(key); - var table2 = tr.append("td").append("table"); + var table2 = tr.append("td").style("padding", "0px").append("table").attr("class","tooltip-inner").append("tbody"); Object.keys(value).forEach((key) => qv_tooltipTableRow(table2,key,value[key])); } else { var tr = table.append("tr"); - if(key!==null) tr.append("th").text(key); - tr.append("td").text(qv_decode(value)); + if(key!==null) { + var label = key; + if (key === "parallel") {label= "\u2B25\u00A0" + key} + else if (key === "serial") {label= "\u25CF\u00A0" + key} + tr.append("th").text(label); + } + tr.append("td").text(qv_tooltipValue(key, value)); } } @@ -305,7 +318,7 @@ function qv_tooltipContents(parent, data, doFilter) { return data.hasOwnProperty(key); }; - var table = parent.append("table"); + var table = parent.append("table").attr("class","tooltip-main").append("tbody"); var display = (key) => { if (key != "costFunctionValues") { qv_tooltipTableRow(table,key,data[key]); @@ -317,7 +330,7 @@ function qv_tooltipContents(parent, data, doFilter) { Object.keys(data).filter(seenFilter).forEach(display); } else if(data && (!Array.isArray(data) || data.length !== 0)) { - qv_tooltipTableRow(parent.append("table"),null,data); + qv_tooltipTableRow(parent.append("table").attr("class","tooltip-main").append("tbody"),null,data); empty = false; } return !empty; @@ -335,7 +348,7 @@ function qv_tooltipShow(event, data, doFilter) { .style("top", y + "px"); tooltip.html(""); if(qv_tooltipContents(tooltip,data,doFilter)) - tooltip.transition().duration(200).style("opacity", .9); + tooltip.transition().duration(200).style("opacity", 1); } function qv_tooltipHide(event) { @@ -551,17 +564,21 @@ function qv_lineGraph (node) { // Node display function qv_dnodeLabel (dnode) { + + + if (dnode != null) { dnode.append("circle") - .attr("cx",25) - .attr("cy",25) - .attr("r",20) - .attr("fill","gray") + .attr("cx",17) + .attr("cy",17) + .attr("r",13.5) + .attr("stroke","#505050") + .attr("stroke-width","3") + .attr("fill", "white") dnode.append("path") - .attr("d", "M20,14 C40,14 40,36 20,36z") - .attr("stroke", "white") - .attr("stroke-width", 4) - .attr("fill", "gray") + .attr("d", "M12.4107 18.904C12.4107 18.296 12.4747 17.704 12.6027 17.128C12.7307 16.552 12.9387 16.04 13.2267 15.592C13.5147 15.144 13.8987 14.784 14.3787 14.512C14.8587 14.24 15.4427 14.104 16.1307 14.104C16.8347 14.104 17.4347 14.24 17.9307 14.512C18.4267 14.768 18.8267 15.112 19.1307 15.544C19.4507 15.976 19.6827 16.48 19.8267 17.056C19.9707 17.616 20.0427 18.2 20.0427 18.808C20.0427 19.384 19.9707 19.952 19.8267 20.512C19.6987 21.072 19.4827 21.576 19.1787 22.024C18.8747 22.456 18.4827 22.808 18.0027 23.08C17.5227 23.352 16.9387 23.488 16.2507 23.488C15.5947 23.488 15.0187 23.36 14.5227 23.104C14.0427 22.848 13.6427 22.504 13.3227 22.072C13.0187 21.64 12.7867 21.152 12.6267 20.608C12.4827 20.048 12.4107 19.48 12.4107 18.904ZM22.0107 25V7.864H19.9707V14.248H19.9227C19.6987 13.88 19.4187 13.576 19.0827 13.336C18.7627 13.08 18.4187 12.88 18.0507 12.736C17.6827 12.576 17.3147 12.464 16.9467 12.4C16.5787 12.336 16.2347 12.304 15.9147 12.304C14.9707 12.304 14.1387 12.48 13.4187 12.832C12.7147 13.168 12.1227 13.632 11.6427 14.224C11.1787 14.8 10.8267 15.48 10.5867 16.264C10.3627 17.048 10.2507 17.88 10.2507 18.76C10.2507 19.64 10.3707 20.472 10.6107 21.256C10.8507 22.04 11.2027 22.728 11.6667 23.32C12.1467 23.912 12.7387 24.384 13.4427 24.736C14.1627 25.088 15.0027 25.264 15.9627 25.264C16.8267 25.264 17.6187 25.112 18.3387 24.808C19.0587 24.504 19.5867 24.008 19.9227 23.32H19.9707V25H22.0107Z") + .attr("fill", "#505050") + } } @@ -668,7 +685,7 @@ function qv_nodeRow(table, key, value, tooltip, insideArray, cardinalities) { var tr = table.append("tr"); var td0 = tr.append("td"); - if(magnitude!==null) td0.append("span").style("color",magnitude).text("\u2588\u2588"); + if(magnitude!==null) td0.append("span").style("color",magnitude).text("\u25AC"); if(key!==null) tr.append("th").text(key); if(value===null) { tr.append("td").append("span").style("font-style","italic").text("null"); From 9d8ae0d96e76c8c561768fca656fecd300931a2e Mon Sep 17 00:00:00 2001 From: Silvano Ravotto Date: Wed, 19 May 2021 14:22:50 -0400 Subject: [PATCH 2/5] wip --- ui/qv.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/qv.js b/ui/qv.js index b49bfa5..6d45649 100644 --- a/ui/qv.js +++ b/ui/qv.js @@ -272,7 +272,7 @@ function qv_tooltipValue (key, value) { if (key == null) return qv_decode(value) else if (key === "id" || key.endsWith("-id") || key === "statusCode") return value else if (key === "lmem" || key === "rmem") return (Math.round(value / 1024 ) + " KB") - else if (key === "ltime" || key === "time") return (Math.round(value) + " ms") + else if (key === "ltime" || key === "rtime") return (Math.round(value) + " ms") else if (typeof value === "number") return value.toExponential(2) else return qv_decode(value) } From 19a92e2effba53cbc410032960a6660eec87d769 Mon Sep 17 00:00:00 2001 From: Silvano Ravotto Date: Mon, 24 May 2021 11:55:39 -0400 Subject: [PATCH 3/5] hover fixes --- ui/qv.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ui/qv.js b/ui/qv.js index 6d45649..73ab850 100644 --- a/ui/qv.js +++ b/ui/qv.js @@ -271,7 +271,7 @@ function qv_tooltipEvents(element, tooltip, doFilter) { function qv_tooltipValue (key, value) { if (key == null) return qv_decode(value) else if (key === "id" || key.endsWith("-id") || key === "statusCode") return value - else if (key === "lmem" || key === "rmem") return (Math.round(value / 1024 ) + " KB") + else if (key === "lmem" || key === "rmem") return (Math.round(value / 1024 ) + " kB") else if (key === "ltime" || key === "rtime") return (Math.round(value) + " ms") else if (typeof value === "number") return value.toExponential(2) else return qv_decode(value) @@ -290,9 +290,10 @@ function qv_tooltipTableRow(table, key, value) { var tr = table.append("tr"); if(key!==null) { var label = key; - if (key === "parallel") {label= "\u2B25\u00A0" + key} - else if (key === "serial") {label= "\u25CF\u00A0" + key} - tr.append("th").text(label); + var el = "th"; + if (key === "parallel") {label= "\u2B25\u00A0" + key; el="td"} + else if (key === "serial") {label= "\u25CF\u00A0" + key; el="td"} + tr.append(el).text(label); } tr.append("td").text(qv_tooltipValue(key, value)); } @@ -347,6 +348,7 @@ function qv_tooltipShow(event, data, doFilter) { .style("left", x + "px") .style("top", y + "px"); tooltip.html(""); + if(qv_tooltipContents(tooltip,data,doFilter)) tooltip.transition().duration(200).style("opacity", 1); } @@ -565,8 +567,6 @@ function qv_lineGraph (node) { function qv_dnodeLabel (dnode) { - - if (dnode != null) { dnode.append("circle") .attr("cx",17) @@ -913,7 +913,7 @@ function qv_showPlan(containerid, json) { dnode = node.filter((d) => d.data.data.dnode==="true" ).append("g") .attr( "transform", d => "translate(" + (qv_box.width - 15) - + "," + (qv_nodeCostHeight(d.data.data) + 2) + ") scale(.20)" ) + + "," + (qv_nodeCostHeight(d.data.data) + 4) + ") scale(.30)" ) qv_dnodeLabel(dnode) // add cost banner From 1687f6403049fd090bf7e31ffdb2fbc6ae5002e2 Mon Sep 17 00:00:00 2001 From: Silvano Ravotto Date: Wed, 26 May 2021 10:03:57 -0400 Subject: [PATCH 4/5] minor fixes --- ui/css/style.css | 17 ++++++++--------- ui/qv.js | 6 ++++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/ui/css/style.css b/ui/css/style.css index cae8789..d1b1bee 100644 --- a/ui/css/style.css +++ b/ui/css/style.css @@ -149,12 +149,10 @@ table.node-inner-table > * > td:last-child { font-size: 12px; font-family: monospace; background:white; - border-radius: 10px; - pointer-events: none; z-index: 5; - box-shadow: gray 5px 5px; + box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25); } .tooltip-main { @@ -164,11 +162,10 @@ table.node-inner-table > * > td:last-child { font-size: 1em; } .tooltip-main tbody> tr > * { - border-bottom: 1px solid #F0F0F0; + border-bottom: 1px solid #B0B0B0; text-align: right; margin: 0px; - padding-left: 5px; - padding-right: 5px; + padding: 2px; border-top-left-radius: 0px; border-top-right-radius: 0px; } @@ -180,8 +177,9 @@ table.node-inner-table > * > td:last-child { border-bottom: 0px; border-bottom-left-radius: 10px; } -.tooltip-main tbody>tr > *:first-child { +.tooltip-main tbody>tr > th { background: #F0F0F0; + padding: 5px; text-align: left; } @@ -193,10 +191,11 @@ table.node-inner-table > * > td:last-child { white-space: pre-wrap; font-size: 1em; padding: 0px; + border-spacing: 0px; } .tooltip-inner tbody> tr > *:first-child { - border-right: 1px solid #E0E0E0; + border-right: 1px solid #B0B0B0; background:white; text-align: left; } @@ -211,7 +210,7 @@ table.node-inner-table > * > td:last-child { } .tooltip-inner tr > * { - border-bottom: 1px solid #F0F0F0; + border-bottom: 1px solid #B0B0B0; border-left: 0px; } diff --git a/ui/qv.js b/ui/qv.js index 73ab850..9bc62aa 100644 --- a/ui/qv.js +++ b/ui/qv.js @@ -271,8 +271,8 @@ function qv_tooltipEvents(element, tooltip, doFilter) { function qv_tooltipValue (key, value) { if (key == null) return qv_decode(value) else if (key === "id" || key.endsWith("-id") || key === "statusCode") return value - else if (key === "lmem" || key === "rmem") return (Math.round(value / 1024 ) + " kB") - else if (key === "ltime" || key === "rtime") return (Math.round(value) + " ms") + else if (key === "lmem" || key === "rmem") return (Math.round(value / 1024 ) ) + else if (key === "ltime" || key === "rtime") return (Math.round(value)) else if (typeof value === "number") return value.toExponential(2) else return qv_decode(value) } @@ -293,6 +293,8 @@ function qv_tooltipTableRow(table, key, value) { var el = "th"; if (key === "parallel") {label= "\u2B25\u00A0" + key; el="td"} else if (key === "serial") {label= "\u25CF\u00A0" + key; el="td"} + else if (key === "lmem" || key === "rmem") label= (key + " (kB)") + else if (key === "ltime" || key === "rtime") label= (key + " (ms)") tr.append(el).text(label); } tr.append("td").text(qv_tooltipValue(key, value)); From add473b0f9cbc94208d3021da50bbd86f7bc7d6e Mon Sep 17 00:00:00 2001 From: John Snelson Date: Fri, 24 Sep 2021 15:31:16 +0100 Subject: [PATCH 5/5] bug:56024 Fix the tooltips to work when the query plan viewer is embedded in another page --- log.html | 3 --- show.xqy | 2 +- ui/css/style.css | 26 +++++++++++++------------- ui/qv.js | 23 +++++++++++++++-------- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/log.html b/log.html index c5919de..3043c45 100644 --- a/log.html +++ b/log.html @@ -50,9 +50,6 @@ - -
-
diff --git a/show.xqy b/show.xqy index 57562c2..57daa1c 100644 --- a/show.xqy +++ b/show.xqy @@ -34,7 +34,7 @@ declare function local:makeHTML($out)
-
+
diff --git a/ui/css/style.css b/ui/css/style.css index d1b1bee..6c40d82 100644 --- a/ui/css/style.css +++ b/ui/css/style.css @@ -140,7 +140,7 @@ table.node-inner-table > * > td:last-child { /********************************************************************************/ /* Tooltip */ -.tooltip { +.qvtooltip { opacity: 0; max-width: 500px; position: absolute; @@ -151,17 +151,17 @@ table.node-inner-table > * > td:last-child { background:white; border-radius: 10px; pointer-events: none; - z-index: 5; + z-index: 1000; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25); } -.tooltip-main { +.qvtooltip-main { border-radius: 10px; border-collapse: collapse; white-space: pre-wrap; font-size: 1em; } -.tooltip-main tbody> tr > * { +.qvtooltip-main tbody> tr > * { border-bottom: 1px solid #B0B0B0; text-align: right; margin: 0px; @@ -170,38 +170,38 @@ table.node-inner-table > * > td:last-child { border-top-right-radius: 0px; } -.tooltip-main tbody>tr:first-child > *:first-child { +.qvtooltip-main tbody>tr:first-child > *:first-child { border-top-left-radius: 10px; } -.tooltip-main tbody>tr:last-child > *:first-child { +.qvtooltip-main tbody>tr:last-child > *:first-child { border-bottom: 0px; border-bottom-left-radius: 10px; } -.tooltip-main tbody>tr > th { +.qvtooltip-main tbody>tr > th { background: #F0F0F0; padding: 5px; text-align: left; } -.tooltip-main tbody > tr:last-child > * { +.qvtooltip-main tbody > tr:last-child > * { border-bottom: 0px; } -.tooltip-inner { +.qvtooltip-inner { white-space: pre-wrap; font-size: 1em; padding: 0px; border-spacing: 0px; } -.tooltip-inner tbody> tr > *:first-child { +.qvtooltip-inner tbody> tr > *:first-child { border-right: 1px solid #B0B0B0; background:white; text-align: left; } -.tooltip-inner tbody > tr > *:last-child { +.qvtooltip-inner tbody > tr > *:last-child { background:white; text-align: right; @@ -209,12 +209,12 @@ table.node-inner-table > * > td:last-child { } -.tooltip-inner tr > * { +.qvtooltip-inner tr > * { border-bottom: 1px solid #B0B0B0; border-left: 0px; } -.tooltip-inner tbody > tr:last-child > *{ +.qvtooltip-inner tbody > tr:last-child > *{ border-bottom: 0; } diff --git a/ui/qv.js b/ui/qv.js index 9bc62aa..6363207 100644 --- a/ui/qv.js +++ b/ui/qv.js @@ -283,7 +283,7 @@ function qv_tooltipTableRow(table, key, value) { else if(value!==null && typeof(value)==="object") { var tr = table.append("tr"); if(key!==null) tr.append("th").text(key); - var table2 = tr.append("td").style("padding", "0px").append("table").attr("class","tooltip-inner").append("tbody"); + var table2 = tr.append("td").style("padding", "0px").append("table").attr("class","qvtooltip-inner").append("tbody"); Object.keys(value).forEach((key) => qv_tooltipTableRow(table2,key,value[key])); } else { @@ -321,7 +321,7 @@ function qv_tooltipContents(parent, data, doFilter) { return data.hasOwnProperty(key); }; - var table = parent.append("table").attr("class","tooltip-main").append("tbody"); + var table = parent.append("table").attr("class","qvtooltip-main").append("tbody"); var display = (key) => { if (key != "costFunctionValues") { qv_tooltipTableRow(table,key,data[key]); @@ -333,7 +333,7 @@ function qv_tooltipContents(parent, data, doFilter) { Object.keys(data).filter(seenFilter).forEach(display); } else if(data && (!Array.isArray(data) || data.length !== 0)) { - qv_tooltipTableRow(parent.append("table").attr("class","tooltip-main").append("tbody"),null,data); + qv_tooltipTableRow(parent.append("table").attr("class","qvtooltip-main").append("tbody"),null,data); empty = false; } return !empty; @@ -341,12 +341,13 @@ function qv_tooltipContents(parent, data, doFilter) { function qv_tooltipShow(event, data, doFilter) { - var boundaries = d3.select("body").node().getBoundingClientRect() + const pageWidth = document.body.scrollWidth; + const pageHeight = document.body.scrollHeight; - var x = Math.min (event.pageX + 28, boundaries.right-100) - var y = Math.min (event.pageY - 28, boundaries.bottom-50) + var x = Math.max(Math.min(event.pageX + 28, pageWidth-100),0) + var y = Math.max(Math.min(event.pageY - 28, pageHeight-50),0) - var tooltip = d3.select("#tooltip") + var tooltip = d3.select("#qvtooltip") .style("left", x + "px") .style("top", y + "px"); tooltip.html(""); @@ -356,7 +357,7 @@ function qv_tooltipShow(event, data, doFilter) { } function qv_tooltipHide(event) { - var tooltip = d3.select("#tooltip"); + var tooltip = d3.select("#qvtooltip"); tooltip.transition() .duration(500) .style("opacity", 0); @@ -832,6 +833,12 @@ function qv_showPlan(containerid, json) { .attr("width", width) .attr("height", height); + if(!d3.select('#qvtooltip').node()) { + d3.select("body").append('div') + .attr('id', 'qvtooltip') + .attr('class', 'qvtooltip'); + } + // set up transform and zoom var g = svg.append("g") var zoom = d3.zoom()