Skip to content

Commit b2eb326

Browse files
committed
Plotly.toImage: format "full-json" now contains config and version key
1 parent 2ca0ae3 commit b2eb326

File tree

3 files changed

+40
-11
lines changed

3 files changed

+40
-11
lines changed

src/plot_api/to_image.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ var Lib = require('../lib');
1717
var helpers = require('../snapshot/helpers');
1818
var toSVG = require('../snapshot/tosvg');
1919
var svgToImg = require('../snapshot/svgtoimg');
20+
var version = require('../core').version;
2021

2122
var attrs = {
2223
format: {
@@ -171,17 +172,24 @@ function toImage(gd, opts) {
171172
var width = clonedGd._fullLayout.width;
172173
var height = clonedGd._fullLayout.height;
173174

175+
function cleanup() {
176+
plotApi.purge(clonedGd);
177+
document.body.removeChild(clonedGd);
178+
}
179+
174180
if(format === 'full-json') {
175-
var json = plots.graphJson(clonedGd, false, 'keepdata', false, true);
181+
var json = plots.graphJson(clonedGd, false, 'keepdata', 'object', true, true);
182+
json.version = version;
183+
json = JSON.stringify(json);
184+
cleanup();
176185
if(imageDataOnly) {
177186
return resolve(json);
178187
} else {
179188
return resolve(helpers.encodeJSON(json));
180189
}
181190
}
182191

183-
plotApi.purge(clonedGd);
184-
document.body.removeChild(clonedGd);
192+
cleanup();
185193

186194
if(format === 'svg') {
187195
if(imageDataOnly) {

src/plots/plots.js

+13-7
Original file line numberDiff line numberDiff line change
@@ -2037,9 +2037,10 @@ plots.didMarginChange = function(margin0, margin1) {
20372037
* keepall: keep data and src
20382038
* @param {String} output If you specify 'object', the result will not be stringified
20392039
* @param {Boolean} useDefaults If truthy, use _fullLayout and _fullData
2040+
* @param {Boolean} includeConfig If truthy, include _context
20402041
* @returns {Object|String}
20412042
*/
2042-
plots.graphJson = function(gd, dataonly, mode, output, useDefaults) {
2043+
plots.graphJson = function(gd, dataonly, mode, output, useDefaults, includeConfig) {
20432044
// if the defaults aren't supplied yet, we need to do that...
20442045
if((useDefaults && dataonly && !gd._fullData) ||
20452046
(useDefaults && !dataonly && !gd._fullLayout)) {
@@ -2050,18 +2051,21 @@ plots.graphJson = function(gd, dataonly, mode, output, useDefaults) {
20502051
var layout = (useDefaults) ? gd._fullLayout : gd.layout;
20512052
var frames = (gd._transitionData || {})._frames;
20522053

2053-
function stripObj(d) {
2054+
function stripObj(d, keepFunction) {
20542055
if(typeof d === 'function') {
2055-
return null;
2056+
return keepFunction ? '_function_' : null;
20562057
}
20572058
if(Lib.isPlainObject(d)) {
20582059
var o = {};
20592060
var v, src;
20602061
for(v in d) {
20612062
// remove private elements and functions
20622063
// _ is for private, [ is a mistake ie [object Object]
2063-
if(typeof d[v] === 'function' ||
2064-
['_', '['].indexOf(v.charAt(0)) !== -1) {
2064+
if(['_', '['].indexOf(v.charAt(0)) !== -1) continue;
2065+
2066+
// if a function, add if necessary then move on
2067+
if(typeof d[v] === 'function') {
2068+
if(keepFunction) o[v] = '_function';
20652069
continue;
20662070
}
20672071

@@ -2091,13 +2095,13 @@ plots.graphJson = function(gd, dataonly, mode, output, useDefaults) {
20912095
}
20922096

20932097
// OK, we're including this... recurse into it
2094-
o[v] = stripObj(d[v]);
2098+
o[v] = stripObj(d[v], keepFunction);
20952099
}
20962100
return o;
20972101
}
20982102

20992103
if(Array.isArray(d)) {
2100-
return d.map(stripObj);
2104+
return d.map(function(x) {return stripObj(x, keepFunction);});
21012105
}
21022106

21032107
if(Lib.isTypedArray(d)) {
@@ -2126,6 +2130,8 @@ plots.graphJson = function(gd, dataonly, mode, output, useDefaults) {
21262130

21272131
if(frames) obj.frames = stripObj(frames);
21282132

2133+
if(includeConfig) obj.config = stripObj(gd._context, true);
2134+
21292135
return (output === 'object') ? obj : JSON.stringify(obj);
21302136
};
21312137

test/jasmine/tests/toimage_test.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,23 @@ describe('Plotly.toImage', function() {
266266

267267
describe('with format `full-json`', function() {
268268
var imgOpts = {format: 'full-json', imageDataOnly: true};
269+
var gd;
270+
271+
beforeEach(function() {
272+
gd = createGraphDiv();
273+
});
274+
afterEach(destroyGraphDiv);
275+
269276
it('export a graph div', function(done) {
270277
Plotly.plot(gd, [{y: [1, 2, 3]}])
271-
.then(function() { return Plotly.toImage('graph', imgOpts);})
278+
.then(function(gd) { return Plotly.toImage(gd, imgOpts);})
272279
.then(function(fig) {
273280
fig = JSON.parse(fig);
281+
['data', 'layout', 'config'].forEach(function(key) {
282+
expect(fig.hasOwnProperty(key)).toBeTruthy('is missing key: ' + key);
283+
});
274284
expect(fig.data[0].mode).toBe('lines+markers', 'contain default mode');
285+
expect(fig.version).toBe(Plotly.version, 'contains Plotly version');
275286
})
276287
.catch(failTest)
277288
.then(done);
@@ -281,7 +292,11 @@ describe('Plotly.toImage', function() {
281292
Plotly.toImage({data: [{y: [1, 2, 3]}]}, imgOpts)
282293
.then(function(fig) {
283294
fig = JSON.parse(fig);
295+
['data', 'layout', 'config'].forEach(function(key) {
296+
expect(fig.hasOwnProperty(key)).toBeTruthy('is missing key: ' + key);
297+
});
284298
expect(fig.data[0].mode).toBe('lines+markers', 'contain default mode');
299+
expect(fig.version).toBe(Plotly.version, 'contains Plotly version');
285300
})
286301
.catch(failTest)
287302
.then(done);

0 commit comments

Comments
 (0)