Skip to content
This repository was archived by the owner on Dec 28, 2021. It is now read-only.

Commit bb2ea8d

Browse files
committed
Make tooltip display above nodes by adding it to the global DOM
1 parent 2d805ed commit bb2ea8d

File tree

1 file changed

+61
-7
lines changed
  • src/rust/ide/view/graph-editor/src/builtin/visualization/java_script

1 file changed

+61
-7
lines changed

src/rust/ide/view/graph-editor/src/builtin/visualization/java_script/sql.js

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ const customSqlTypePrefix = 'Standard.Database.Data.Sql.Sql_Type.'
1313
/** Specifies opacity of interpolation background color. */
1414
const interpolationBacgroundOpacity = 0.3
1515

16+
/** A regular expression for parsing CSS transforms. */
17+
const matrixRegex = /matrix(3d)?\(.*?\)/
18+
1619
/** The CSS styles for the visualization. */
1720
const visualizationStyle = `
1821
<style>
@@ -80,15 +83,15 @@ loadScript('https://cdnjs.cloudflare.com/ajax/libs/sql-formatter/4.0.2/sql-forma
8083
* interpolated query parameters.
8184
*/
8285
class SqlVisualization extends Visualization {
83-
// TODO Change the type below once #837 is done:
84-
// 'Standard.Database.Data.Table.Table | Standard.Database.Data.Column.Column'
8586
static inputType = 'Standard.Database.Data.Table.Table | Standard.Database.Data.Column.Column'
86-
static label = 'SQL Query'
87+
static label = 'SQL Query (dev)'
8788

8889
constructor(api) {
8990
super(api)
9091
this.setPreprocessorModule('Standard.Visualization.Sql.Visualization')
9192
this.setPreprocessorCode(`x -> here.prepare_visualization x`)
93+
94+
this.tooltip = null
9295
}
9396

9497
onDataReceived(data) {
@@ -126,7 +129,10 @@ class SqlVisualization extends Visualization {
126129
containers.scrollable.innerHTML = visHtml
127130
this.dom.appendChild(parentContainer)
128131

129-
const tooltip = new Tooltip(parentContainer)
132+
const tooltipParent = document.querySelector('#root > .scene > .front > .view_projection')
133+
console.log(tooltipParent)
134+
const tooltip = new Tooltip(tooltipParent)
135+
this.tooltip = tooltip
130136
const baseMismatches = this.dom.getElementsByClassName('mismatch')
131137
const extendedMismatchAreas = this.dom.getElementsByClassName('mismatch-mouse-area')
132138
setupMouseInteractionForMismatches(tooltip, baseMismatches)
@@ -142,6 +148,7 @@ class SqlVisualization extends Visualization {
142148
while (this.dom.firstChild) {
143149
this.dom.removeChild(this.dom.lastChild)
144150
}
151+
this.removeTooltip()
145152
}
146153

147154
/**
@@ -170,6 +177,18 @@ class SqlVisualization extends Visualization {
170177
}
171178
}
172179

180+
onHide() {
181+
this.removeTooltip()
182+
}
183+
184+
/** Removes the tooltip element, if it has been created. */
185+
removeTooltip() {
186+
if (this.tooltip !== null) {
187+
this.tooltip.destroy()
188+
this.tooltip = null
189+
}
190+
}
191+
173192
setSize(size) {
174193
this.dom.setAttributeNS(null, 'width', size[0])
175194
this.dom.setAttributeNS(null, 'height', size[1])
@@ -372,6 +391,10 @@ class Tooltip {
372391
* ignored.
373392
*/
374393
hide(actor) {
394+
if (this.tooltip == null) {
395+
console.log('hide called on destroyed tooltip')
396+
return
397+
}
375398
if (this.tooltipOwner === null || this.tooltipOwner == actor) {
376399
this.tooltipOwner = null
377400
this.tooltip.style.opacity = 0
@@ -384,6 +407,11 @@ class Tooltip {
384407
* Tooltip content is specified by the `message` which can include arbitrary HTML.
385408
*/
386409
show(actor, message) {
410+
if (this.tooltip == null) {
411+
console.log('show called on destroyed tooltip')
412+
return
413+
}
414+
387415
this.tooltipOwner = actor
388416
this.tooltip.innerHTML = message
389417
this.tooltip.style.opacity = 1
@@ -393,7 +421,7 @@ class Tooltip {
393421
const scrollElement = codeContainer.parentElement
394422

395423
const scrollOffsetX = scrollElement.scrollLeft
396-
const scrollOffsetY = scrollElement.scrollTop + scrollElement.offsetHeight
424+
const scrollOffsetY = scrollElement.scrollTop
397425

398426
const interpolantOffsetX = interpolantContainer.offsetLeft
399427
const interpolantOffsetY = interpolantContainer.offsetTop
@@ -402,11 +430,37 @@ class Tooltip {
402430
const belowPadding = 3
403431
const belowOffset = interpolantContainer.offsetHeight + belowPadding
404432

405-
const x = interpolantOffsetX - scrollOffsetX + centeringOffset
406-
const y = interpolantOffsetY - scrollOffsetY + belowOffset
433+
const visualization = actor.closest('.visualization')
434+
const visMatrix = getMatrix(visualization)
435+
436+
const x = visMatrix.m41 + interpolantOffsetX - scrollOffsetX + centeringOffset
437+
const y = visMatrix.m42 + interpolantOffsetY - scrollOffsetY + belowOffset
407438

408439
this.tooltip.style.transform = 'translate(' + x + 'px, ' + y + 'px)'
409440
}
441+
442+
/** Removes the element itself.
443+
*
444+
* The tooltip instance is not usable after this has been called.
445+
*/
446+
destroy() {
447+
this.tooltipOwner = null
448+
if (this.tooltip == null) {
449+
console.log('destroy called twice on a tooltip')
450+
return
451+
}
452+
this.tooltip.remove()
453+
this.tooltip = null
454+
}
455+
}
456+
457+
/** A helper function that returns a parsed CSS transformation matrix for a given element. */
458+
function getMatrix(element) {
459+
const transform = window.getComputedStyle(element).transform
460+
console.log(transform)
461+
const matrixString = transform.match(matrixRegex)[0]
462+
const matrix = new DOMMatrix(matrixString)
463+
return matrix
410464
}
411465

412466
/**

0 commit comments

Comments
 (0)