-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Conversation
/** Maximum of all finite values. */ | ||
maximum: number | boolean; | ||
} | ||
|
||
// TODO(cais): Add sub-interfaces of `BaseTensorHealthPill` for other tensor |
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.
Nit: update 'HealthPill' in this comment, maybe also in the filename, and search the rest of the code for any other instances
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.
@@ -178,6 +178,7 @@ | |||
id="tensorValueMultiView" | |||
continue-to-callback="[[_createContinueToCallback()]]" | |||
tensor-name-clicked="[[_createNodeClickedHandler()]]" | |||
get-health-pill="[[_createGetHealthPill()]]" |
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.
get-numeric-summary, _createGetNumericSummary()
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 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, |
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.
here too
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.
Ditto.
@@ -307,6 +311,31 @@ | |||
.catch((err) => reject(err)); | |||
}); | |||
}, | |||
getNumericSummary: async () => { | |||
return new Promise((resolve, reject) => { |
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.
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()
.
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 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; |
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 numericSummary
have this detailed type in the first place, avoiding the need for the cast? Will there be any other concrete types?
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.
private menu: Menu | null = null; | ||
|
||
// Value render mode. | ||
protected valueRenderMode: 'text' | 'image'; |
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.
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.
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 changing it to an enum.
@@ -0,0 +1,278 @@ | |||
/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. |
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.
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.
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 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', () => { |
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.
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.
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. Made mouseleave a no-op as you suggested.
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.
Thanks for the review, @davidsoergel
/** Maximum of all finite values. */ | ||
maximum: number | boolean; | ||
} | ||
|
||
// TODO(cais): Add sub-interfaces of `BaseTensorHealthPill` for other tensor |
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.
@@ -0,0 +1,278 @@ | |||
/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. |
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 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'; |
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 changing it to an enum.
@@ -178,6 +178,7 @@ | |||
id="tensorValueMultiView" | |||
continue-to-callback="[[_createContinueToCallback()]]" | |||
tensor-name-clicked="[[_createNodeClickedHandler()]]" | |||
get-health-pill="[[_createGetHealthPill()]]" |
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 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, |
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.
Ditto.
@@ -307,6 +311,31 @@ | |||
.catch((err) => reject(err)); | |||
}); | |||
}, | |||
getNumericSummary: async () => { | |||
return new Promise((resolve, reject) => { |
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 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', () => { |
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. Made mouseleave a no-op as you suggested.
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.
LGTM, thanks for the fixes!
Motivation for features / changes
Technical description of changes
FlatMenu
andMenu
classes.ColorMap
and a basic implementationGrayscaleColorMap
. The latter is used for image rendering of numeric and boolean tensor values.BooleanOrNumericTensorNumericSummary
Screenshots of UI changes