Skip to content

Commit cdd836c

Browse files
authored
Merge pull request #5302 from Displayr/5291-dynamic-transforms
5291: recalculation of dynamic CSS transforms on hover
2 parents f7baf5d + b97895f commit cdd836c

File tree

19 files changed

+161
-80
lines changed

19 files changed

+161
-80
lines changed

src/components/fx/hover.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ exports.loneHover = function loneHover(hoverItems, opts) {
194194
d.offset -= anchor;
195195
});
196196

197-
var scaleX = opts.gd._fullLayout._inverseScaleX;
198-
var scaleY = opts.gd._fullLayout._inverseScaleY;
197+
var scaleX = opts.gd._fullLayout._invScaleX;
198+
var scaleY = opts.gd._fullLayout._invScaleY;
199199
alignHoverText(hoverLabel, fullOpts.rotateLabels, scaleX, scaleY);
200200

201201
return multiHover ? hoverLabel : hoverLabel.node();
@@ -340,7 +340,8 @@ function _hover(gd, evt, subplot, noHoverEvent) {
340340
xpx = evt.clientX - dbb.left;
341341
ypx = evt.clientY - dbb.top;
342342

343-
var transformedCoords = Lib.apply3DTransform(fullLayout._inverseTransform)(xpx, ypx);
343+
fullLayout._calcInverseTransform(gd);
344+
var transformedCoords = Lib.apply3DTransform(fullLayout._invTransform)(xpx, ypx);
344345

345346
xpx = transformedCoords[0];
346347
ypx = transformedCoords[1];
@@ -725,7 +726,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
725726

726727
if(!helpers.isUnifiedHover(hovermode)) {
727728
hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout);
728-
alignHoverText(hoverLabels, rotateLabels, fullLayout._inverseScaleX, fullLayout._inverseScaleY);
729+
alignHoverText(hoverLabels, rotateLabels, fullLayout._invScaleX, fullLayout._invScaleY);
729730
} // TODO: tagName hack is needed to appease geo.js's hack of using evt.target=true
730731
// we should improve the "fx" API so other plots can use it without these hack.
731732
if(evt.target && evt.target.tagName) {

src/lib/dom.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,18 @@ function isTransformableElement(element) {
150150
return element && (element instanceof Element || element instanceof HTMLElement);
151151
}
152152

153+
function equalDomRects(a, b) {
154+
return (
155+
a && b &&
156+
a.x === b.x &&
157+
a.y === b.y &&
158+
a.top === b.top &&
159+
a.left === b.left &&
160+
a.right === b.right &&
161+
a.bottom === b.bottom
162+
);
163+
}
164+
153165
module.exports = {
154166
getGraphDiv: getGraphDiv,
155167
isPlotDiv: isPlotDiv,
@@ -160,4 +172,5 @@ module.exports = {
160172
getFullTransformMatrix: getFullTransformMatrix,
161173
getElementTransformMatrix: getElementTransformMatrix,
162174
getElementAndAncestors: getElementAndAncestors,
175+
equalDomRects: equalDomRects
163176
};

src/lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ lib.deleteRelatedStyleRule = domModule.deleteRelatedStyleRule;
151151
lib.getFullTransformMatrix = domModule.getFullTransformMatrix;
152152
lib.getElementTransformMatrix = domModule.getElementTransformMatrix;
153153
lib.getElementAndAncestors = domModule.getElementAndAncestors;
154+
lib.equalDomRects = domModule.equalDomRects;
154155

155156
lib.clearResponsive = require('./clear_responsive');
156157

src/lib/svg_text_utils.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,9 +748,12 @@ function alignHTMLWith(_base, container, options) {
748748
var x0 = getLeft() - cRect.left;
749749
var y0 = getTop() - cRect.top;
750750
var gd = options.gd || {};
751-
var transformedCoords = Lib.apply3DTransform(gd._fullLayout._inverseTransform)(x0, y0);
752-
x0 = transformedCoords[0];
753-
y0 = transformedCoords[1];
751+
if(options.gd) {
752+
gd._fullLayout._calcInverseTransform(gd);
753+
var transformedCoords = Lib.apply3DTransform(gd._fullLayout._invTransform)(x0, y0);
754+
x0 = transformedCoords[0];
755+
y0 = transformedCoords[1];
756+
}
754757

755758
this.style({
756759
top: y0 + 'px',

src/plot_api/plot_api.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3706,17 +3706,28 @@ function purge(gd) {
37063706
return gd;
37073707
}
37083708

3709+
// determines if the graph div requires a recalculation of its inverse matrix transforms by comparing old + new bounding boxes.
3710+
function calcInverseTransform(gd) {
3711+
var fullLayout = gd._fullLayout;
3712+
3713+
var newBBox = gd.getBoundingClientRect();
3714+
if(Lib.equalDomRects(newBBox, fullLayout._lastBBox)) return;
3715+
3716+
var m = fullLayout._invTransform = Lib.inverseTransformMatrix(Lib.getFullTransformMatrix(gd));
3717+
fullLayout._invScaleX = Math.sqrt(m[0][0] * m[0][0] + m[0][1] * m[0][1] + m[0][2] * m[0][2]);
3718+
fullLayout._invScaleY = Math.sqrt(m[1][0] * m[1][0] + m[1][1] * m[1][1] + m[1][2] * m[1][2]);
3719+
fullLayout._lastBBox = newBBox;
3720+
}
3721+
37093722
// -------------------------------------------------------
37103723
// makePlotFramework: Create the plot container and axes
37113724
// -------------------------------------------------------
37123725
function makePlotFramework(gd) {
37133726
var gd3 = d3.select(gd);
37143727
var fullLayout = gd._fullLayout;
3715-
if(fullLayout._inverseTransform === undefined) {
3716-
var m = fullLayout._inverseTransform = Lib.inverseTransformMatrix(Lib.getFullTransformMatrix(gd));
3717-
fullLayout._inverseScaleX = Math.sqrt(m[0][0] * m[0][0] + m[0][1] * m[0][1] + m[0][2] * m[0][2]);
3718-
fullLayout._inverseScaleY = Math.sqrt(m[1][0] * m[1][0] + m[1][1] * m[1][1] + m[1][2] * m[1][2]);
3719-
}
3728+
3729+
fullLayout._calcInverseTransform = calcInverseTransform;
3730+
fullLayout._calcInverseTransform(gd);
37203731

37213732
// Plot container
37223733
fullLayout._container = gd3.selectAll('.plot-container').data([0]);

src/plots/cartesian/dragbox.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
166166

167167
recomputeAxisLists();
168168

169-
scaleX = gd._fullLayout._inverseScaleX;
170-
scaleY = gd._fullLayout._inverseScaleY;
169+
scaleX = gd._fullLayout._invScaleX;
170+
scaleY = gd._fullLayout._invScaleY;
171171

172172
if(!allFixedRanges) {
173173
if(isMainDrag) {
@@ -335,7 +335,8 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
335335
x0 = startX - dragBBox.left;
336336
y0 = startY - dragBBox.top;
337337

338-
var transformedCoords = Lib.apply3DTransform(gd._fullLayout._inverseTransform)(x0, y0);
338+
gd._fullLayout._calcInverseTransform(gd);
339+
var transformedCoords = Lib.apply3DTransform(gd._fullLayout._invTransform)(x0, y0);
339340
x0 = transformedCoords[0];
340341
y0 = transformedCoords[1];
341342

src/plots/cartesian/select.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,12 @@ function prepSelect(e, startX, startY, dragOptions, mode) {
6868
var x0 = startX - dragBBox.left;
6969
var y0 = startY - dragBBox.top;
7070

71-
var transformedCoords = Lib.apply3DTransform(fullLayout._inverseTransform)(x0, y0);
71+
fullLayout._calcInverseTransform(gd);
72+
var transformedCoords = Lib.apply3DTransform(fullLayout._invTransform)(x0, y0);
7273
x0 = transformedCoords[0];
7374
y0 = transformedCoords[1];
74-
var scaleX = fullLayout._inverseScaleX;
75-
var scaleY = fullLayout._inverseScaleY;
75+
var scaleX = fullLayout._invScaleX;
76+
var scaleY = fullLayout._invScaleY;
7677

7778
var x1 = x0;
7879
var y1 = y0;

src/plots/gl3d/scene.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,10 @@ proto.render = function() {
307307
// update size of svg container
308308
var svgContainer = scene.svgContainer;
309309
var clientRect = scene.container.getBoundingClientRect();
310-
var scaleX = gd._fullLayout._inverseScaleX;
311-
var scaleY = gd._fullLayout._inverseScaleY;
310+
311+
gd._fullLayout._calcInverseTransform(gd);
312+
var scaleX = gd._fullLayout._invScaleX;
313+
var scaleY = gd._fullLayout._invScaleY;
312314
var width = clientRect.width * scaleX;
313315
var height = clientRect.height * scaleY;
314316
svgContainer.setAttributeNS(null, 'viewBox', '0 0 ' + width + ' ' + height);

src/plots/polar/polar.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -680,8 +680,8 @@ proto.updateMainDrag = function(fullLayout) {
680680
var chw = constants.cornerHalfWidth;
681681
var chl = constants.cornerLen / 2;
682682

683-
var scaleX = gd._fullLayout._inverseScaleX;
684-
var scaleY = gd._fullLayout._inverseScaleY;
683+
var scaleX;
684+
var scaleY;
685685

686686
var mainDrag = dragBox.makeDragger(layers, 'path', 'maindrag', 'crosshair');
687687

@@ -943,7 +943,10 @@ proto.updateMainDrag = function(fullLayout) {
943943
var dragModeNow = gd._fullLayout.dragmode;
944944

945945
var bbox = mainDrag.getBoundingClientRect();
946-
var inverse = gd._fullLayout._inverseTransform;
946+
gd._fullLayout._calcInverseTransform(gd);
947+
var inverse = gd._fullLayout._invTransform;
948+
scaleX = gd._fullLayout._invScaleX;
949+
scaleY = gd._fullLayout._invScaleY;
947950
var transformedCoords = Lib.apply3DTransform(inverse)(startX - bbox.left, startY - bbox.top);
948951
x0 = transformedCoords[0];
949952
y0 = transformedCoords[1];
@@ -1198,8 +1201,8 @@ proto.updateAngularDrag = function(fullLayout) {
11981201
var fullLayoutNow = _this.gd._fullLayout;
11991202
var polarLayoutNow = fullLayoutNow[_this.id];
12001203

1201-
var x1 = x0 + dx * fullLayout._inverseScaleX;
1202-
var y1 = y0 + dy * fullLayout._inverseScaleY;
1204+
var x1 = x0 + dx * fullLayout._invScaleX;
1205+
var y1 = y0 + dy * fullLayout._invScaleY;
12031206
var a1 = xy2a(x1, y1);
12041207
var da = rad2deg(a1 - a0);
12051208
rot1 = rot0 + da;
@@ -1293,7 +1296,8 @@ proto.updateAngularDrag = function(fullLayout) {
12931296
x0 = startX - bbox.left;
12941297
y0 = startY - bbox.top;
12951298

1296-
var transformedCoords = Lib.apply3DTransform(fullLayout._inverseTransform)(x0, y0);
1299+
gd._fullLayout._calcInverseTransform(gd);
1300+
var transformedCoords = Lib.apply3DTransform(fullLayout._invTransform)(x0, y0);
12971301
x0 = transformedCoords[0];
12981302
y0 = transformedCoords[1];
12991303

src/plots/ternary/ternary.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,8 @@ proto.initInteractions = function() {
523523
_this.dragOptions.xaxes = [_this.xaxis];
524524
_this.dragOptions.yaxes = [_this.yaxis];
525525

526-
scaleX = gd._fullLayout._inverseScaleX;
527-
scaleY = gd._fullLayout._inverseScaleY;
526+
scaleX = gd._fullLayout._invScaleX;
527+
scaleY = gd._fullLayout._invScaleY;
528528

529529
var dragModeNow = _this.dragOptions.dragmode = gd._fullLayout.dragmode;
530530

@@ -579,9 +579,11 @@ proto.initInteractions = function() {
579579

580580
function zoomPrep(e, startX, startY) {
581581
var dragBBox = dragger.getBoundingClientRect();
582-
var inverse = gd._fullLayout._inverseTransform;
583582
x0 = startX - dragBBox.left;
584583
y0 = startY - dragBBox.top;
584+
585+
gd._fullLayout._calcInverseTransform(gd);
586+
var inverse = gd._fullLayout._invTransform;
585587
var transformedCoords = Lib.apply3DTransform(inverse)(x0, y0);
586588
x0 = transformedCoords[0];
587589
y0 = transformedCoords[1];

0 commit comments

Comments
 (0)