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

[DataViz] Snapshot works for GoogleCharts #33703

Merged
merged 7 commits into from Mar 20, 2020
Merged

[DataViz] Snapshot works for GoogleCharts #33703

merged 7 commits into from Mar 20, 2020

Conversation

ajpal
Copy link
Contributor

@ajpal ajpal commented Mar 18, 2020

Part 1
Implements rendering GoogleChart types (bar, histogram, scatter plot) as <img> elements in the snapshot modal.
Bar Chart:
image
image

Histogram:
image
image

Scatter Plot:
image
image

Links

Testing story

Reviewer Checklist:

  • Tests provide adequate coverage
  • Code is well-commented
  • New features are translatable or updates will not break translations
  • Relevant documentation has been added or updated
  • User impact is well-understood and desirable
  • Pull Request is labeled appropriately
  • Follow-up work items (including potential tech debt) are tracked and linked

@ajpal ajpal requested a review from a team as a code owner March 18, 2020 17:05
@ajpal ajpal changed the base branch from staging to mar17-snapshot March 18, 2020 17:05
@ajpal ajpal mentioned this pull request Mar 18, 2020
7 tasks
Copy link
Contributor

@islemaster islemaster left a comment

Choose a reason for hiding this comment

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

👍 Nothing blocking.

imageType = imageType || 'image/png';
options = options || {};
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use default parameters here?

return <div ref={element => (this.chartArea = element)} />;
return (
<div
id="googleChartContainer"
Copy link
Contributor

Choose a reason for hiding this comment

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

If we're not going to explicitly pass refs around, it might be a good idea to share this id between components with a constant, so we won't accidentally change it in only one place in the future.

class Snapshot extends React.Component {
static propTypes = {
chartType: PropTypes.number.isRequired,
Copy link
Contributor

Choose a reason for hiding this comment

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

If you want to get really specific,

chartType: PropTypes.oneOf(Object.values(ChartType)).isRequired,

this.getImageFromCrossTab();
break;
default:
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The empty default case seems weird. Why not

if (ChartType.CROSS_TAB === this.props.chartType) {
  this.getImageFromCrossTab();
} else {
  this.getImageFromGoogleChart();
}

...until things are more complicated?

svgToDataURI(svg, 'image/png', {renderer: 'native'}).then(imageURI => {
if (this.isMounted_) {
this.setState({imageSrc: imageURI});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I've heard isMounted is an antipattern but have never been totally satisfied with the alternatives - cancellable promises are cool, but also have more boilerplate than I'd like.

No need to change anything, but I'd love to hear your thoughts on this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oo thanks for pointing this out. I didn't know isMounted was an anti-pattern, I think I just modeled this off of similar structures elsewhere in our codebase. I will look into cancellable promises as a follow-up PR.

return <div ref={element => (this.chartArea = element)} />;
return (
<div
id="googleChartContainer"
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: use kebab-case for element IDs

return;
}
svgToDataURI(svg, 'image/png', {renderer: 'native'}).then(imageURI => {
if (this.isMounted_) {
Copy link
Contributor

Choose a reason for hiding this comment

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

i don't think i understand why this.isMounted_ is necessary -- won't this method only ever be called when the component has already mounted?

Copy link
Contributor

Choose a reason for hiding this comment

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

i just noticed Brad's comment that's basically the same -- feel free to answer there

Copy link
Contributor Author

Choose a reason for hiding this comment

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

getImageFromGoogleChart will only be called when the component is mounted, but it's possible that the snapshot modal is closed before svgToDataURI finishes, in which case the component will be unmounted by the time the callback runs. That's why I have the isMounted_ check before setting the state from the callback

@ajpal ajpal changed the base branch from mar17-snapshot to staging March 20, 2020 17:45
Copy link
Contributor

@maddiedierker maddiedierker left a comment

Choose a reason for hiding this comment

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

🎉

@ajpal ajpal merged commit 175cbb7 into staging Mar 20, 2020
@ajpal ajpal deleted the mar18-googlechart branch May 26, 2020 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants