Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add format "full-json" to Plotly.toImage and Plotly.dowloadImage #4593

Merged
merged 7 commits into from
Mar 11, 2020

Conversation

antoinerg
Copy link
Contributor

@antoinerg antoinerg commented Feb 19, 2020

First step needed to complete plotly/orca#283

This PR introduces a new export format full-json that returns the graph JSON by using plots.graphJson()

Also, this PR introduces a version.js file containing the current version of the library which is easy to import in any part of the code. See 6a8ac65 for details.

TODO

  • resolve conflicts
  • sort object keys
  • use full.json extension

cc @nicolaskruchten

@antoinerg antoinerg added the feature something new label Feb 19, 2020
@archmoj archmoj added this to the v1.53.0 milestone Feb 19, 2020
@archmoj
Copy link
Contributor

archmoj commented Feb 19, 2020

Since the figure attributes change from one version to another, we should possibly write plotly.js version to the output, IMO.

@etpinard
Copy link
Contributor

we should possibly write plotly.js version to the output, IMO.

Not a bad idea!

Should we write it side-by-side with the data and layout attributes or put it in layout.version?

@antoinerg
Copy link
Contributor Author

Should we write it side-by-side with the data and layout attributes or put it in layout.version?

Shouldn't we also consider config? Regardless, I think it would make sense to include the version.

cc @alexcjohnson

@etpinard
Copy link
Contributor

Shouldn't we also consider config

We could, but in general the config won't be JSON-serializable. We could include only the JSON-serializable parts of the config and maybe add a placeholder for functions, for example:

modeBarButtonsToAdd: [{
  name: 'my button',
  click: function(gd) { console.log('hello') }
}]

// would become

{
  modeBarButtonsToAdd: [{
    name: 'my button',
    click: '_function_'
  }]
}

@archmoj
Copy link
Contributor

archmoj commented Feb 19, 2020

One more question:
Is the resulting object sorted by keys?

@alexcjohnson
Copy link
Collaborator

Yes, I'd include config using @etpinard's suggestion for functions. And very nice idea @archmoj re: version. I'd say it goes at the top level, to make it clear it's not actually an attribute.

@antoinerg
Copy link
Contributor Author

@etpinard is it OK to assume nothing in data or layout is ever a function?

If that's the case, can I simply replace

plotly.js/src/plots/plots.js

Lines 2054 to 2056 in 15d75db

if(typeof d === 'function') {
return null;
}

with

        if(typeof d === 'function') {
            return '_function_';
        }

That should be safe and non-breaking, right?

@etpinard
Copy link
Contributor

is it OK to assume nothing in data or layout is ever a function?

No, there are plenty of functions inside fullLayout e.g. fullLayout.xaxis.l2p

@nicolaskruchten
Copy link
Contributor

nicolaskruchten commented Feb 19, 2020 via email

@alexcjohnson
Copy link
Collaborator

plots.graphJson already removes attributes with leading underscores and values that are functions. That covers everything outside the schema that's in data and layout. config converting to gd._context is handled differently and as @etpinard points out has some functions in the actual user-provided values, so sending it back will need special handling as well.

@nicolaskruchten
Copy link
Contributor

I'm not sure about the value of returning config here TBH...

@alexcjohnson
Copy link
Collaborator

config could certainly be omitted at least to start - could always add it in later, perhaps if and when we convert it to using the same coerce machinery as data and layout.

@antoinerg
Copy link
Contributor Author

antoinerg commented Feb 20, 2020

@alexcjohnson adding config is not too bad (see 9497ed5)

The problem I have at the moment is outputting the version number (ie. Plotly.version) without getting circular dependency (see 9497ed5#r37388098). What's the easiest way to refer to the version number from anywhere in the code?

@etpinard
Copy link
Contributor

etpinard commented Feb 20, 2020

What's the easiest way to refer to the version number from anywhere in the code?

The trick is to hardcode it just like in

exports.version = '1.52.2';

and

exports.version = '1.52.2';

and then add a line below

makeBuildCSS();
copyTopojsonFiles();
updateVersion(constants.pathToPlotlyCore);
updateVersion(constants.pathToPlotlyGeoAssetsSrc);

updateVersion(/* path/to/file/ */);

and let the update_version.js util do the rest.

@antoinerg
Copy link
Contributor Author

At the moment, when downloading the file via downloadImage we end up with a filename with extension .full-json. Should we instead set the extension to .full.json or .json?

cc @plotly/plotly_js @nicolaskruchten

updateVersion(constants.pathToPlotlyCore);
updateVersion(constants.pathToPlotlyGeoAssetsSrc);
updateVersion(constants.pathToPlotlyVersion);
Copy link
Contributor

Choose a reason for hiding this comment

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

nicely done !!

@nicolaskruchten
Copy link
Contributor

I like .json but this is a weakly-held preference.

@archmoj
Copy link
Contributor

archmoj commented Mar 10, 2020

some TODOs here:

  • resolve conflicts
  • sort object keys
  • use .json extension

@antoinerg
Copy link
Contributor Author

antoinerg commented Mar 11, 2020

  • sort object keys

I'm wondering if sorting the object's keys recursively is really required? Would it be valuable to users?

cc @alexcjohnson @nicolaskruchten @archmoj

@alexcjohnson
Copy link
Collaborator

Sorting isn’t a hard requirement, could be omitted for now, but I do think it could be useful. @archmoj pointed out diffing, though I guess _full* will have a consistent order anyway due to the coerce process. But regardless, some objects will be pretty big, sorting will make it easier to find things.

@antoinerg
Copy link
Contributor Author

Sorting isn’t a hard requirement, could be omitted for now, but I do think it could be useful.

Ok so would 81b8813 be satisfactory? I guess I could turn the forEach into a for loop. Any other comments?

@alexcjohnson
Copy link
Collaborator

Ok so would 81b8813 be satisfactory?

Looks great to me - I wouldn't worry about for vs forEach there, these are not looping over data arrays, and are not being called often.

No other comments from me, let's do it!

@antoinerg antoinerg closed this Mar 11, 2020
@antoinerg antoinerg deleted the full-json branch March 11, 2020 20:29
@antoinerg antoinerg restored the full-json branch March 11, 2020 20:31
@antoinerg antoinerg reopened this Mar 11, 2020
Copy link
Collaborator

@alexcjohnson alexcjohnson left a comment

Choose a reason for hiding this comment

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

💃 beautiful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants