Skip to content

Commit 0625c65

Browse files
authored
Merge pull request #7233 from plotly/release-v2.35.3
Merge `release-v2.35.3` dev branch to master to include recent fixes
2 parents c15fd07 + de644bb commit 0625c65

File tree

15 files changed

+164
-16
lines changed

15 files changed

+164
-16
lines changed

draftlogs/7164_fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Allow null or broken selection objects without throwing an error [[#7164](https://github.com/plotly/plotly.js/pull/7164)]

draftlogs/7167_fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Render scatterternary traces correctly if they have the `ids` attribute [[#7164](https://github.com/plotly/plotly.js/pull/7164)]

draftlogs/7199_fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Do not convert url-sourced layout images to data uri unless we're in staticPlot mode, to improve interactivity when images are changed with zoom/pan [[#7199](https://github.com/plotly/plotly.js/pull/7199)]

draftlogs/7204_fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fix mablibre source map [[#7204](https://github.com/plotly/plotly.js/pull/7204)]

draftlogs/7205_fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fix years in license [[#7205](https://github.com/plotly/plotly.js/pull/7205)]

src/components/images/draw.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ module.exports = function draw(gd) {
7373

7474
thisImage.attr('xmlns', xmlnsNamespaces.svg);
7575

76-
if(d.source && d.source.slice(0, 5) === 'data:') {
76+
if(!gd._context.staticPlot || (d.source && d.source.slice(0, 5) === 'data:')) {
7777
thisImage.attr('xlink:href', d.source);
7878
this._imgSrc = d.source;
7979
} else {

src/components/selections/select.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ function prepSelect(evt, startX, startY, dragOptions, mode) {
182182
for(var q = 0; q < selections.length; q++) {
183183
var s = fullLayout.selections[q];
184184
if(
185+
!s ||
185186
s.xref !== xRef ||
186187
s.yref !== yRef
187188
) {

src/plots/cartesian/index.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,10 @@ function makeSubplotLayer(gd, plotinfo) {
568568
var yLayer = constants.layerValue2layerClass[plotinfo.yaxis.layer];
569569
var hasOnlyLargeSploms = fullLayout._hasOnlyLargeSploms;
570570

571-
if(!plotinfo.mainplot || fullLayout._zindices.length > 1) {
571+
var hasMultipleZ = fullLayout._zindices.length > 1;
572+
var mainplotinfo = plotinfo.mainplotinfo;
573+
574+
if(!plotinfo.mainplot || hasMultipleZ) {
572575
if(hasOnlyLargeSploms) {
573576
// TODO could do even better
574577
// - we don't need plot (but we would have to mock it in lsInner
@@ -585,9 +588,15 @@ function makeSubplotLayer(gd, plotinfo) {
585588
plotinfo.shapelayer = ensureSingle(backLayer, 'g', 'shapelayer');
586589
plotinfo.imagelayer = ensureSingle(backLayer, 'g', 'imagelayer');
587590

588-
plotinfo.minorGridlayer = ensureSingle(plotgroup, 'g', 'minor-gridlayer');
589-
plotinfo.gridlayer = ensureSingle(plotgroup, 'g', 'gridlayer');
590-
plotinfo.zerolinelayer = ensureSingle(plotgroup, 'g', 'zerolinelayer');
591+
if(mainplotinfo && hasMultipleZ) {
592+
plotinfo.minorGridlayer = mainplotinfo.minorGridlayer;
593+
plotinfo.gridlayer = mainplotinfo.gridlayer;
594+
plotinfo.zerolinelayer = mainplotinfo.zerolinelayer;
595+
} else {
596+
plotinfo.minorGridlayer = ensureSingle(plotgroup, 'g', 'minor-gridlayer');
597+
plotinfo.gridlayer = ensureSingle(plotgroup, 'g', 'gridlayer');
598+
plotinfo.zerolinelayer = ensureSingle(plotgroup, 'g', 'zerolinelayer');
599+
}
591600

592601
var betweenLayer = ensureSingle(plotgroup, 'g', 'layer-between');
593602
plotinfo.shapelayerBetween = ensureSingle(betweenLayer, 'g', 'shapelayer');
@@ -622,7 +631,6 @@ function makeSubplotLayer(gd, plotinfo) {
622631
}
623632
}
624633
} else {
625-
var mainplotinfo = plotinfo.mainplotinfo;
626634
var mainplotgroup = mainplotinfo.plotgroup;
627635
var xId = id + '-x';
628636
var yId = id + '-y';

src/plots/map/map.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
var maplibregl = require('maplibre-gl/dist/maplibre-gl-unminified');
3+
var maplibregl = require('maplibre-gl');
44

55
var Lib = require('../../lib');
66
var geoUtils = require('../../lib/geo_location_utils');

src/traces/scatterternary/calc.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = function calc(gd, trace) {
1515
var displaySum = ternary.sum;
1616
var normSum = trace.sum || displaySum;
1717
var arrays = {a: trace.a, b: trace.b, c: trace.c};
18+
var ids = trace.ids;
1819

1920
var i, j, dataArray, newArray, fillArray1, fillArray2;
2021

@@ -58,6 +59,9 @@ module.exports = function calc(gd, trace) {
5859
y = a;
5960
x = c - b;
6061
cd[i] = {x: x, y: y, a: a, b: b, c: c};
62+
if (ids) {
63+
cd[i].id = ids[i];
64+
}
6165
} else cd[i] = {x: false, y: false};
6266
}
6367

Loading

test/image/mocks/ternary_simple.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"a": [2, 1, 1],
55
"b": [1, 2, 1],
66
"c": [1, 1, 2.12345],
7+
"ids": ["first ID", "second ID", "third ID"],
78
"type": "scatterternary"
89
}
910
],

test/jasmine/tests/layout_images_test.js

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,8 @@ describe('Layout images', function() {
319319
var gd;
320320
var data = [{ x: [1, 2, 3], y: [1, 2, 3] }];
321321

322-
beforeEach(function(done) {
323-
gd = createGraphDiv();
324-
Plotly.newPlot(gd, data, {
322+
var layoutFn = function() {
323+
return {
325324
images: [{
326325
source: jsLogo,
327326
x: 2,
@@ -331,12 +330,17 @@ describe('Layout images', function() {
331330
}],
332331
width: 500,
333332
height: 400
334-
}).then(done);
333+
};
334+
}
335+
336+
beforeEach(function(done) {
337+
gd = createGraphDiv();
338+
Plotly.newPlot(gd, data, layoutFn()).then(done);
335339
});
336340

337341
afterEach(destroyGraphDiv);
338342

339-
it('should only create canvas if url image', function(done) {
343+
it('should only create canvas if url image and staticPlot', function(done) {
340344
var originalCreateElement = document.createElement;
341345
var newCanvasElement;
342346
spyOn(document, 'createElement').and.callFake(function(elementType) {
@@ -350,7 +354,21 @@ describe('Layout images', function() {
350354

351355
Plotly.relayout(gd, 'images[0].source', dataUriImage)
352356
.then(function() {
353-
expect(newCanvasElement).toBeUndefined();
357+
expect(newCanvasElement).withContext('non-static data uri').toBeUndefined();
358+
359+
return Plotly.relayout(gd, 'images[0].source', jsLogo);
360+
})
361+
.then(function() {
362+
expect(newCanvasElement).withContext('non-static url').toBeUndefined();
363+
364+
return Plotly.newPlot(gd, data, layoutFn(), {staticPlot: true});
365+
})
366+
.then(function() {
367+
newCanvasElement = undefined;
368+
return Plotly.relayout(gd, 'images[0].source', dataUriImage);
369+
})
370+
.then(function() {
371+
expect(newCanvasElement).withContext('static data uri').toBeUndefined();
354372

355373
return Plotly.relayout(gd, 'images[0].source', jsLogo);
356374
})
@@ -392,11 +410,21 @@ describe('Layout images', function() {
392410
.then(done, done.fail);
393411
});
394412

395-
it('should remove the image tag if an invalid source', function(done) {
413+
it('should remove the image tag if an invalid source and staticPlot', function(done) {
396414
var selection = d3Select('image');
397415
expect(selection.size()).toBe(1);
398416

399417
Plotly.relayout(gd, 'images[0].source', 'invalidUrl')
418+
.then(function() {
419+
var newSelection = d3Select('image');
420+
expect(newSelection.size()).toBe(1);
421+
})
422+
.then(function() {
423+
return Plotly.newPlot(gd, data, layoutFn(), {staticPlot: true});
424+
})
425+
.then(function() {
426+
return Plotly.relayout(gd, 'images[0].source', 'invalidUrl');
427+
})
400428
.then(function() {
401429
var newSelection = d3Select('image');
402430
expect(newSelection.size()).toBe(0);

test/jasmine/tests/select_test.js

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ function assertSelectionNodes(cornerCnt, outlineCnt, _msg) {
7575
}
7676

7777
var selectingCnt, selectingData, selectedCnt, selectedData, deselectCnt, doubleClickData;
78-
var selectedPromise, deselectPromise, clickedPromise;
78+
var selectedPromise, deselectPromise, clickedPromise, relayoutPromise;
7979

8080
function resetEvents(gd) {
8181
selectingCnt = 0;
@@ -125,6 +125,12 @@ function resetEvents(gd) {
125125
resolve();
126126
});
127127
});
128+
129+
relayoutPromise = new Promise(function(resolve) {
130+
gd.on('plotly_relayout', function() {
131+
resolve();
132+
});
133+
});
128134
}
129135

130136
function assertEventCounts(selecting, selected, deselect, msg) {
@@ -1035,6 +1041,100 @@ describe('Test select box and lasso in general:', function() {
10351041
});
10361042
});
10371043

1044+
describe('select / deselect with fake selections', function() {
1045+
var gd;
1046+
beforeEach(function(done) {
1047+
gd = createGraphDiv();
1048+
1049+
var mockCopy = Lib.extendDeep({}, mock);
1050+
mockCopy.layout.dragmode = 'select';
1051+
mockCopy.layout.hovermode = 'closest';
1052+
mockCopy.layout.selections = [null];
1053+
addInvisible(mockCopy);
1054+
1055+
_newPlot(gd, mockCopy.data, mockCopy.layout)
1056+
.then(done);
1057+
});
1058+
1059+
it('should trigger selecting/selected/deselect events', function(done) {
1060+
resetEvents(gd);
1061+
1062+
drag(selectPath);
1063+
1064+
selectedPromise.then(function() {
1065+
expect(selectedCnt).toBe(1, 'with the correct selected count');
1066+
assertEventData(selectedData.points, [{
1067+
curveNumber: 0,
1068+
pointNumber: 0,
1069+
pointIndex: 0,
1070+
x: 0.002,
1071+
y: 16.25
1072+
}, {
1073+
curveNumber: 0,
1074+
pointNumber: 1,
1075+
pointIndex: 1,
1076+
x: 0.004,
1077+
y: 12.5
1078+
}], 'with the correct selected points (2)');
1079+
assertRange(selectedData.range, {
1080+
x: [0.002000, 0.0046236],
1081+
y: [0.10209191961595454, 24.512223978291406]
1082+
}, 'with the correct selected range');
1083+
1084+
return doubleClick(250, 200);
1085+
})
1086+
.then(deselectPromise)
1087+
.then(function() {
1088+
expect(doubleClickData).toBe(null, 'with the correct deselect data');
1089+
})
1090+
.then(done, done.fail);
1091+
});
1092+
1093+
it('should handle add/sub selection', function(done) {
1094+
resetEvents(gd);
1095+
expect(gd.layout.selections.length).toBe(1);
1096+
1097+
drag([[193, 193], [213, 193]], {shiftKey: true})
1098+
1099+
selectedPromise.then(function() {
1100+
expect(selectedCnt).toBe(1, 'with the correct selected count');
1101+
assertEventData(selectedData.points, [{
1102+
curveNumber: 0,
1103+
pointNumber: 4,
1104+
pointIndex: 4,
1105+
x: 0.013,
1106+
y: 6.875
1107+
}], 'with the correct selected points (1)');
1108+
})
1109+
.then(function() {
1110+
// this is not working here, but it works in the test dashboard, not sure why
1111+
// but at least this test shows us that no errors are thrown.
1112+
// expect(gd.layout.selections.length).toBe(2, 'fake selection is still there');
1113+
1114+
resetEvents(gd);
1115+
1116+
return doubleClick(250, 200);
1117+
})
1118+
.then(relayoutPromise)
1119+
.then(function() {
1120+
expect(gd.layout.selections.length).toBe(0, 'fake selection is cleared');
1121+
expect(doubleClickData).toBe(null, 'with the correct deselect data');
1122+
})
1123+
.then(done, done.fail);
1124+
});
1125+
1126+
it('should clear fake selections on doubleclick', function(done) {
1127+
resetEvents(gd);
1128+
1129+
doubleClick(250, 200);
1130+
1131+
relayoutPromise.then(function() {
1132+
expect(gd.layout.selections.length).toBe(0, 'fake selections are cleared');
1133+
})
1134+
.then(done, done.fail);
1135+
});
1136+
});
1137+
10381138
describe('lasso events', function() {
10391139
var mockCopy = Lib.extendDeep({}, mock);
10401140
mockCopy.layout.dragmode = 'lasso';
@@ -1979,6 +2079,7 @@ describe('Test select box and lasso per trace:', function() {
19792079
function() {
19802080
assertPoints([[0.5, 0.25, 0.25]]);
19812081
assertSelectedPoints({0: [0]});
2082+
expect(selectedData.points[0].id).toBe("first ID")
19822083
},
19832084
[380, 180],
19842085
BOXEVENTS, 'scatterternary select'

test/jasmine/tests/ternary_test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ var assertHoverLabelContent = customAssertions.assertHoverLabelContent;
2121

2222
var SORTED_EVENT_KEYS = [
2323
'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
24-
'xaxis', 'yaxis', 'a', 'b', 'c',
24+
'xaxis', 'yaxis', 'a', 'b', 'c', 'id',
2525
'bbox'
2626
].sort();
2727

0 commit comments

Comments
 (0)