Fossil SCM
Resolve the fork.
Commit
fde231b274e3b0e6abe3e17e2f587c913291ff7a7b0c2eec594dd397a121a10d
Parent
5fc142df073760f…
2 files changed
+76
-26
+76
-26
+76
-26
| --- src/graph.js | ||
| +++ src/graph.js | ||
| @@ -75,20 +75,60 @@ | ||
| 75 | 75 | } |
| 76 | 76 | amendCssOnce = 0; |
| 77 | 77 | } |
| 78 | 78 | var tooltipObj = document.createElement("span"); |
| 79 | 79 | tooltipObj.className = "tl-tooltip"; |
| 80 | -tooltipObj.style.visibility = "hidden"; | |
| 80 | +tooltipObj.style.display = "none"; | |
| 81 | 81 | document.getElementsByClassName("content")[0].appendChild(tooltipObj); |
| 82 | +/* Clear the close timer if the mouse is over the tooltip. */ | |
| 83 | +tooltipObj.onmouseenter = function(e) { | |
| 84 | + stopCloseTimer(); | |
| 85 | +}; | |
| 86 | +/* Init the close timer if the mouse is no longer over the tooltip. */ | |
| 87 | +tooltipObj.onmouseleave = function(e) { | |
| 88 | + if (tooltipInfo.ixActive != -1) | |
| 89 | + resumeCloseTimer(); | |
| 90 | +}; | |
| 82 | 91 | /* This object must be in the global scope, so that (non-shadowed) access is |
| 83 | 92 | ** possible from within a setTimeout() closure. */ |
| 84 | 93 | window.tooltipInfo = { |
| 85 | 94 | dwellTimeout: 250, /* The tooltip dwell timeout. */ |
| 86 | - idTimer: 0, /* The tooltip dwell timer. */ | |
| 87 | - ixElement: -1, /* The id of the last hovered element. */ | |
| 95 | + closeTimeout: 3000, /* The tooltip close timeout. */ | |
| 96 | + idTimer: 0, /* The tooltip dwell timer id. */ | |
| 97 | + idTimerClose: 0, /* The tooltip close timer id. */ | |
| 98 | + ixHover: -1, /* The id of the element with the mouse. */ | |
| 99 | + ixActive: -1, /* The id of the element with the tooltip. */ | |
| 88 | 100 | posX: 0, posY: 0 /* The last mouse position. */ |
| 89 | 101 | }; |
| 102 | +/* These functions must be in the global scope, so that access is possible from | |
| 103 | +** within (non-local) event handlers. */ | |
| 104 | +var hideGraphTooltip = function() { | |
| 105 | + stopCloseTimer(); | |
| 106 | + tooltipObj.style.display = "none"; | |
| 107 | + this.tooltipInfo.ixActive = -1; | |
| 108 | +}.bind(window); | |
| 109 | +var stopDwellTimer = function() { | |
| 110 | + if (this.tooltipInfo.idTimer != 0) { | |
| 111 | + clearTimeout(this.tooltipInfo.idTimer); | |
| 112 | + this.tooltipInfo.idTimer = 0; | |
| 113 | + } | |
| 114 | +}.bind(window); | |
| 115 | +var resumeCloseTimer = function() { | |
| 116 | + /* This timer must be stopped explicitly to reset the elapsed timeout. */ | |
| 117 | + if (this.tooltipInfo.idTimerClose == 0) { | |
| 118 | + this.tooltipInfo.idTimerClose = setTimeout(function() { | |
| 119 | + this.tooltipInfo.idTimerClose = 0; | |
| 120 | + hideGraphTooltip(); | |
| 121 | + }.bind(window),this.tooltipInfo.closeTimeout); | |
| 122 | + } | |
| 123 | +}.bind(window); | |
| 124 | +var stopCloseTimer = function() { | |
| 125 | + if (this.tooltipInfo.idTimerClose != 0) { | |
| 126 | + clearTimeout(this.tooltipInfo.idTimerClose); | |
| 127 | + this.tooltipInfo.idTimerClose = 0; | |
| 128 | + } | |
| 129 | +}.bind(window); | |
| 90 | 130 | |
| 91 | 131 | /* Construct that graph corresponding to the timeline-data-N object */ |
| 92 | 132 | function TimelineGraph(tx){ |
| 93 | 133 | var topObj = document.getElementById("timelineTable"+tx.iTableId); |
| 94 | 134 | amendCss(tx.circleNodes, tx.showArrowheads); |
| @@ -99,52 +139,63 @@ | ||
| 99 | 139 | var ix = findTxIndex(e); |
| 100 | 140 | var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */ |
| 101 | 141 | document.getElementsByTagName('body')[0].style.cursor = cursor; |
| 102 | 142 | /* Keep the already visible tooltip at a constant position, as long as the |
| 103 | 143 | ** mouse is over the same element. */ |
| 104 | - if (tooltipObj.style.display != "none" && ix == tooltipInfo.ixElement) | |
| 105 | - return; | |
| 144 | + var isReentry = false; // Detect mouse move back to same element. | |
| 145 | + if (tooltipObj.style.display != "none") { | |
| 146 | + if (ix == tooltipInfo.ixHover) | |
| 147 | + return; | |
| 148 | + if (-1 == tooltipInfo.ixHover && ix == tooltipInfo.ixActive) | |
| 149 | + isReentry = true; | |
| 150 | + } | |
| 106 | 151 | /* The tooltip is either not visible, or the mouse is over a different |
| 107 | 152 | ** element, so clear the dwell timer, and record the new element id and |
| 108 | 153 | ** mouse position. */ |
| 109 | - if (tooltipInfo.idTimer != 0) { | |
| 110 | - clearTimeout(tooltipInfo.idTimer); | |
| 111 | - tooltipInfo.idTimer = 0; | |
| 112 | - } | |
| 154 | + stopDwellTimer(); | |
| 113 | 155 | if (ix >= 0) { |
| 114 | 156 | /* Close the tooltip only if the mouse is over another element, and init |
| 115 | 157 | ** the dwell timer again. */ |
| 116 | - tooltipObj.style.display = "none"; | |
| 117 | - tooltipInfo.ixElement = ix; | |
| 158 | + if (!isReentry) | |
| 159 | + hideGraphTooltip(); | |
| 160 | + tooltipInfo.ixHover = ix; | |
| 118 | 161 | tooltipInfo.posX = e.x; |
| 119 | 162 | tooltipInfo.posY = e.y; |
| 120 | - if( tooltipInfo.dwellTimeout>0 ){ | |
| 163 | + /* Clear the close timer, if not already cleared by hideGraphTooltip(). */ | |
| 164 | + stopCloseTimer(); | |
| 165 | + if (!isReentry && tooltipInfo.dwellTimeout>0) { | |
| 121 | 166 | tooltipInfo.idTimer = setTimeout(function() { |
| 122 | 167 | this.tooltipInfo.idTimer = 0; |
| 168 | + /* Clear the timer to hide the tooltip. */ | |
| 169 | + stopCloseTimer(); | |
| 123 | 170 | showGraphTooltip( |
| 124 | - this.tooltipInfo.ixElement, | |
| 171 | + this.tooltipInfo.ixHover, | |
| 125 | 172 | this.tooltipInfo.posX, |
| 126 | 173 | this.tooltipInfo.posY); |
| 174 | + this.tooltipInfo.ixActive = this.tooltipInfo.ixHover; | |
| 127 | 175 | }.bind(window),tooltipInfo.dwellTimeout); |
| 128 | 176 | } |
| 129 | 177 | } |
| 130 | - else | |
| 131 | - tooltipInfo.ixElement = -1; | |
| 178 | + else { | |
| 179 | + tooltipInfo.ixHover = -1; | |
| 180 | + /* The mouse is not over an element with a tooltip, init the hide | |
| 181 | + ** timer. */ | |
| 182 | + resumeCloseTimer(); | |
| 183 | + } | |
| 132 | 184 | }; |
| 133 | 185 | topObj.onmouseleave = function(e) { |
| 134 | 186 | /* Hide the tooltip if the mouse is outside the "timelineTableN" element, |
| 135 | 187 | ** and outside the tooltip. */ |
| 136 | 188 | if (tooltipObj.style.display != "none" && |
| 137 | 189 | e.relatedTarget && |
| 138 | 190 | e.relatedTarget != tooltipObj) { |
| 139 | - tooltipObj.style.display = "none"; | |
| 191 | + tooltipInfo.ixHover = -1; | |
| 192 | + hideGraphTooltip(); | |
| 140 | 193 | /* Clear the dwell timer. */ |
| 141 | - if (tooltipInfo.idTimer != 0) { | |
| 142 | - clearTimeout(tooltipInfo.idTimer); | |
| 143 | - tooltipInfo.idTimer = 0; | |
| 144 | - } | |
| 145 | - tooltipInfo.ixElement = -1; | |
| 194 | + stopDwellTimer(); | |
| 195 | + /* Clear the close timer. */ | |
| 196 | + stopCloseTimer(); | |
| 146 | 197 | } |
| 147 | 198 | }; |
| 148 | 199 | var canvasDiv; |
| 149 | 200 | var railPitch; |
| 150 | 201 | var mergeOffset; |
| @@ -472,11 +523,11 @@ | ||
| 472 | 523 | drawNode(tx.rowinfo[i], btm); |
| 473 | 524 | } |
| 474 | 525 | } |
| 475 | 526 | var selRow; |
| 476 | 527 | function clickOnNode(e){ |
| 477 | - tooltipObj.style.display = "none" | |
| 528 | + hideGraphTooltip() | |
| 478 | 529 | var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow]; |
| 479 | 530 | if( !selRow ){ |
| 480 | 531 | selRow = p; |
| 481 | 532 | this.className += " sel"; |
| 482 | 533 | canvasDiv.className += " sel"; |
| @@ -530,33 +581,32 @@ | ||
| 530 | 581 | var ix = findTxIndex(e); |
| 531 | 582 | showGraphTooltip(ix,e.x,e.y); |
| 532 | 583 | } |
| 533 | 584 | function showGraphTooltip(ix,posX,posY){ |
| 534 | 585 | if( ix<0 ){ |
| 535 | - tooltipObj.style.display = "none" | |
| 586 | + hideGraphTooltip() | |
| 536 | 587 | }else{ |
| 537 | 588 | var br = tx.rowinfo[ix].br |
| 538 | 589 | var dest = branchHyperlink(ix) |
| 539 | 590 | var hbr = br.replace(/&/g, "&") |
| 540 | 591 | .replace(/</g, "<") |
| 541 | 592 | .replace(/>/g, ">") |
| 542 | 593 | .replace(/"/g, """) |
| 543 | 594 | .replace(/'/g, "'"); |
| 544 | 595 | tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>" |
| 545 | - tooltipObj.style.display = "inline" | |
| 546 | 596 | tooltipObj.style.position = "absolute" |
| 547 | 597 | var x = posX + 4 + window.pageXOffset |
| 548 | 598 | tooltipObj.style.left = x+"px" |
| 549 | 599 | var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4 |
| 550 | 600 | tooltipObj.style.top = y+"px" |
| 551 | - tooltipObj.style.visibility = "visible" | |
| 601 | + tooltipObj.style.display = "inline" | |
| 552 | 602 | } |
| 553 | 603 | } |
| 554 | 604 | function dblclickOnGraph(e){ |
| 555 | 605 | var ix = findTxIndex(e); |
| 556 | 606 | var dest = branchHyperlink(ix) |
| 557 | - tooltipObj.style.display = "none" | |
| 607 | + hideGraphTooltip() | |
| 558 | 608 | window.location.href = dest |
| 559 | 609 | } |
| 560 | 610 | function changeDisplay(selector,value){ |
| 561 | 611 | var x = document.getElementsByClassName(selector); |
| 562 | 612 | var n = x.length; |
| 563 | 613 |
| --- src/graph.js | |
| +++ src/graph.js | |
| @@ -75,20 +75,60 @@ | |
| 75 | } |
| 76 | amendCssOnce = 0; |
| 77 | } |
| 78 | var tooltipObj = document.createElement("span"); |
| 79 | tooltipObj.className = "tl-tooltip"; |
| 80 | tooltipObj.style.visibility = "hidden"; |
| 81 | document.getElementsByClassName("content")[0].appendChild(tooltipObj); |
| 82 | /* This object must be in the global scope, so that (non-shadowed) access is |
| 83 | ** possible from within a setTimeout() closure. */ |
| 84 | window.tooltipInfo = { |
| 85 | dwellTimeout: 250, /* The tooltip dwell timeout. */ |
| 86 | idTimer: 0, /* The tooltip dwell timer. */ |
| 87 | ixElement: -1, /* The id of the last hovered element. */ |
| 88 | posX: 0, posY: 0 /* The last mouse position. */ |
| 89 | }; |
| 90 | |
| 91 | /* Construct that graph corresponding to the timeline-data-N object */ |
| 92 | function TimelineGraph(tx){ |
| 93 | var topObj = document.getElementById("timelineTable"+tx.iTableId); |
| 94 | amendCss(tx.circleNodes, tx.showArrowheads); |
| @@ -99,52 +139,63 @@ | |
| 99 | var ix = findTxIndex(e); |
| 100 | var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */ |
| 101 | document.getElementsByTagName('body')[0].style.cursor = cursor; |
| 102 | /* Keep the already visible tooltip at a constant position, as long as the |
| 103 | ** mouse is over the same element. */ |
| 104 | if (tooltipObj.style.display != "none" && ix == tooltipInfo.ixElement) |
| 105 | return; |
| 106 | /* The tooltip is either not visible, or the mouse is over a different |
| 107 | ** element, so clear the dwell timer, and record the new element id and |
| 108 | ** mouse position. */ |
| 109 | if (tooltipInfo.idTimer != 0) { |
| 110 | clearTimeout(tooltipInfo.idTimer); |
| 111 | tooltipInfo.idTimer = 0; |
| 112 | } |
| 113 | if (ix >= 0) { |
| 114 | /* Close the tooltip only if the mouse is over another element, and init |
| 115 | ** the dwell timer again. */ |
| 116 | tooltipObj.style.display = "none"; |
| 117 | tooltipInfo.ixElement = ix; |
| 118 | tooltipInfo.posX = e.x; |
| 119 | tooltipInfo.posY = e.y; |
| 120 | if( tooltipInfo.dwellTimeout>0 ){ |
| 121 | tooltipInfo.idTimer = setTimeout(function() { |
| 122 | this.tooltipInfo.idTimer = 0; |
| 123 | showGraphTooltip( |
| 124 | this.tooltipInfo.ixElement, |
| 125 | this.tooltipInfo.posX, |
| 126 | this.tooltipInfo.posY); |
| 127 | }.bind(window),tooltipInfo.dwellTimeout); |
| 128 | } |
| 129 | } |
| 130 | else |
| 131 | tooltipInfo.ixElement = -1; |
| 132 | }; |
| 133 | topObj.onmouseleave = function(e) { |
| 134 | /* Hide the tooltip if the mouse is outside the "timelineTableN" element, |
| 135 | ** and outside the tooltip. */ |
| 136 | if (tooltipObj.style.display != "none" && |
| 137 | e.relatedTarget && |
| 138 | e.relatedTarget != tooltipObj) { |
| 139 | tooltipObj.style.display = "none"; |
| 140 | /* Clear the dwell timer. */ |
| 141 | if (tooltipInfo.idTimer != 0) { |
| 142 | clearTimeout(tooltipInfo.idTimer); |
| 143 | tooltipInfo.idTimer = 0; |
| 144 | } |
| 145 | tooltipInfo.ixElement = -1; |
| 146 | } |
| 147 | }; |
| 148 | var canvasDiv; |
| 149 | var railPitch; |
| 150 | var mergeOffset; |
| @@ -472,11 +523,11 @@ | |
| 472 | drawNode(tx.rowinfo[i], btm); |
| 473 | } |
| 474 | } |
| 475 | var selRow; |
| 476 | function clickOnNode(e){ |
| 477 | tooltipObj.style.display = "none" |
| 478 | var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow]; |
| 479 | if( !selRow ){ |
| 480 | selRow = p; |
| 481 | this.className += " sel"; |
| 482 | canvasDiv.className += " sel"; |
| @@ -530,33 +581,32 @@ | |
| 530 | var ix = findTxIndex(e); |
| 531 | showGraphTooltip(ix,e.x,e.y); |
| 532 | } |
| 533 | function showGraphTooltip(ix,posX,posY){ |
| 534 | if( ix<0 ){ |
| 535 | tooltipObj.style.display = "none" |
| 536 | }else{ |
| 537 | var br = tx.rowinfo[ix].br |
| 538 | var dest = branchHyperlink(ix) |
| 539 | var hbr = br.replace(/&/g, "&") |
| 540 | .replace(/</g, "<") |
| 541 | .replace(/>/g, ">") |
| 542 | .replace(/"/g, """) |
| 543 | .replace(/'/g, "'"); |
| 544 | tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>" |
| 545 | tooltipObj.style.display = "inline" |
| 546 | tooltipObj.style.position = "absolute" |
| 547 | var x = posX + 4 + window.pageXOffset |
| 548 | tooltipObj.style.left = x+"px" |
| 549 | var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4 |
| 550 | tooltipObj.style.top = y+"px" |
| 551 | tooltipObj.style.visibility = "visible" |
| 552 | } |
| 553 | } |
| 554 | function dblclickOnGraph(e){ |
| 555 | var ix = findTxIndex(e); |
| 556 | var dest = branchHyperlink(ix) |
| 557 | tooltipObj.style.display = "none" |
| 558 | window.location.href = dest |
| 559 | } |
| 560 | function changeDisplay(selector,value){ |
| 561 | var x = document.getElementsByClassName(selector); |
| 562 | var n = x.length; |
| 563 |
| --- src/graph.js | |
| +++ src/graph.js | |
| @@ -75,20 +75,60 @@ | |
| 75 | } |
| 76 | amendCssOnce = 0; |
| 77 | } |
| 78 | var tooltipObj = document.createElement("span"); |
| 79 | tooltipObj.className = "tl-tooltip"; |
| 80 | tooltipObj.style.display = "none"; |
| 81 | document.getElementsByClassName("content")[0].appendChild(tooltipObj); |
| 82 | /* Clear the close timer if the mouse is over the tooltip. */ |
| 83 | tooltipObj.onmouseenter = function(e) { |
| 84 | stopCloseTimer(); |
| 85 | }; |
| 86 | /* Init the close timer if the mouse is no longer over the tooltip. */ |
| 87 | tooltipObj.onmouseleave = function(e) { |
| 88 | if (tooltipInfo.ixActive != -1) |
| 89 | resumeCloseTimer(); |
| 90 | }; |
| 91 | /* This object must be in the global scope, so that (non-shadowed) access is |
| 92 | ** possible from within a setTimeout() closure. */ |
| 93 | window.tooltipInfo = { |
| 94 | dwellTimeout: 250, /* The tooltip dwell timeout. */ |
| 95 | closeTimeout: 3000, /* The tooltip close timeout. */ |
| 96 | idTimer: 0, /* The tooltip dwell timer id. */ |
| 97 | idTimerClose: 0, /* The tooltip close timer id. */ |
| 98 | ixHover: -1, /* The id of the element with the mouse. */ |
| 99 | ixActive: -1, /* The id of the element with the tooltip. */ |
| 100 | posX: 0, posY: 0 /* The last mouse position. */ |
| 101 | }; |
| 102 | /* These functions must be in the global scope, so that access is possible from |
| 103 | ** within (non-local) event handlers. */ |
| 104 | var hideGraphTooltip = function() { |
| 105 | stopCloseTimer(); |
| 106 | tooltipObj.style.display = "none"; |
| 107 | this.tooltipInfo.ixActive = -1; |
| 108 | }.bind(window); |
| 109 | var stopDwellTimer = function() { |
| 110 | if (this.tooltipInfo.idTimer != 0) { |
| 111 | clearTimeout(this.tooltipInfo.idTimer); |
| 112 | this.tooltipInfo.idTimer = 0; |
| 113 | } |
| 114 | }.bind(window); |
| 115 | var resumeCloseTimer = function() { |
| 116 | /* This timer must be stopped explicitly to reset the elapsed timeout. */ |
| 117 | if (this.tooltipInfo.idTimerClose == 0) { |
| 118 | this.tooltipInfo.idTimerClose = setTimeout(function() { |
| 119 | this.tooltipInfo.idTimerClose = 0; |
| 120 | hideGraphTooltip(); |
| 121 | }.bind(window),this.tooltipInfo.closeTimeout); |
| 122 | } |
| 123 | }.bind(window); |
| 124 | var stopCloseTimer = function() { |
| 125 | if (this.tooltipInfo.idTimerClose != 0) { |
| 126 | clearTimeout(this.tooltipInfo.idTimerClose); |
| 127 | this.tooltipInfo.idTimerClose = 0; |
| 128 | } |
| 129 | }.bind(window); |
| 130 | |
| 131 | /* Construct that graph corresponding to the timeline-data-N object */ |
| 132 | function TimelineGraph(tx){ |
| 133 | var topObj = document.getElementById("timelineTable"+tx.iTableId); |
| 134 | amendCss(tx.circleNodes, tx.showArrowheads); |
| @@ -99,52 +139,63 @@ | |
| 139 | var ix = findTxIndex(e); |
| 140 | var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */ |
| 141 | document.getElementsByTagName('body')[0].style.cursor = cursor; |
| 142 | /* Keep the already visible tooltip at a constant position, as long as the |
| 143 | ** mouse is over the same element. */ |
| 144 | var isReentry = false; // Detect mouse move back to same element. |
| 145 | if (tooltipObj.style.display != "none") { |
| 146 | if (ix == tooltipInfo.ixHover) |
| 147 | return; |
| 148 | if (-1 == tooltipInfo.ixHover && ix == tooltipInfo.ixActive) |
| 149 | isReentry = true; |
| 150 | } |
| 151 | /* The tooltip is either not visible, or the mouse is over a different |
| 152 | ** element, so clear the dwell timer, and record the new element id and |
| 153 | ** mouse position. */ |
| 154 | stopDwellTimer(); |
| 155 | if (ix >= 0) { |
| 156 | /* Close the tooltip only if the mouse is over another element, and init |
| 157 | ** the dwell timer again. */ |
| 158 | if (!isReentry) |
| 159 | hideGraphTooltip(); |
| 160 | tooltipInfo.ixHover = ix; |
| 161 | tooltipInfo.posX = e.x; |
| 162 | tooltipInfo.posY = e.y; |
| 163 | /* Clear the close timer, if not already cleared by hideGraphTooltip(). */ |
| 164 | stopCloseTimer(); |
| 165 | if (!isReentry && tooltipInfo.dwellTimeout>0) { |
| 166 | tooltipInfo.idTimer = setTimeout(function() { |
| 167 | this.tooltipInfo.idTimer = 0; |
| 168 | /* Clear the timer to hide the tooltip. */ |
| 169 | stopCloseTimer(); |
| 170 | showGraphTooltip( |
| 171 | this.tooltipInfo.ixHover, |
| 172 | this.tooltipInfo.posX, |
| 173 | this.tooltipInfo.posY); |
| 174 | this.tooltipInfo.ixActive = this.tooltipInfo.ixHover; |
| 175 | }.bind(window),tooltipInfo.dwellTimeout); |
| 176 | } |
| 177 | } |
| 178 | else { |
| 179 | tooltipInfo.ixHover = -1; |
| 180 | /* The mouse is not over an element with a tooltip, init the hide |
| 181 | ** timer. */ |
| 182 | resumeCloseTimer(); |
| 183 | } |
| 184 | }; |
| 185 | topObj.onmouseleave = function(e) { |
| 186 | /* Hide the tooltip if the mouse is outside the "timelineTableN" element, |
| 187 | ** and outside the tooltip. */ |
| 188 | if (tooltipObj.style.display != "none" && |
| 189 | e.relatedTarget && |
| 190 | e.relatedTarget != tooltipObj) { |
| 191 | tooltipInfo.ixHover = -1; |
| 192 | hideGraphTooltip(); |
| 193 | /* Clear the dwell timer. */ |
| 194 | stopDwellTimer(); |
| 195 | /* Clear the close timer. */ |
| 196 | stopCloseTimer(); |
| 197 | } |
| 198 | }; |
| 199 | var canvasDiv; |
| 200 | var railPitch; |
| 201 | var mergeOffset; |
| @@ -472,11 +523,11 @@ | |
| 523 | drawNode(tx.rowinfo[i], btm); |
| 524 | } |
| 525 | } |
| 526 | var selRow; |
| 527 | function clickOnNode(e){ |
| 528 | hideGraphTooltip() |
| 529 | var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow]; |
| 530 | if( !selRow ){ |
| 531 | selRow = p; |
| 532 | this.className += " sel"; |
| 533 | canvasDiv.className += " sel"; |
| @@ -530,33 +581,32 @@ | |
| 581 | var ix = findTxIndex(e); |
| 582 | showGraphTooltip(ix,e.x,e.y); |
| 583 | } |
| 584 | function showGraphTooltip(ix,posX,posY){ |
| 585 | if( ix<0 ){ |
| 586 | hideGraphTooltip() |
| 587 | }else{ |
| 588 | var br = tx.rowinfo[ix].br |
| 589 | var dest = branchHyperlink(ix) |
| 590 | var hbr = br.replace(/&/g, "&") |
| 591 | .replace(/</g, "<") |
| 592 | .replace(/>/g, ">") |
| 593 | .replace(/"/g, """) |
| 594 | .replace(/'/g, "'"); |
| 595 | tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>" |
| 596 | tooltipObj.style.position = "absolute" |
| 597 | var x = posX + 4 + window.pageXOffset |
| 598 | tooltipObj.style.left = x+"px" |
| 599 | var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4 |
| 600 | tooltipObj.style.top = y+"px" |
| 601 | tooltipObj.style.display = "inline" |
| 602 | } |
| 603 | } |
| 604 | function dblclickOnGraph(e){ |
| 605 | var ix = findTxIndex(e); |
| 606 | var dest = branchHyperlink(ix) |
| 607 | hideGraphTooltip() |
| 608 | window.location.href = dest |
| 609 | } |
| 610 | function changeDisplay(selector,value){ |
| 611 | var x = document.getElementsByClassName(selector); |
| 612 | var n = x.length; |
| 613 |
+76
-26
| --- src/graph.js | ||
| +++ src/graph.js | ||
| @@ -75,20 +75,60 @@ | ||
| 75 | 75 | } |
| 76 | 76 | amendCssOnce = 0; |
| 77 | 77 | } |
| 78 | 78 | var tooltipObj = document.createElement("span"); |
| 79 | 79 | tooltipObj.className = "tl-tooltip"; |
| 80 | -tooltipObj.style.visibility = "hidden"; | |
| 80 | +tooltipObj.style.display = "none"; | |
| 81 | 81 | document.getElementsByClassName("content")[0].appendChild(tooltipObj); |
| 82 | +/* Clear the close timer if the mouse is over the tooltip. */ | |
| 83 | +tooltipObj.onmouseenter = function(e) { | |
| 84 | + stopCloseTimer(); | |
| 85 | +}; | |
| 86 | +/* Init the close timer if the mouse is no longer over the tooltip. */ | |
| 87 | +tooltipObj.onmouseleave = function(e) { | |
| 88 | + if (tooltipInfo.ixActive != -1) | |
| 89 | + resumeCloseTimer(); | |
| 90 | +}; | |
| 82 | 91 | /* This object must be in the global scope, so that (non-shadowed) access is |
| 83 | 92 | ** possible from within a setTimeout() closure. */ |
| 84 | 93 | window.tooltipInfo = { |
| 85 | 94 | dwellTimeout: 250, /* The tooltip dwell timeout. */ |
| 86 | - idTimer: 0, /* The tooltip dwell timer. */ | |
| 87 | - ixElement: -1, /* The id of the last hovered element. */ | |
| 95 | + closeTimeout: 3000, /* The tooltip close timeout. */ | |
| 96 | + idTimer: 0, /* The tooltip dwell timer id. */ | |
| 97 | + idTimerClose: 0, /* The tooltip close timer id. */ | |
| 98 | + ixHover: -1, /* The id of the element with the mouse. */ | |
| 99 | + ixActive: -1, /* The id of the element with the tooltip. */ | |
| 88 | 100 | posX: 0, posY: 0 /* The last mouse position. */ |
| 89 | 101 | }; |
| 102 | +/* These functions must be in the global scope, so that access is possible from | |
| 103 | +** within (non-local) event handlers. */ | |
| 104 | +var hideGraphTooltip = function() { | |
| 105 | + stopCloseTimer(); | |
| 106 | + tooltipObj.style.display = "none"; | |
| 107 | + this.tooltipInfo.ixActive = -1; | |
| 108 | +}.bind(window); | |
| 109 | +var stopDwellTimer = function() { | |
| 110 | + if (this.tooltipInfo.idTimer != 0) { | |
| 111 | + clearTimeout(this.tooltipInfo.idTimer); | |
| 112 | + this.tooltipInfo.idTimer = 0; | |
| 113 | + } | |
| 114 | +}.bind(window); | |
| 115 | +var resumeCloseTimer = function() { | |
| 116 | + /* This timer must be stopped explicitly to reset the elapsed timeout. */ | |
| 117 | + if (this.tooltipInfo.idTimerClose == 0) { | |
| 118 | + this.tooltipInfo.idTimerClose = setTimeout(function() { | |
| 119 | + this.tooltipInfo.idTimerClose = 0; | |
| 120 | + hideGraphTooltip(); | |
| 121 | + }.bind(window),this.tooltipInfo.closeTimeout); | |
| 122 | + } | |
| 123 | +}.bind(window); | |
| 124 | +var stopCloseTimer = function() { | |
| 125 | + if (this.tooltipInfo.idTimerClose != 0) { | |
| 126 | + clearTimeout(this.tooltipInfo.idTimerClose); | |
| 127 | + this.tooltipInfo.idTimerClose = 0; | |
| 128 | + } | |
| 129 | +}.bind(window); | |
| 90 | 130 | |
| 91 | 131 | /* Construct that graph corresponding to the timeline-data-N object */ |
| 92 | 132 | function TimelineGraph(tx){ |
| 93 | 133 | var topObj = document.getElementById("timelineTable"+tx.iTableId); |
| 94 | 134 | amendCss(tx.circleNodes, tx.showArrowheads); |
| @@ -99,52 +139,63 @@ | ||
| 99 | 139 | var ix = findTxIndex(e); |
| 100 | 140 | var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */ |
| 101 | 141 | document.getElementsByTagName('body')[0].style.cursor = cursor; |
| 102 | 142 | /* Keep the already visible tooltip at a constant position, as long as the |
| 103 | 143 | ** mouse is over the same element. */ |
| 104 | - if (tooltipObj.style.display != "none" && ix == tooltipInfo.ixElement) | |
| 105 | - return; | |
| 144 | + var isReentry = false; // Detect mouse move back to same element. | |
| 145 | + if (tooltipObj.style.display != "none") { | |
| 146 | + if (ix == tooltipInfo.ixHover) | |
| 147 | + return; | |
| 148 | + if (-1 == tooltipInfo.ixHover && ix == tooltipInfo.ixActive) | |
| 149 | + isReentry = true; | |
| 150 | + } | |
| 106 | 151 | /* The tooltip is either not visible, or the mouse is over a different |
| 107 | 152 | ** element, so clear the dwell timer, and record the new element id and |
| 108 | 153 | ** mouse position. */ |
| 109 | - if (tooltipInfo.idTimer != 0) { | |
| 110 | - clearTimeout(tooltipInfo.idTimer); | |
| 111 | - tooltipInfo.idTimer = 0; | |
| 112 | - } | |
| 154 | + stopDwellTimer(); | |
| 113 | 155 | if (ix >= 0) { |
| 114 | 156 | /* Close the tooltip only if the mouse is over another element, and init |
| 115 | 157 | ** the dwell timer again. */ |
| 116 | - tooltipObj.style.display = "none"; | |
| 117 | - tooltipInfo.ixElement = ix; | |
| 158 | + if (!isReentry) | |
| 159 | + hideGraphTooltip(); | |
| 160 | + tooltipInfo.ixHover = ix; | |
| 118 | 161 | tooltipInfo.posX = e.x; |
| 119 | 162 | tooltipInfo.posY = e.y; |
| 120 | - if( tooltipInfo.dwellTimeout>0 ){ | |
| 163 | + /* Clear the close timer, if not already cleared by hideGraphTooltip(). */ | |
| 164 | + stopCloseTimer(); | |
| 165 | + if (!isReentry && tooltipInfo.dwellTimeout>0) { | |
| 121 | 166 | tooltipInfo.idTimer = setTimeout(function() { |
| 122 | 167 | this.tooltipInfo.idTimer = 0; |
| 168 | + /* Clear the timer to hide the tooltip. */ | |
| 169 | + stopCloseTimer(); | |
| 123 | 170 | showGraphTooltip( |
| 124 | - this.tooltipInfo.ixElement, | |
| 171 | + this.tooltipInfo.ixHover, | |
| 125 | 172 | this.tooltipInfo.posX, |
| 126 | 173 | this.tooltipInfo.posY); |
| 174 | + this.tooltipInfo.ixActive = this.tooltipInfo.ixHover; | |
| 127 | 175 | }.bind(window),tooltipInfo.dwellTimeout); |
| 128 | 176 | } |
| 129 | 177 | } |
| 130 | - else | |
| 131 | - tooltipInfo.ixElement = -1; | |
| 178 | + else { | |
| 179 | + tooltipInfo.ixHover = -1; | |
| 180 | + /* The mouse is not over an element with a tooltip, init the hide | |
| 181 | + ** timer. */ | |
| 182 | + resumeCloseTimer(); | |
| 183 | + } | |
| 132 | 184 | }; |
| 133 | 185 | topObj.onmouseleave = function(e) { |
| 134 | 186 | /* Hide the tooltip if the mouse is outside the "timelineTableN" element, |
| 135 | 187 | ** and outside the tooltip. */ |
| 136 | 188 | if (tooltipObj.style.display != "none" && |
| 137 | 189 | e.relatedTarget && |
| 138 | 190 | e.relatedTarget != tooltipObj) { |
| 139 | - tooltipObj.style.display = "none"; | |
| 191 | + tooltipInfo.ixHover = -1; | |
| 192 | + hideGraphTooltip(); | |
| 140 | 193 | /* Clear the dwell timer. */ |
| 141 | - if (tooltipInfo.idTimer != 0) { | |
| 142 | - clearTimeout(tooltipInfo.idTimer); | |
| 143 | - tooltipInfo.idTimer = 0; | |
| 144 | - } | |
| 145 | - tooltipInfo.ixElement = -1; | |
| 194 | + stopDwellTimer(); | |
| 195 | + /* Clear the close timer. */ | |
| 196 | + stopCloseTimer(); | |
| 146 | 197 | } |
| 147 | 198 | }; |
| 148 | 199 | var canvasDiv; |
| 149 | 200 | var railPitch; |
| 150 | 201 | var mergeOffset; |
| @@ -472,11 +523,11 @@ | ||
| 472 | 523 | drawNode(tx.rowinfo[i], btm); |
| 473 | 524 | } |
| 474 | 525 | } |
| 475 | 526 | var selRow; |
| 476 | 527 | function clickOnNode(e){ |
| 477 | - tooltipObj.style.display = "none" | |
| 528 | + hideGraphTooltip() | |
| 478 | 529 | var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow]; |
| 479 | 530 | if( !selRow ){ |
| 480 | 531 | selRow = p; |
| 481 | 532 | this.className += " sel"; |
| 482 | 533 | canvasDiv.className += " sel"; |
| @@ -530,33 +581,32 @@ | ||
| 530 | 581 | var ix = findTxIndex(e); |
| 531 | 582 | showGraphTooltip(ix,e.x,e.y); |
| 532 | 583 | } |
| 533 | 584 | function showGraphTooltip(ix,posX,posY){ |
| 534 | 585 | if( ix<0 ){ |
| 535 | - tooltipObj.style.display = "none" | |
| 586 | + hideGraphTooltip() | |
| 536 | 587 | }else{ |
| 537 | 588 | var br = tx.rowinfo[ix].br |
| 538 | 589 | var dest = branchHyperlink(ix) |
| 539 | 590 | var hbr = br.replace(/&/g, "&") |
| 540 | 591 | .replace(/</g, "<") |
| 541 | 592 | .replace(/>/g, ">") |
| 542 | 593 | .replace(/"/g, """) |
| 543 | 594 | .replace(/'/g, "'"); |
| 544 | 595 | tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>" |
| 545 | - tooltipObj.style.display = "inline" | |
| 546 | 596 | tooltipObj.style.position = "absolute" |
| 547 | 597 | var x = posX + 4 + window.pageXOffset |
| 548 | 598 | tooltipObj.style.left = x+"px" |
| 549 | 599 | var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4 |
| 550 | 600 | tooltipObj.style.top = y+"px" |
| 551 | - tooltipObj.style.visibility = "visible" | |
| 601 | + tooltipObj.style.display = "inline" | |
| 552 | 602 | } |
| 553 | 603 | } |
| 554 | 604 | function dblclickOnGraph(e){ |
| 555 | 605 | var ix = findTxIndex(e); |
| 556 | 606 | var dest = branchHyperlink(ix) |
| 557 | - tooltipObj.style.display = "none" | |
| 607 | + hideGraphTooltip() | |
| 558 | 608 | window.location.href = dest |
| 559 | 609 | } |
| 560 | 610 | function changeDisplay(selector,value){ |
| 561 | 611 | var x = document.getElementsByClassName(selector); |
| 562 | 612 | var n = x.length; |
| 563 | 613 |
| --- src/graph.js | |
| +++ src/graph.js | |
| @@ -75,20 +75,60 @@ | |
| 75 | } |
| 76 | amendCssOnce = 0; |
| 77 | } |
| 78 | var tooltipObj = document.createElement("span"); |
| 79 | tooltipObj.className = "tl-tooltip"; |
| 80 | tooltipObj.style.visibility = "hidden"; |
| 81 | document.getElementsByClassName("content")[0].appendChild(tooltipObj); |
| 82 | /* This object must be in the global scope, so that (non-shadowed) access is |
| 83 | ** possible from within a setTimeout() closure. */ |
| 84 | window.tooltipInfo = { |
| 85 | dwellTimeout: 250, /* The tooltip dwell timeout. */ |
| 86 | idTimer: 0, /* The tooltip dwell timer. */ |
| 87 | ixElement: -1, /* The id of the last hovered element. */ |
| 88 | posX: 0, posY: 0 /* The last mouse position. */ |
| 89 | }; |
| 90 | |
| 91 | /* Construct that graph corresponding to the timeline-data-N object */ |
| 92 | function TimelineGraph(tx){ |
| 93 | var topObj = document.getElementById("timelineTable"+tx.iTableId); |
| 94 | amendCss(tx.circleNodes, tx.showArrowheads); |
| @@ -99,52 +139,63 @@ | |
| 99 | var ix = findTxIndex(e); |
| 100 | var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */ |
| 101 | document.getElementsByTagName('body')[0].style.cursor = cursor; |
| 102 | /* Keep the already visible tooltip at a constant position, as long as the |
| 103 | ** mouse is over the same element. */ |
| 104 | if (tooltipObj.style.display != "none" && ix == tooltipInfo.ixElement) |
| 105 | return; |
| 106 | /* The tooltip is either not visible, or the mouse is over a different |
| 107 | ** element, so clear the dwell timer, and record the new element id and |
| 108 | ** mouse position. */ |
| 109 | if (tooltipInfo.idTimer != 0) { |
| 110 | clearTimeout(tooltipInfo.idTimer); |
| 111 | tooltipInfo.idTimer = 0; |
| 112 | } |
| 113 | if (ix >= 0) { |
| 114 | /* Close the tooltip only if the mouse is over another element, and init |
| 115 | ** the dwell timer again. */ |
| 116 | tooltipObj.style.display = "none"; |
| 117 | tooltipInfo.ixElement = ix; |
| 118 | tooltipInfo.posX = e.x; |
| 119 | tooltipInfo.posY = e.y; |
| 120 | if( tooltipInfo.dwellTimeout>0 ){ |
| 121 | tooltipInfo.idTimer = setTimeout(function() { |
| 122 | this.tooltipInfo.idTimer = 0; |
| 123 | showGraphTooltip( |
| 124 | this.tooltipInfo.ixElement, |
| 125 | this.tooltipInfo.posX, |
| 126 | this.tooltipInfo.posY); |
| 127 | }.bind(window),tooltipInfo.dwellTimeout); |
| 128 | } |
| 129 | } |
| 130 | else |
| 131 | tooltipInfo.ixElement = -1; |
| 132 | }; |
| 133 | topObj.onmouseleave = function(e) { |
| 134 | /* Hide the tooltip if the mouse is outside the "timelineTableN" element, |
| 135 | ** and outside the tooltip. */ |
| 136 | if (tooltipObj.style.display != "none" && |
| 137 | e.relatedTarget && |
| 138 | e.relatedTarget != tooltipObj) { |
| 139 | tooltipObj.style.display = "none"; |
| 140 | /* Clear the dwell timer. */ |
| 141 | if (tooltipInfo.idTimer != 0) { |
| 142 | clearTimeout(tooltipInfo.idTimer); |
| 143 | tooltipInfo.idTimer = 0; |
| 144 | } |
| 145 | tooltipInfo.ixElement = -1; |
| 146 | } |
| 147 | }; |
| 148 | var canvasDiv; |
| 149 | var railPitch; |
| 150 | var mergeOffset; |
| @@ -472,11 +523,11 @@ | |
| 472 | drawNode(tx.rowinfo[i], btm); |
| 473 | } |
| 474 | } |
| 475 | var selRow; |
| 476 | function clickOnNode(e){ |
| 477 | tooltipObj.style.display = "none" |
| 478 | var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow]; |
| 479 | if( !selRow ){ |
| 480 | selRow = p; |
| 481 | this.className += " sel"; |
| 482 | canvasDiv.className += " sel"; |
| @@ -530,33 +581,32 @@ | |
| 530 | var ix = findTxIndex(e); |
| 531 | showGraphTooltip(ix,e.x,e.y); |
| 532 | } |
| 533 | function showGraphTooltip(ix,posX,posY){ |
| 534 | if( ix<0 ){ |
| 535 | tooltipObj.style.display = "none" |
| 536 | }else{ |
| 537 | var br = tx.rowinfo[ix].br |
| 538 | var dest = branchHyperlink(ix) |
| 539 | var hbr = br.replace(/&/g, "&") |
| 540 | .replace(/</g, "<") |
| 541 | .replace(/>/g, ">") |
| 542 | .replace(/"/g, """) |
| 543 | .replace(/'/g, "'"); |
| 544 | tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>" |
| 545 | tooltipObj.style.display = "inline" |
| 546 | tooltipObj.style.position = "absolute" |
| 547 | var x = posX + 4 + window.pageXOffset |
| 548 | tooltipObj.style.left = x+"px" |
| 549 | var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4 |
| 550 | tooltipObj.style.top = y+"px" |
| 551 | tooltipObj.style.visibility = "visible" |
| 552 | } |
| 553 | } |
| 554 | function dblclickOnGraph(e){ |
| 555 | var ix = findTxIndex(e); |
| 556 | var dest = branchHyperlink(ix) |
| 557 | tooltipObj.style.display = "none" |
| 558 | window.location.href = dest |
| 559 | } |
| 560 | function changeDisplay(selector,value){ |
| 561 | var x = document.getElementsByClassName(selector); |
| 562 | var n = x.length; |
| 563 |
| --- src/graph.js | |
| +++ src/graph.js | |
| @@ -75,20 +75,60 @@ | |
| 75 | } |
| 76 | amendCssOnce = 0; |
| 77 | } |
| 78 | var tooltipObj = document.createElement("span"); |
| 79 | tooltipObj.className = "tl-tooltip"; |
| 80 | tooltipObj.style.display = "none"; |
| 81 | document.getElementsByClassName("content")[0].appendChild(tooltipObj); |
| 82 | /* Clear the close timer if the mouse is over the tooltip. */ |
| 83 | tooltipObj.onmouseenter = function(e) { |
| 84 | stopCloseTimer(); |
| 85 | }; |
| 86 | /* Init the close timer if the mouse is no longer over the tooltip. */ |
| 87 | tooltipObj.onmouseleave = function(e) { |
| 88 | if (tooltipInfo.ixActive != -1) |
| 89 | resumeCloseTimer(); |
| 90 | }; |
| 91 | /* This object must be in the global scope, so that (non-shadowed) access is |
| 92 | ** possible from within a setTimeout() closure. */ |
| 93 | window.tooltipInfo = { |
| 94 | dwellTimeout: 250, /* The tooltip dwell timeout. */ |
| 95 | closeTimeout: 3000, /* The tooltip close timeout. */ |
| 96 | idTimer: 0, /* The tooltip dwell timer id. */ |
| 97 | idTimerClose: 0, /* The tooltip close timer id. */ |
| 98 | ixHover: -1, /* The id of the element with the mouse. */ |
| 99 | ixActive: -1, /* The id of the element with the tooltip. */ |
| 100 | posX: 0, posY: 0 /* The last mouse position. */ |
| 101 | }; |
| 102 | /* These functions must be in the global scope, so that access is possible from |
| 103 | ** within (non-local) event handlers. */ |
| 104 | var hideGraphTooltip = function() { |
| 105 | stopCloseTimer(); |
| 106 | tooltipObj.style.display = "none"; |
| 107 | this.tooltipInfo.ixActive = -1; |
| 108 | }.bind(window); |
| 109 | var stopDwellTimer = function() { |
| 110 | if (this.tooltipInfo.idTimer != 0) { |
| 111 | clearTimeout(this.tooltipInfo.idTimer); |
| 112 | this.tooltipInfo.idTimer = 0; |
| 113 | } |
| 114 | }.bind(window); |
| 115 | var resumeCloseTimer = function() { |
| 116 | /* This timer must be stopped explicitly to reset the elapsed timeout. */ |
| 117 | if (this.tooltipInfo.idTimerClose == 0) { |
| 118 | this.tooltipInfo.idTimerClose = setTimeout(function() { |
| 119 | this.tooltipInfo.idTimerClose = 0; |
| 120 | hideGraphTooltip(); |
| 121 | }.bind(window),this.tooltipInfo.closeTimeout); |
| 122 | } |
| 123 | }.bind(window); |
| 124 | var stopCloseTimer = function() { |
| 125 | if (this.tooltipInfo.idTimerClose != 0) { |
| 126 | clearTimeout(this.tooltipInfo.idTimerClose); |
| 127 | this.tooltipInfo.idTimerClose = 0; |
| 128 | } |
| 129 | }.bind(window); |
| 130 | |
| 131 | /* Construct that graph corresponding to the timeline-data-N object */ |
| 132 | function TimelineGraph(tx){ |
| 133 | var topObj = document.getElementById("timelineTable"+tx.iTableId); |
| 134 | amendCss(tx.circleNodes, tx.showArrowheads); |
| @@ -99,52 +139,63 @@ | |
| 139 | var ix = findTxIndex(e); |
| 140 | var cursor = (ix<0) ? "" : "pointer"; /* Or: cursor = "help"? */ |
| 141 | document.getElementsByTagName('body')[0].style.cursor = cursor; |
| 142 | /* Keep the already visible tooltip at a constant position, as long as the |
| 143 | ** mouse is over the same element. */ |
| 144 | var isReentry = false; // Detect mouse move back to same element. |
| 145 | if (tooltipObj.style.display != "none") { |
| 146 | if (ix == tooltipInfo.ixHover) |
| 147 | return; |
| 148 | if (-1 == tooltipInfo.ixHover && ix == tooltipInfo.ixActive) |
| 149 | isReentry = true; |
| 150 | } |
| 151 | /* The tooltip is either not visible, or the mouse is over a different |
| 152 | ** element, so clear the dwell timer, and record the new element id and |
| 153 | ** mouse position. */ |
| 154 | stopDwellTimer(); |
| 155 | if (ix >= 0) { |
| 156 | /* Close the tooltip only if the mouse is over another element, and init |
| 157 | ** the dwell timer again. */ |
| 158 | if (!isReentry) |
| 159 | hideGraphTooltip(); |
| 160 | tooltipInfo.ixHover = ix; |
| 161 | tooltipInfo.posX = e.x; |
| 162 | tooltipInfo.posY = e.y; |
| 163 | /* Clear the close timer, if not already cleared by hideGraphTooltip(). */ |
| 164 | stopCloseTimer(); |
| 165 | if (!isReentry && tooltipInfo.dwellTimeout>0) { |
| 166 | tooltipInfo.idTimer = setTimeout(function() { |
| 167 | this.tooltipInfo.idTimer = 0; |
| 168 | /* Clear the timer to hide the tooltip. */ |
| 169 | stopCloseTimer(); |
| 170 | showGraphTooltip( |
| 171 | this.tooltipInfo.ixHover, |
| 172 | this.tooltipInfo.posX, |
| 173 | this.tooltipInfo.posY); |
| 174 | this.tooltipInfo.ixActive = this.tooltipInfo.ixHover; |
| 175 | }.bind(window),tooltipInfo.dwellTimeout); |
| 176 | } |
| 177 | } |
| 178 | else { |
| 179 | tooltipInfo.ixHover = -1; |
| 180 | /* The mouse is not over an element with a tooltip, init the hide |
| 181 | ** timer. */ |
| 182 | resumeCloseTimer(); |
| 183 | } |
| 184 | }; |
| 185 | topObj.onmouseleave = function(e) { |
| 186 | /* Hide the tooltip if the mouse is outside the "timelineTableN" element, |
| 187 | ** and outside the tooltip. */ |
| 188 | if (tooltipObj.style.display != "none" && |
| 189 | e.relatedTarget && |
| 190 | e.relatedTarget != tooltipObj) { |
| 191 | tooltipInfo.ixHover = -1; |
| 192 | hideGraphTooltip(); |
| 193 | /* Clear the dwell timer. */ |
| 194 | stopDwellTimer(); |
| 195 | /* Clear the close timer. */ |
| 196 | stopCloseTimer(); |
| 197 | } |
| 198 | }; |
| 199 | var canvasDiv; |
| 200 | var railPitch; |
| 201 | var mergeOffset; |
| @@ -472,11 +523,11 @@ | |
| 523 | drawNode(tx.rowinfo[i], btm); |
| 524 | } |
| 525 | } |
| 526 | var selRow; |
| 527 | function clickOnNode(e){ |
| 528 | hideGraphTooltip() |
| 529 | var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow]; |
| 530 | if( !selRow ){ |
| 531 | selRow = p; |
| 532 | this.className += " sel"; |
| 533 | canvasDiv.className += " sel"; |
| @@ -530,33 +581,32 @@ | |
| 581 | var ix = findTxIndex(e); |
| 582 | showGraphTooltip(ix,e.x,e.y); |
| 583 | } |
| 584 | function showGraphTooltip(ix,posX,posY){ |
| 585 | if( ix<0 ){ |
| 586 | hideGraphTooltip() |
| 587 | }else{ |
| 588 | var br = tx.rowinfo[ix].br |
| 589 | var dest = branchHyperlink(ix) |
| 590 | var hbr = br.replace(/&/g, "&") |
| 591 | .replace(/</g, "<") |
| 592 | .replace(/>/g, ">") |
| 593 | .replace(/"/g, """) |
| 594 | .replace(/'/g, "'"); |
| 595 | tooltipObj.innerHTML = "<a href=\""+dest+"\">"+hbr+"</a>" |
| 596 | tooltipObj.style.position = "absolute" |
| 597 | var x = posX + 4 + window.pageXOffset |
| 598 | tooltipObj.style.left = x+"px" |
| 599 | var y = posY + window.pageYOffset - tooltipObj.clientHeight - 4 |
| 600 | tooltipObj.style.top = y+"px" |
| 601 | tooltipObj.style.display = "inline" |
| 602 | } |
| 603 | } |
| 604 | function dblclickOnGraph(e){ |
| 605 | var ix = findTxIndex(e); |
| 606 | var dest = branchHyperlink(ix) |
| 607 | hideGraphTooltip() |
| 608 | window.location.href = dest |
| 609 | } |
| 610 | function changeDisplay(selector,value){ |
| 611 | var x = document.getElementsByClassName(selector); |
| 612 | var n = x.length; |
| 613 |