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

[tensor-widget] Add support for hierarchical menu and image view of tensor values #2729

Merged
merged 16 commits into from
Oct 9, 2019
Merged

[tensor-widget] Add support for hierarchical menu and image view of tensor values #2729

merged 16 commits into from
Oct 9, 2019

Conversation

caisq
Copy link
Contributor

@caisq caisq commented Oct 4, 2019

  • Motivation for features / changes

    • Continue developing TensorWidget
  • Technical description of changes

    • Add menu.ts: Include FlatMenu and Menu classes.
    • Add a default menu item to TensorWdigetImpl, one that allows user to switch between text and image representations of numeric tensors.
    • Add colormap.ts: Include the base class ColorMap and a basic implementation GrayscaleColorMap. The latter is used for image rendering of numeric and boolean tensor values.
    • Add minimum and maximum values to BooleanOrNumericTensorNumericSummary
    • Rename terminology: health pill --> numeric summary
    • Update demo.ts.
  • Screenshots of UI changes
    image

image

image

image

@caisq caisq requested a review from davidsoergel October 5, 2019 03:44
/** Maximum of all finite values. */
maximum: number | boolean;
}

// TODO(cais): Add sub-interfaces of `BaseTensorHealthPill` for other tensor
Copy link
Member

Choose a reason for hiding this comment

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

Nit: update 'HealthPill' in this comment, maybe also in the filename, and search the rest of the code for any other instances

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -178,6 +178,7 @@
id="tensorValueMultiView"
continue-to-callback="[[_createContinueToCallback()]]"
tensor-name-clicked="[[_createNodeClickedHandler()]]"
get-health-pill="[[_createGetHealthPill()]]"
Copy link
Member

Choose a reason for hiding this comment

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

get-numeric-summary, _createGetNumericSummary()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This part belongs to the existing debugger plugin code, which has called it "health-pill" for a while. For the sake of consistency, I'd like to avoid changing the terminology here.

@@ -52,6 +52,8 @@
type: Number,
value: 0,
},

getHealthPill: Function,
Copy link
Member

Choose a reason for hiding this comment

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

here too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ditto.

@@ -307,6 +311,31 @@
.catch((err) => reject(err));
});
},
getNumericSummary: async () => {
return new Promise((resolve, reject) => {
Copy link
Member

Choose a reason for hiding this comment

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

Avoid mixing async/await with explicit Promise/callback style-- it's confusing. Since this function is already async, you can throw an error instead of reject(), and return instead of resolve().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with what you said in principle. But unfortunately this doesn't work in this Polymer code when I tried it. So I'll keep this style for now. Hopefully it won't be a problem when the debugger plugin v2 is written in Angular or other more modern frameworks.

maximum = value;
}
}
(numericSummary as BooleanOrNumericTensorNumericSummary).minimum = minimum;
Copy link
Member

Choose a reason for hiding this comment

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

Can numericSummary have this detailed type in the first place, avoiding the need for the cast? Will there be any other concrete types?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

private menu: Menu | null = null;

// Value render mode.
protected valueRenderMode: 'text' | 'image';
Copy link
Member

Choose a reason for hiding this comment

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

nit: my instinct is to use an enum here (maybe with string values, e.g. TEXT = 'text'). On the other hand, I don't know why I think that, and this also works fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done changing it to an enum.

@@ -0,0 +1,278 @@
/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
Copy link
Member

Choose a reason for hiding this comment

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

File comment: this revives my concern about integrating TensorWidget into a framework-based app. I.e., we'll want to make the look & feel match https://material.angular.io/components/menu. We can commit this anyway and deal with the Angular (etc.?) integration when the time comes.

One important behavior difference is that these menus disappear when you stop hovering on them, whereas Material (and MacOS, etc.) menus persist until you click elsewhere. That may be worth fixing here in any case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm still not convinced the value of adding a dependency overweighs the benefit of increased package size and build complexity. I've fixed the menu mouseleave callback issue you pointed out below. I guess we can leave this as an open point. If further UI widget needs come up in the future, we can revisit it.

}
menuItem.classList.add('tensor-widget-dim-dropdown-menu-item-active');
});
menuItem.addEventListener('mouseleave', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Ideally mouseleave should be a no-op, and this logic should trigger on a click anywhere outside the menu. Maybe that requires a transparent page-sized element to catch the clicks? I don't know how Angular Material components handle this case. I did a React version previously; I don't remember how it worked but let me know if it would help to look it up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Made mouseleave a no-op as you suggested.

Copy link
Contributor Author

@caisq caisq left a comment

Choose a reason for hiding this comment

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

Thanks for the review, @davidsoergel

/** Maximum of all finite values. */
maximum: number | boolean;
}

// TODO(cais): Add sub-interfaces of `BaseTensorHealthPill` for other tensor
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -0,0 +1,278 @@
/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm still not convinced the value of adding a dependency overweighs the benefit of increased package size and build complexity. I've fixed the menu mouseleave callback issue you pointed out below. I guess we can leave this as an open point. If further UI widget needs come up in the future, we can revisit it.

private menu: Menu | null = null;

// Value render mode.
protected valueRenderMode: 'text' | 'image';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done changing it to an enum.

@@ -178,6 +178,7 @@
id="tensorValueMultiView"
continue-to-callback="[[_createContinueToCallback()]]"
tensor-name-clicked="[[_createNodeClickedHandler()]]"
get-health-pill="[[_createGetHealthPill()]]"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This part belongs to the existing debugger plugin code, which has called it "health-pill" for a while. For the sake of consistency, I'd like to avoid changing the terminology here.

@@ -52,6 +52,8 @@
type: Number,
value: 0,
},

getHealthPill: Function,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ditto.

@@ -307,6 +311,31 @@
.catch((err) => reject(err));
});
},
getNumericSummary: async () => {
return new Promise((resolve, reject) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with what you said in principle. But unfortunately this doesn't work in this Polymer code when I tried it. So I'll keep this style for now. Hopefully it won't be a problem when the debugger plugin v2 is written in Angular or other more modern frameworks.

}
menuItem.classList.add('tensor-widget-dim-dropdown-menu-item-active');
});
menuItem.addEventListener('mouseleave', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Made mouseleave a no-op as you suggested.

@caisq caisq requested a review from davidsoergel October 9, 2019 14:36
Copy link
Member

@davidsoergel davidsoergel left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for the fixes!

@caisq caisq merged commit 185c0c4 into tensorflow:master Oct 9, 2019
@caisq caisq deleted the tensor-widget-menu branch October 9, 2019 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants