Skip to content

Commit ead4bc5

Browse files
authored
Merge pull request #737 from plotly/config-queue-length
Set undo/redo queue length via setPlotConfig
2 parents 12bed39 + 5d30962 commit ead4bc5

File tree

5 files changed

+101
-28
lines changed

5 files changed

+101
-28
lines changed

src/lib/queue.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99

1010
'use strict';
1111

12-
var Plotly = require('../plotly');
12+
var Lib = require('../lib');
13+
var config = require('../plot_api/plot_config');
14+
1315

1416
/**
1517
* Copy arg array *without* removing `undefined` values from objects.
@@ -28,8 +30,8 @@ function copyArgArray(gd, args) {
2830
if(arg === gd) copy[i] = arg;
2931
else if(typeof arg === 'object') {
3032
copy[i] = Array.isArray(arg) ?
31-
Plotly.Lib.extendDeep([], arg) :
32-
Plotly.Lib.extendDeepAll({}, arg);
33+
Lib.extendDeep([], arg) :
34+
Lib.extendDeepAll({}, arg);
3335
}
3436
else copy[i] = arg;
3537
}
@@ -82,11 +84,17 @@ queue.add = function(gd, undoFunc, undoArgs, redoFunc, redoArgs) {
8284
gd.undoQueue.beginSequence = false;
8385

8486
// we unshift to handle calls for undo in a forward for loop later
85-
queueObj.undo.calls.unshift(undoFunc);
86-
queueObj.undo.args.unshift(undoArgs);
87-
queueObj.redo.calls.push(redoFunc);
88-
queueObj.redo.args.push(redoArgs);
87+
if(queueObj) {
88+
queueObj.undo.calls.unshift(undoFunc);
89+
queueObj.undo.args.unshift(undoArgs);
90+
queueObj.redo.calls.push(redoFunc);
91+
queueObj.redo.args.push(redoArgs);
92+
}
8993

94+
if(gd.undoQueue.queue.length > config.queueLength) {
95+
gd.undoQueue.queue.shift();
96+
gd.undoQueue.index--;
97+
}
9098
};
9199

92100
/**

src/plot_api/plot_api.js

+10-20
Original file line numberDiff line numberDiff line change
@@ -1263,9 +1263,7 @@ Plotly.extendTraces = function extendTraces(gd, update, indices, maxPoints) {
12631263
var promise = Plotly.redraw(gd);
12641264

12651265
var undoArgs = [gd, undo.update, indices, undo.maxPoints];
1266-
if(Queue) {
1267-
Queue.add(gd, Plotly.prependTraces, undoArgs, extendTraces, arguments);
1268-
}
1266+
Queue.add(gd, Plotly.prependTraces, undoArgs, extendTraces, arguments);
12691267

12701268
return promise;
12711269
};
@@ -1292,9 +1290,7 @@ Plotly.prependTraces = function prependTraces(gd, update, indices, maxPoints) {
12921290
var promise = Plotly.redraw(gd);
12931291

12941292
var undoArgs = [gd, undo.update, indices, undo.maxPoints];
1295-
if(Queue) {
1296-
Queue.add(gd, Plotly.extendTraces, undoArgs, prependTraces, arguments);
1297-
}
1293+
Queue.add(gd, Plotly.extendTraces, undoArgs, prependTraces, arguments);
12981294

12991295
return promise;
13001296
};
@@ -1342,7 +1338,7 @@ Plotly.addTraces = function addTraces(gd, traces, newIndices) {
13421338
// i.e., we can simply redraw and be done
13431339
if(typeof newIndices === 'undefined') {
13441340
promise = Plotly.redraw(gd);
1345-
if(Queue) Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs);
1341+
Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs);
13461342
return promise;
13471343
}
13481344

@@ -1365,10 +1361,10 @@ Plotly.addTraces = function addTraces(gd, traces, newIndices) {
13651361

13661362
// if we're here, the user has defined specific places to place the new traces
13671363
// this requires some extra work that moveTraces will do
1368-
if(Queue) Queue.startSequence(gd);
1369-
if(Queue) Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs);
1364+
Queue.startSequence(gd);
1365+
Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs);
13701366
promise = Plotly.moveTraces(gd, currentIndices, newIndices);
1371-
if(Queue) Queue.stopSequence(gd);
1367+
Queue.stopSequence(gd);
13721368
return promise;
13731369
};
13741370

@@ -1409,8 +1405,7 @@ Plotly.deleteTraces = function deleteTraces(gd, indices) {
14091405
}
14101406

14111407
var promise = Plotly.redraw(gd);
1412-
1413-
if(Queue) Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs);
1408+
Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs);
14141409

14151410
return promise;
14161411
};
@@ -1508,8 +1503,7 @@ Plotly.moveTraces = function moveTraces(gd, currentIndices, newIndices) {
15081503
gd.data = newData;
15091504

15101505
var promise = Plotly.redraw(gd);
1511-
1512-
if(Queue) Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs);
1506+
Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs);
15131507

15141508
return promise;
15151509
};
@@ -1955,9 +1949,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
19551949

19561950
// now all attribute mods are done, as are redo and undo
19571951
// so we can save them
1958-
if(Queue) {
1959-
Queue.add(gd, restyle, [gd, undoit, traces], restyle, [gd, redoit, traces]);
1960-
}
1952+
Queue.add(gd, restyle, [gd, undoit, traces], restyle, [gd, redoit, traces]);
19611953

19621954
// do we need to force a recalc?
19631955
var autorangeOn = false;
@@ -2375,9 +2367,7 @@ Plotly.relayout = function relayout(gd, astr, val) {
23752367
}
23762368
// now all attribute mods are done, as are
23772369
// redo and undo so we can save them
2378-
if(Queue) {
2379-
Queue.add(gd, relayout, [gd, undoit], relayout, [gd, redoit]);
2380-
}
2370+
Queue.add(gd, relayout, [gd, undoit], relayout, [gd, redoit]);
23812371

23822372
// calculate autosizing - if size hasn't changed,
23832373
// will remove h&w so we don't need to redraw

src/plot_api/plot_config.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
var Lib = require('../lib');
1212

1313
/**
14-
* This will be transfered over to gd and overridden by
14+
* This will be transferred over to gd and overridden by
1515
* config args to Plotly.plot.
1616
*
1717
* The defaults are the appropriate settings for plotly.js,
@@ -26,6 +26,9 @@ module.exports = {
2626
// we can edit titles, move annotations, etc
2727
editable: false,
2828

29+
// set the length of the undo/redo queue
30+
queueLength: 0,
31+
2932
// plot will respect layout.autosize=true and infer its container size
3033
autosizable: false,
3134

test/jasmine/tests/lib_test.js

+71
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var Lib = require('@src/lib');
22
var setCursor = require('@src/lib/setcursor');
33

44
var d3 = require('d3');
5+
var Plotly = require('@lib');
56
var PlotlyInternal = require('@src/plotly');
67
var createGraphDiv = require('../assets/create_graph_div');
78
var destroyGraphDiv = require('../assets/destroy_graph_div');
@@ -1042,3 +1043,73 @@ describe('Test lib.js:', function() {
10421043
});
10431044
});
10441045
});
1046+
1047+
describe('Queue', function() {
1048+
'use strict';
1049+
1050+
var gd;
1051+
1052+
beforeEach(function() {
1053+
gd = createGraphDiv();
1054+
});
1055+
1056+
afterEach(function() {
1057+
destroyGraphDiv();
1058+
Plotly.setPlotConfig({ queueLength: 0 });
1059+
});
1060+
1061+
it('should not fill in undoQueue by default', function(done) {
1062+
Plotly.plot(gd, [{
1063+
y: [2, 1, 2]
1064+
}]).then(function() {
1065+
expect(gd.undoQueue).toBeUndefined();
1066+
1067+
return Plotly.restyle(gd, 'marker.color', 'red');
1068+
}).then(function() {
1069+
expect(gd.undoQueue.index).toEqual(0);
1070+
expect(gd.undoQueue.queue).toEqual([]);
1071+
1072+
return Plotly.relayout(gd, 'title', 'A title');
1073+
}).then(function() {
1074+
expect(gd.undoQueue.index).toEqual(0);
1075+
expect(gd.undoQueue.queue).toEqual([]);
1076+
1077+
done();
1078+
});
1079+
});
1080+
1081+
it('should fill in undoQueue up to value found in *queueLength* config', function(done) {
1082+
Plotly.setPlotConfig({ queueLength: 2 });
1083+
1084+
Plotly.plot(gd, [{
1085+
y: [2, 1, 2]
1086+
}]).then(function() {
1087+
expect(gd.undoQueue).toBeUndefined();
1088+
1089+
return Plotly.restyle(gd, 'marker.color', 'red');
1090+
}).then(function() {
1091+
expect(gd.undoQueue.index).toEqual(1);
1092+
expect(gd.undoQueue.queue[0].undo.args[0][1]['marker.color']).toEqual([undefined]);
1093+
expect(gd.undoQueue.queue[0].redo.args[0][1]['marker.color']).toEqual('red');
1094+
1095+
return Plotly.relayout(gd, 'title', 'A title');
1096+
}).then(function() {
1097+
expect(gd.undoQueue.index).toEqual(2);
1098+
expect(gd.undoQueue.queue[1].undo.args[0][1].title).toEqual(undefined);
1099+
expect(gd.undoQueue.queue[1].redo.args[0][1].title).toEqual('A title');
1100+
1101+
return Plotly.restyle(gd, 'mode', 'markers');
1102+
}).then(function() {
1103+
expect(gd.undoQueue.index).toEqual(2);
1104+
expect(gd.undoQueue.queue[2]).toBeUndefined();
1105+
1106+
expect(gd.undoQueue.queue[1].undo.args[0][1].mode).toEqual([undefined]);
1107+
expect(gd.undoQueue.queue[1].redo.args[0][1].mode).toEqual('markers');
1108+
1109+
expect(gd.undoQueue.queue[0].undo.args[0][1].title).toEqual(undefined);
1110+
expect(gd.undoQueue.queue[0].redo.args[0][1].title).toEqual('A title');
1111+
1112+
done();
1113+
});
1114+
});
1115+
});

test/jasmine/tests/plot_api_test.js

+1
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ describe('Test plot api', function() {
420420

421421
describe('Plotly.ExtendTraces', function() {
422422
var gd;
423+
423424
beforeEach(function() {
424425
gd = {
425426
data: [

0 commit comments

Comments
 (0)