Skip to content

Add JSON download modebar button - #7990

Open
gokul-debugger wants to merge 2 commits into
plotly:mainfrom
gokul-debugger:feat/download-figure-json-main
Open

Add JSON download modebar button#7990
gokul-debugger wants to merge 2 commits into
plotly:mainfrom
gokul-debugger:feat/download-figure-json-main

Conversation

@gokul-debugger

Copy link
Copy Markdown

What does this PR do?

Adds an opt-in downloadJson modebar button for exporting the current Plotly figure as JSON.

The button can be enabled through:

config: {
    modeBarButtonsToAdd: ['downloadJson']
}

or through layout.modebar.add.

It uses Plotly's existing full-json export pipeline, preserving the established serialization behavior for figure data, layout, config, typed arrays, and version metadata. Download failures are reported through the existing Plotly notifier.

This replaces #7963, which GitHub closed after its base branch was deleted.

Closes #7917

Testing

  • npm run test-jasmine -- modebar --nowatch (103 tests passed)
  • npm run lint
  • npm run typecheck
  • npm run test-syntax
  • npm run schema-typegen-diff-check
  • git diff --check

@gokul-debugger
gokul-debugger marked this pull request as ready for review August 24, 2026 23:16
@camdecoster camdecoster self-assigned this Aug 25, 2026
@gokul-debugger

Copy link
Copy Markdown
Author

All substantive CI checks are passing. The only failure is flaky-no-gl-jasmine, which appears unrelated to this change. I do not have permission to rerun it from my fork. Could a maintainer please rerun that check when convenient?

@camdecoster camdecoster left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good and is working in my testing. I'd like to move where the button gets added and add a success message for parity with the toImage button. Once that's done, I can approve and merge.

Comment on lines +96 to 97
| 'downloadJson'
// Other

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be more appropriate to keep this under 'Other'.

Suggested change
| 'downloadJson'
// Other
// Other
| 'downloadJson'

Comment on lines +72 to +83
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);
});
}
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add the success message along with the error message.

Suggested change
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.downloadJson = {
name: 'downloadJson',
title: (gd) => _(gd, 'Download plot as JSON'),
icon: Icons.disk,
click: (gd) => {
Registry.call('downloadImage', gd, { format: 'full-json' })
.then((filename) => {
Lib.notifier(_(gd, 'JSON download succeeded') + ' - ' + filename, 'long', gd);
})
.catch(() => {
Lib.notifier(_(gd, 'Sorry, there was a problem downloading your JSON file!'), 'long', gd);
});
}
};

Comment on lines 145 to 149
// buttons common to all plot types
var commonGroup = ['toImage'];
if(context.showSendToCloud) commonGroup.push('sendChartToCloud');
addGroup(commonGroup);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this section down and add a boolean to track if the button should be included.

Suggested change
let addDownloadJson = false;

enableHover('hoverClosest3d');
enableHover('hoverClosestPie');
} else if(b === 'downloadjson') {
newList.push(modeBarButtons.downloadJson);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
newList.push(modeBarButtons.downloadJson);
addDownloadJson = true;

buttonsToAdd = newList;
}

addGroup(dragModeGroup);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By moving this down, we can place the downloadJson button next to the download image button, which makes more sense to me.

Suggested change
// buttons common to all plot types
const commonGroup = ['toImage'];
if (addDownloadJson) commonGroup.push('downloadJson');
if (context.showSendToCloud) commonGroup.push('sendChartToCloud');
addGroup(commonGroup);
addGroup(dragModeGroup);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Add modebar button to download figure JSON

2 participants