-
Notifications
You must be signed in to change notification settings - Fork 130
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
Adds a loader element #124
Conversation
d7b53eb
to
bc427cb
Compare
@ebidel Hey, Eric! Super important changes in here. My team discovered a ridiculous bug where calling the old loader multiple times resulted in variations of the corechart package being loaded. The versions were incompatible so it broke ... a lot. I wrote this new loader element to handle loading packages all at once and it also consolidates events and data object creation. This leaves the chart element itself to focus on just handling the chart stuff. Also fixes some tests. If you could take a look, that'd be great! |
function getRandomValue() { | ||
return Math.random() * 10; | ||
} | ||
const getRandomValue = () => Math.random() * 10; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think we should use arrow functions yet. IE 10/11 and Safari < 10 will have issues.
Going to hold off removing the rest until the es6 features are removed. I'd also like to better understand the bugs you encountered and the perf hit of loading all the packages upfront. It makes the element much less granular. Can you post some numbers? |
Sorry about the es6, we use that internally, so this code is mostly a copy/paste of the fix I made to address the bug. Thanks for the quick review. I wanted to run the design by you before I worked on it too much in case you had some major concerns. It's actually not a performance hit but a performance win. The bug we encountered may or may not be something that only internal users were subject to. In our case, we make heavy use of the google-chart element. We even use raw Google Chart library to draw controls and dashboards (see #91 for that enhancement). We were loading the the library multiple times to load We saw the following exceptions (where
Our hypothesis was that different versions of the code were being loaded for Japan and America, however, the first exception really stood out to me. The chart was most definitely, always being drawn with a DataView. No question. I logged the data properties at the draw call for all of the charts on the page and noticed that some DataTable instances were from a constructor Thus, this element was born. It consolidates all of the package loading into one global state. It debounces the actual load call to collect as many packages into the load as possible. The loader can be primed with any extra required packages, as well. It separates out the package logic from the chart logic meaning that users can create their own Google Visualization stuff that this element does not currently support. This also means we do not need to rely on the Google Visualization team to allow us to call The point is that this allows users much greater flexibility and stability. Completely eliminating the need to do their own library loads outside of using the Now, users can do:
or:
instead of:
This also means that users will be able to do more Polymer-y event handling (although currently only implemented for the existing events):
I hope this clears things up, but please let me know if you have any other questions. I'll remove the es6 stuff, but in the mean time, please still give the code a design review when you can. Thanks, |
A note on performance: Time to first render of a chart using just the
Page load time for multiple chart types**:
It seems the collective loading version spends more time idle. This indicates the 100ms may be too long, but I think it's still a good value to at least start with. We could include a property to have it load immediately in the case of known chart packages.
*Measured by "Default Functionality > fires google-chart-render event for initial load" test. **Using the demo page. Not a completely fair test in this case sense the version with collective loading also loads and renders a material Bar chart and does not have the |
1f08ae2
to
c0c39a5
Compare
@ebidel : All of your comments have been integrated. PTAL |
7246d7b
to
eeb4062
Compare
}; | ||
|
||
function namespaceForType(type) { | ||
return google[type.startsWith('md-') ? 'charts' : 'visualization']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should handle if google
is undefined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow what you mean.
This is only called after google
and google.charts
or google.visualization
is loaded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, but returning a default ns would be good just in case.
if (!window.google) {
// return default ns.
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we may be talking about different things.
In this case, the namespace is where the chart constructor is located.
For traditional chart types, that namespace is google.visualization
.
For new (material) charts, that namespace is google.charts
.
e.g.
google.visualization.BarChart // traditional bar chart
google.charts.Bar // material bar/column chart
So there is no default that would work. The calling function would look for defaultns.BarChart
or something which would be equally incorrect.
This function is called inside of a protected area where the required package is guaranteed to have already been loaded. There is no way to recover from a situation where the package is loaded but google
or google.charts
is not available.
The exception thrown Uncaught ReferenceError: google is not defined
LGTM in this case. If we were to check if google exists, it would just be to throw a different exception.
What do you think?
The refactoring seems 👍 Haven't tested it myself, but it's more modular and seems to clean up the codebase. |
Cool, I'll integrate these changes this weekend. I have a follow-up PR that removes all the loading based promises from inside the chart element since now we have Polymer events and bindings for the loading. Cleans up even more stuff. |
eeb4062
to
8ba2aab
Compare
8ba2aab
to
1178867
Compare
I think just the one comment left. |
Handles loading the necessary packages for charts.
1178867
to
bec220f
Compare
Finished adding documentation. |
@@ -18,6 +18,10 @@ | |||
'bar': { | |||
ctor: 'BarChart', | |||
}, | |||
'md-bar': { | |||
ctor: 'Bar', | |||
pkg: 'bar', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pkg: 'bar'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nvm, I see others are like this already.
LGTM |
When is this releasing? I am struck at using google chart's treemap using polymer. Please help. |
I have realised that it has already been released. Thanks. |
Someone can help me for the integration in angular ? https://stackoverflow.com/q/51153920/9962015 |
This fixes a major bug my team discovered.
It collects all the packages into one load call which is extremely important right now.
Now that all the packages are loaded at once, we can use the new loader.
Now that we are using the new loader, we can use the new material chart types.
This also redoes events to be more Polymer-y and changes the getImageURI function to a getter.