Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions draftlogs/7990_add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add an opt-in modebar button for downloading Plotly figures as JSON [[#7990](https://github.com/plotly/plotly.js/pull/7990)]
13 changes: 13 additions & 0 deletions src/components/modebar/buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ modeBarButtons.toImage = {
}
};

modeBarButtons.downloadJson = {
name: 'downloadJson',
title: function (gd) {
return _(gd, 'Download plot as JSON');
},
icon: Icons.disk,
click: function (gd) {
Registry.call('downloadImage', gd, {format: 'full-json'}).catch(function () {
Lib.notifier(_(gd, 'Sorry, there was a problem downloading your JSON file!'), 'long', gd);
});
}
};

modeBarButtons.sendChartToCloud = {
name: 'sendChartToCloud',
title: function (gd) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/modebar/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var backButtons = [
'hovercompare',
'togglehover',
'togglespikelines'
].concat(DRAW_MODES);
].concat(DRAW_MODES, ['downloadJson']);

var foreButtons = [];
var addToForeButtons = function(b) {
Expand Down
2 changes: 2 additions & 0 deletions src/components/modebar/manage.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ function getButtonGroups(gd) {
enableHover('hoverClosestGeo');
enableHover('hoverClosest3d');
enableHover('hoverClosestPie');
} else if(b === 'downloadjson') {
newList.push(modeBarButtons.downloadJson);
}
} else newList.push(b);
}
Expand Down
3 changes: 2 additions & 1 deletion src/plot_api/plot_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,8 @@ var configAttributes = {
'To enable predefined modebar buttons e.g. shape drawing, hover and spikelines,',
'simply provide their string name(s). This could include:',
'*v1hovermode*, *hoverclosest*, *hovercompare*, *togglehover*, *togglespikelines*,',
'*drawline*, *drawopenpath*, *drawclosedpath*, *drawcircle*, *drawrect* and *eraseshape*.',
'*drawline*, *drawopenpath*, *drawclosedpath*, *drawcircle*, *drawrect*, *eraseshape*',
'and *downloadJson*.',
'Please note that these predefined buttons will only be shown if they are compatible',
'with all trace types used in a graph.'
].join(' ')
Expand Down
9 changes: 5 additions & 4 deletions src/types/core/layout.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ export type AxisName = XAxisName | YAxisName;
* - `config.modeBarButtons` — the button's registry key, resolved against
* Plotly's button table; an unknown key throws.
* - `config.modeBarButtonsToAdd` — as a *string*, only the shape-drawing
* buttons (`drawline` … `eraseshape`) and the category aliases at the end of
* this union. Any other button has to be added as a `ModeBarButton` object;
* passing its name as a string does not resolve to the built-in button.
* buttons (`drawline` … `eraseshape`), `downloadJson`, and the category
* aliases at the end of this union. Any other button has to be added as a
* `ModeBarButton` object; passing its name as a string does not resolve to
* the built-in button.
*/
export type ModeBarDefaultButtons =
// Cartesian
Expand Down Expand Up @@ -92,6 +93,7 @@ export type ModeBarDefaultButtons =
| 'drawcircle'
| 'drawrect'
| 'eraseshape'
| 'downloadJson'
// Other
| 'toImage'
| 'sendChartToCloud'
Expand Down Expand Up @@ -169,4 +171,3 @@ export interface Template {
/** Template layout defaults. */
layout?: Partial<Layout> | undefined;
}

4 changes: 2 additions & 2 deletions src/types/generated/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16166,7 +16166,7 @@ export interface Layout {
modebar?: {
/** Sets the color of the active or hovered on icons in the modebar. */
activecolor?: Color;
/** Determines which predefined modebar buttons to add. Please note that these buttons will only be shown if they are compatible with all trace types used in a graph. Similar to `config.modeBarButtonsToAdd` option. This may include *v1hovermode*, *hoverclosest*, *hovercompare*, *togglehover*, *togglespikelines*, *drawline*, *drawopenpath*, *drawclosedpath*, *drawcircle*, *drawrect*, *eraseshape*. */
/** Determines which predefined modebar buttons to add. Please note that these buttons will only be shown if they are compatible with all trace types used in a graph. Similar to `config.modeBarButtonsToAdd` option. This may include *v1hovermode*, *hoverclosest*, *hovercompare*, *togglehover*, *togglespikelines*, *drawline*, *drawopenpath*, *drawclosedpath*, *drawcircle*, *drawrect*, *eraseshape*, *downloadJson*. */
add?: string | string[];
/** Sets the background color of the modebar. */
bgcolor?: Color;
Expand Down Expand Up @@ -16621,7 +16621,7 @@ export interface ConfigBase {
*/
modeBarButtons?: any;
/**
* Add mode bar button using config objects See ./components/modebar/buttons.js for list of arguments. To enable predefined modebar buttons e.g. shape drawing, hover and spikelines, simply provide their string name(s). This could include: *v1hovermode*, *hoverclosest*, *hovercompare*, *togglehover*, *togglespikelines*, *drawline*, *drawopenpath*, *drawclosedpath*, *drawcircle*, *drawrect* and *eraseshape*. Please note that these predefined buttons will only be shown if they are compatible with all trace types used in a graph.
* Add mode bar button using config objects See ./components/modebar/buttons.js for list of arguments. To enable predefined modebar buttons e.g. shape drawing, hover and spikelines, simply provide their string name(s). This could include: *v1hovermode*, *hoverclosest*, *hovercompare*, *togglehover*, *togglespikelines*, *drawline*, *drawopenpath*, *drawclosedpath*, *drawcircle*, *drawrect*, *eraseshape* and *downloadJson*. Please note that these predefined buttons will only be shown if they are compatible with all trace types used in a graph.
* @default []
*/
modeBarButtonsToAdd?: any;
Expand Down
55 changes: 55 additions & 0 deletions test/jasmine/tests/modebar_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var createModeBar = require('../../../src/components/modebar/modebar');
var manageModeBar = require('../../../src/components/modebar/manage');

var Plotly = require('../../../lib/index');
var Lib = require('../../../src/lib');
var Plots = require('../../../src/plots/plots');
var Registry = require('../../../src/registry');
var createGraphDiv = require('../assets/create_graph_div');
Expand Down Expand Up @@ -1054,6 +1055,60 @@ describe('ModeBar', function() {
});
});

describe('downloadJson handler', function() {
beforeEach(function() {
spyOn(Registry, 'call').and.returnValue(Promise.resolve());
gd = createGraphDiv();
});

it('requests a full JSON download when added through config', function(done) {
Plotly.newPlot(gd, {data: [], layout: {}, config: {
modeBarButtonsToAdd: ['downloadJson']
}})
.then(function() {
selectButton(gd._fullLayout._modeBar, 'downloadJson').click();
expect(Registry.call)
.toHaveBeenCalledWith('downloadImage', gd, {format: 'full-json'});
})
.then(done, done.fail);
});

it('requests a full JSON download when added through layout', function(done) {
Plotly.newPlot(gd, {data: [], layout: {
modebar: {add: ['downloadJson']}
}})
.then(function() {
selectButton(gd._fullLayout._modeBar, 'downloadJson').click();
expect(Registry.call)
.toHaveBeenCalledWith('downloadImage', gd, {format: 'full-json'});
})
.then(done, done.fail);
});

it('reports download failures', function(done) {
spyOn(Lib, 'notifier');
Registry.call.and.callFake(function() {
return Promise.reject();
});

Plotly.newPlot(gd, {data: [], layout: {}, config: {
modeBarButtonsToAdd: ['downloadJson']
}})
.then(function() {
selectButton(gd._fullLayout._modeBar, 'downloadJson').click();
return Promise.resolve();
})
.then(function() {
expect(Lib.notifier).toHaveBeenCalledWith(
'Sorry, there was a problem downloading your JSON file!',
'long',
gd
);
})
.then(done, done.fail);
});
});

describe('cartesian handlers', function() {
beforeEach(function(done) {
var mockData = [{
Expand Down
4 changes: 2 additions & 2 deletions test/plot-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@
"valType": "any"
},
"modeBarButtonsToAdd": {
"description": "Add mode bar button using config objects See ./components/modebar/buttons.js for list of arguments. To enable predefined modebar buttons e.g. shape drawing, hover and spikelines, simply provide their string name(s). This could include: *v1hovermode*, *hoverclosest*, *hovercompare*, *togglehover*, *togglespikelines*, *drawline*, *drawopenpath*, *drawclosedpath*, *drawcircle*, *drawrect* and *eraseshape*. Please note that these predefined buttons will only be shown if they are compatible with all trace types used in a graph.",
"description": "Add mode bar button using config objects See ./components/modebar/buttons.js for list of arguments. To enable predefined modebar buttons e.g. shape drawing, hover and spikelines, simply provide their string name(s). This could include: *v1hovermode*, *hoverclosest*, *hovercompare*, *togglehover*, *togglespikelines*, *drawline*, *drawopenpath*, *drawclosedpath*, *drawcircle*, *drawrect*, *eraseshape* and *downloadJson*. Please note that these predefined buttons will only be shown if they are compatible with all trace types used in a graph.",
"dflt": [],
"valType": "any"
},
Expand Down Expand Up @@ -4167,7 +4167,7 @@
},
"add": {
"arrayOk": true,
"description": "Determines which predefined modebar buttons to add. Please note that these buttons will only be shown if they are compatible with all trace types used in a graph. Similar to `config.modeBarButtonsToAdd` option. This may include *v1hovermode*, *hoverclosest*, *hovercompare*, *togglehover*, *togglespikelines*, *drawline*, *drawopenpath*, *drawclosedpath*, *drawcircle*, *drawrect*, *eraseshape*.",
"description": "Determines which predefined modebar buttons to add. Please note that these buttons will only be shown if they are compatible with all trace types used in a graph. Similar to `config.modeBarButtonsToAdd` option. This may include *v1hovermode*, *hoverclosest*, *hovercompare*, *togglehover*, *togglespikelines*, *drawline*, *drawopenpath*, *drawclosedpath*, *drawcircle*, *drawrect*, *eraseshape*, *downloadJson*.",
"dflt": "",
"editType": "modebar",
"valType": "string"
Expand Down
Loading