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

Modify dashboard mapping to take object values #459

Merged
merged 6 commits into from
Sep 2, 2017

Conversation

chihuahua
Copy link
Member

@chihuahua chihuahua commented Sep 2, 2017

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.
pr curves

xuvg4au1yp8

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.
Copy link
Contributor

@wchargin wchargin left a 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}`);
Copy link
Contributor

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?

Copy link
Member Author

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 &&
Copy link
Contributor

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.

Copy link
Member Author

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(
Copy link
Contributor

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])?

Copy link
Member Author

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',
},
};
Copy link
Contributor

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.

Copy link
Member Author

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 {
Copy link
Contributor

Choose a reason for hiding this comment

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

How about DashboardData?

Copy link
Member Author

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} = {
Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member Author

@chihuahua chihuahua left a 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}`);
Copy link
Member Author

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 {
Copy link
Member Author

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} = {
Copy link
Member Author

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',
},
};
Copy link
Member Author

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(
Copy link
Member Author

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 &&
Copy link
Member Author

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: {
Copy link
Contributor

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).

Copy link
Member Author

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 Datums. Thus, renamed PLUGIN_TO_DASHBOARD_DATA to PLUGIN_TO_DASHBOARD_DATUM

Copy link
Contributor

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.

Copy link
Contributor

@wchargin wchargin left a 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.

@chihuahua chihuahua merged commit 7d1d430 into master Sep 2, 2017
@chihuahua chihuahua deleted the chihuahua-add-tab-name branch September 2, 2017 05:34
jart added a commit to jart/tensorboard that referenced this pull request Oct 4, 2017
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
jart added a commit that referenced this pull request Oct 4, 2017
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
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.

None yet

2 participants