-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Modify dashboard mapping to take object values #459
Conversation
58464ce
to
30109ef
Compare
Previously, logic related to dashboards would reference TENSORBOARD_PLUGINS, a mapping between plugin name to dashboard element name. Logic would also use the name of the plugin (the key of that mapping) as the tab name displayed in TensorBoard. This is suboptimal for several reasons - the plugin name is not necessarily optimized for display purposes. For instance, take the plugin name pr_curves. We would ideally remove the underscore from it. Renamed the _dashboards array within the tf-tensorboard component to _dashboardInformationObjects to emphasize how that array is not a string array, but rather contains objects.
30109ef
to
85e29e3
Compare
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.
DashboardInformation
and _dashboardInformationObjects
are really mouthfuls. How about DashboardData
and _dashboardData
? This is a more common pattern, in my experience: for instance, we have PluginData
, Summary[Meta]Data
, etc. Names matter. :-)
if (!container) { | ||
// This dashboard doesn't exist. Nothing to do here. | ||
console.log(`no exist - ${selectedDashboard}`); |
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.
Did you mean to remove this? If you want to keep it, (a) what value does it add? and (b) could you improve the message?
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.
Removed.
@@ -696,7 +714,9 @@ | |||
&& selectedDashboard == null); | |||
}, | |||
_computeShowNoSuchDashboardMessage(dashboards, selectedDashboard) { | |||
return !!selectedDashboard && !dashboards.includes(selectedDashboard); | |||
return !!selectedDashboard && |
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.
Can we just write !!selectedDashboard && !dashboards.some(d => d.plugin === selectedDashboard)
? The lodash boilerplate is really unnecessary here.
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.
Yes - that boilerplate looks convoluted. Done.
@@ -664,7 +679,10 @@ | |||
return; | |||
} | |||
const activePlugins = result.value; | |||
this._activeDashboards = this._dashboards.filter(d => activePlugins[d]); | |||
this._activeDashboards = _.map( |
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.
Do you think that this is easier to read as this._dashboardInformationObjects.map(d => d.plugin).filter(p => activePlugins[p])
?
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.
Yes! Producing a list of strings and then filtering does seem clearer - the filtering logic only needs to observe the string value. Done.
plugin: 'profile', | ||
tabName: 'Profile', | ||
}, | ||
}; |
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.
What do you think about adding the following after this line:
Object.entries(PLUGIN_TO_DASHBOARD_INFORMATION).forEach(([plugin, data]) => {
if (data.plugin !== plugin) {
throw new Error(`Plugin name mismatch for key: ${plugin}`);
}
}
This free check seems like it might save us some trouble down the line.
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.
Good idea. Done.
limitations under the License. | ||
==============================================================================*/ | ||
|
||
export interface DashboardInformation { |
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.
How about DashboardData
?
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.
Done.
|
||
// Maps plugin name (must match the backend) to DashboardInformation. | ||
const PLUGIN_TO_DASHBOARD_INFORMATION | ||
: {[key: string]: DashboardInformation} = { |
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.
It looks like you don't need this line break, and it's certainly nicer to read without it.
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.
Done.
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 verified that demos WAI (same screenshots).
if (!container) { | ||
// This dashboard doesn't exist. Nothing to do here. | ||
console.log(`no exist - ${selectedDashboard}`); |
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.
Removed.
limitations under the License. | ||
==============================================================================*/ | ||
|
||
export interface DashboardInformation { |
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.
Done.
|
||
// Maps plugin name (must match the backend) to DashboardInformation. | ||
const PLUGIN_TO_DASHBOARD_INFORMATION | ||
: {[key: string]: DashboardInformation} = { |
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.
Done.
plugin: 'profile', | ||
tabName: 'Profile', | ||
}, | ||
}; |
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.
Good idea. Done.
@@ -664,7 +679,10 @@ | |||
return; | |||
} | |||
const activePlugins = result.value; | |||
this._activeDashboards = this._dashboards.filter(d => activePlugins[d]); | |||
this._activeDashboards = _.map( |
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.
Yes! Producing a list of strings and then filtering does seem clearer - the filtering logic only needs to observe the string value. Done.
@@ -696,7 +714,9 @@ | |||
&& selectedDashboard == null); | |||
}, | |||
_computeShowNoSuchDashboardMessage(dashboards, selectedDashboard) { | |||
return !!selectedDashboard && !dashboards.includes(selectedDashboard); | |||
return !!selectedDashboard && |
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.
Yes - that boilerplate looks convoluted. Done.
* | ||
* @type {!Array<Object>} | ||
*/ | ||
_dashboardInformationObjects: { | ||
_dashboardDataObjects: { |
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.
The other half of my earlier comment (perhaps just implied) was that the Objects
is totally redundant here. _dashboardData
is easier to work with, and the "data" bit clarifies that it's not just the dashboard names (a goal that you noted in your original description, and with which I agree).
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.
True. Objects seems redundant. We now use Data
to refer to a list of Datum
s. Thus, renamed PLUGIN_TO_DASHBOARD_DATA
to PLUGIN_TO_DASHBOARD_DATUM
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.
Cool. I was considering that; either's fine with me.
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.
You have my approval.
The plugin list no longer needs to be specified at all. The HTML imports themselves are now the plugin list. Special properties, e.g. custom tab names, are now defined as properties on the Polymer components themselves. The tradeoff is that each plugin's dashboard must call a registration function, providing the plugin name and the name of the custom element. See also: tensorflow#459
The plugin list no longer needs to be specified at all. The HTML imports themselves are now the plugin list. Special properties, e.g. custom tab names, are now defined as properties on the Polymer components themselves. The tradeoff is that each plugin's dashboard must call a registration function, providing the plugin name and the name of the custom element. See also: #459
Previously, logic related to dashboards would reference
TENSORBOARD_PLUGINS, a mapping between plugin name to dashboard element
name. Logic would also use the name of the plugin (the key of that
mapping) as the tab name displayed in TensorBoard.
This is suboptimal for several reasons - the plugin name is not
necessarily optimized for display purposes. For instance, take the
plugin name pr_curves. We would ideally remove the underscore from it.
We thus introduce the concept of
DashboardData
, which encapsulates data on a dashboard - the name of the element for the dashboard component (elementName
), the name of the associated plugin (plugin
), and the name to show within the navigation menu (tabName
).Renamed the _dashboards array within the tf-tensorboard component to
_dashboardInformationObjects to emphasize how that array is not a string
array, but rather contains objects.
Note that the underscore is now gone from the tab name of the PR curves dashboard.