Skip to content

Commit

Permalink
Start replacing titles with custom tooltip element and modify color l…
Browse files Browse the repository at this point in the history
…egend information display.

PiperOrigin-RevId: 501686472
  • Loading branch information
cjqian authored and LIT team committed Jan 12, 2023
1 parent 7d3f235 commit bd0f7fc
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 52 deletions.
27 changes: 19 additions & 8 deletions lit_nlp/client/elements/color_legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ export class ColorLegend extends ReactiveElement {
@observable @property({type: Object}) scale: D3Scale =
d3.scaleOrdinal([DEFAULT]).domain(['all']) as D3Scale;
@property({type: String}) legendType = LegendType.CATEGORICAL;
@property({type: String}) selectedColorName = '';
@property({type: String}) label = '';
/** Optional hover tooltip text on the color palette icon. */
@property({type: String}) paletteTooltipText = '';
/** Width of the container. Used to determine if blocks should be labeled. */
@property({type: Number}) legendWidth = 150;

Expand Down Expand Up @@ -187,11 +189,16 @@ export class ColorLegend extends ReactiveElement {
// clang-format off
return html`
<div class="legend-container">
<mwc-icon class="icon material-icon-outlined">palette</mwc-icon>
<div class="color-label" title=${this.selectedColorName}
<lit-tooltip .content=${this.paletteTooltipText}
.tooltipPosition=${'above'}>
<mwc-icon class="icon material-icon-outlined"
slot="tooltip-anchor">palette</mwc-icon>
</lit-tooltip>
<div class="color-label" title=${this.label}
name="color-name">
${this.selectedColorName}
${this.label}
</div>
${this.scale.domain().map(
(val: string|number) => this.renderLegendBlock(val, hideLabels))}
</div>
Expand All @@ -211,15 +218,19 @@ export class ColorLegend extends ReactiveElement {
// round it to an integer if the value is greater than or equal to 5
rangeUnit = rangeUnit >= 5 ? Math.round(rangeUnit) : rangeUnit;


// clang-format off
return html`
<div class="legend-container">
<mwc-icon class="icon material-icon-outlined">palette</mwc-icon>
<div class="color-label" title=${this.selectedColorName}
<lit-tooltip .content=${this.paletteTooltipText}
.tooltipPosition=${'above'}>
<mwc-icon class="icon material-icon-outlined"
slot="tooltip-anchor">palette</mwc-icon>
</lit-tooltip>
<div class="color-label" title=${this.label}
name="color-name">
${this.selectedColorName}
${this.label}
</div>
<div class='legend-label'>${this.toStringValue(minValue)}</div>
${domain.map((colorVal: number) => {
if (colorVal !== minValue) {
Expand Down
12 changes: 7 additions & 5 deletions lit_nlp/client/elements/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -740,11 +740,13 @@ export class DataTable extends ReactiveElement {
@click=${lastPage}>
last_page
</mwc-icon>
<mwc-icon class='icon-button mdi-outlined'
title="Go to a random page" @click=${randomPage}>
casino
</mwc-icon>
`;
<lit-tooltip .content=${"Go to a random page"}
.tooltipPosition=${"above"}>
<mwc-icon class='icon-button mdi-outlined' @click=${randomPage}
slot="tooltip-anchor">
casino
</mwc-icon>
</lit-tooltip>`;
// clang-format on
}

Expand Down
4 changes: 4 additions & 0 deletions lit_nlp/client/elements/tooltip.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
overflow: hidden;
}

.above {
bottom: 28px;
}

.lit-tooltip .tooltip-text a {
color: #7bcccc;
}
Expand Down
55 changes: 38 additions & 17 deletions lit_nlp/client/elements/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,25 @@
// tslint:disable:no-new-decorators
import {html} from 'lit';
import {customElement, property} from 'lit/decorators';
import {classMap} from 'lit/directives/class-map';

import {styles} from './tooltip.css';
import {ReactiveElement} from '../lib/elements';
import {getTemplateStringFromMarkdown} from '../lib/utils';
import {styles as sharedStyles} from '../lib/shared_styles.css';
import {getTemplateStringFromMarkdown} from '../lib/utils';

import {styles} from './tooltip.css';

/**
* An element that displays a header with a label and a toggle to expand or
* collapse the subordinate content.
* A tooltip element that displays on hover and on click.
*
* Use the `tooltip-anchor` slot for the control; this will be rendered where
* the <lit-tooltip> element is placed.
*
* Usage:
* <lit-tooltip style=${tooltipStyle> .content=${tooltipMarkdown}>
* <button slot="tooltip-anchor">
* </button>
* </lit-tooltip>
*/
@customElement('lit-tooltip')
export class LitTooltip extends ReactiveElement {
Expand All @@ -38,25 +48,36 @@ export class LitTooltip extends ReactiveElement {

// Markdown that shows on hover.
@property({type: String}) content = '';
@property({type: String}) tooltipPosition: string = '';
@property({type: Boolean}) shouldRenderAriaLabel = true;

renderAriaLabel() {
return this.shouldRenderAriaLabel ? html`aria-label=${this.content}` : '';
}

/**
* Renders the reference tooltip with text and optional URL.
* Renders the reference tooltip.
*/
override render() {
if (this.content === '') {
return html``;
}
const tooltipClass = classMap({
'tooltip-text': true,
'above': this.tooltipPosition === 'above'
});

return html`
<div class='lit-tooltip'>
<span class="help-icon material-icon-outlined icon-button">
help_outline
</span>
<span class='tooltip-text'>
${getTemplateStringFromMarkdown(this.content)}
</span>
</div>
`;
<div class='lit-tooltip'>
<slot name="tooltip-anchor">
${this.content === '' ? '' : html`
<span class="help-icon material-icon-outlined icon-button">
help_outline
</span>`}
</slot>
${this.content === '' ? '' : html`
<span class=${tooltipClass} ${this.renderAriaLabel()}>
${getTemplateStringFromMarkdown(this.content)}
</span>`}
</div>
`;
}
}

Expand Down
15 changes: 15 additions & 0 deletions lit_nlp/client/elements/tooltip_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,20 @@ describe('tooltip test', () => {
expect(tooltipText.innerHTML).toContain('Test content');
const style = window.getComputedStyle(tooltipText);
expect(style.getPropertyValue('visibility')).toEqual('hidden');
expect(tooltipText).not.toHaveClass('above');
});

it('conditionally renders aria label', async () => {
expect(tooltip.renderAriaLabel()).not.toEqual(``);
tooltip.shouldRenderAriaLabel = false;
expect(tooltip.renderAriaLabel()).toEqual(``);
});

it('conditionally updates tooltip position', async () => {
tooltip.tooltipPosition = 'above';
await tooltip.updateComplete;
const tooltipText =
tooltip.renderRoot.querySelector<HTMLSpanElement>('span.tooltip-text')!;
expect(tooltipText).toHaveClass('above');
});
});
2 changes: 2 additions & 0 deletions lit_nlp/client/modules/data_table_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ export class DataTableModule extends LitModule {

if (isPrimarySelection || isFocused || isReferenceSelection ||
isStarred) {
// TODO(b/255799266): Add fast tooltips to icons.
// There's an issue with table resizing and mwc-icon interactions.
return html`
<mwc-icon style="${getActionStyle(isReferenceSelection)}"
class="${getActionClass(isReferenceSelection)}"
Expand Down
4 changes: 2 additions & 2 deletions lit_nlp/client/modules/dive_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ export class DiveModule extends LitModule {
<div class="dropdown-holder">
<label class="dropdown-label">${label}</label>
<select class="dropdown limit-width" @change=${onChange}
title=${this.groupService.denseFeatureNames[index]}>
aria-label=${this.groupService.denseFeatureNames[index]}>
${this.groupService.denseFeatureNames.map((feature, i) => html`
<option value=${i} ?selected=${index === i}>
${feature}
Expand Down Expand Up @@ -569,7 +569,7 @@ export class DiveModule extends LitModule {

// clang-format off
return html`<color-legend legendType=${legendType}
selectedColorName=${this.colorService.selectedColorOption.name}
label=${this.colorService.selectedColorOption.name}
.scale=${this.colorService.selectedColorOption.scale}>
</color-legend>`;
// clang-format on
Expand Down
12 changes: 8 additions & 4 deletions lit_nlp/client/modules/embeddings_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import '../elements/tooltip';
// tslint:disable:no-new-decorators
// taze: ResizeObserver from //third_party/javascript/typings/resize_observer_browser
import '@material/mwc-icon';
Expand Down Expand Up @@ -573,17 +574,20 @@ export class EmbeddingsModule extends LitModule {
${this.renderLabelBySelect()}
${this.renderSpriteBySelect()}
<div>
<mwc-icon class="icon-button mdi-outlined"
title="Reset view"
@click=${onClickReset}>view_in_ar</mwc-icon>
<lit-tooltip .content=${'Reset view'}>
<mwc-icon class="icon-button mdi-outlined"
@click=${onClickReset} slot="tooltip-anchor">
view_in_ar
</mwc-icon>
</lit-tooltip>
</div>
</div>
<div class="module-results-area">
${this.renderResultsArea()}
</div>
<div class="module-footer">
<color-legend legendType=${legendType}
selectedColorName=${this.colorService.selectedColorOption.name}
label=${this.colorService.selectedColorOption.name}
.scale=${this.colorService.selectedColorOption.scale}>
</color-legend>
<button class="hairline-button selected-nearest-button"
Expand Down
2 changes: 1 addition & 1 deletion lit_nlp/client/modules/feature_attribution_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ export class FeatureAttributionModule extends LitModule {
</div>
<div class="module-footer">
<div class="color-legend-container">
<color-legend selectedColorName="Salience" .scale=${scale}
<color-legend label="Salience" .scale=${scale}
legendType=${LegendType.SEQUENTIAL} numBlocks=${7}>
</color-legend>
<mwc-icon class="icon material-icon-outlined"
Expand Down
25 changes: 12 additions & 13 deletions lit_nlp/client/modules/salience_map_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ interface InterpreterState {
const LEGEND_INFO_TITLE_SIGNED =
"Salience is relative to the model's prediction of a class. A positive " +
"score (more green) for a token means that token influenced the model to " +
"predict that class, whereas a negaitve score (more pink) means the " +
"token influenced the model to not predict that class.";
"predict that class.";

const LEGEND_INFO_TITLE_UNSIGNED =
"Salience is relative to the model's prediction of a class. A larger " +
Expand Down Expand Up @@ -306,24 +305,23 @@ export class SalienceMapModule extends LitModule {
return html`<img src='${salienceImage}'></img>`;
}

renderColorLegend(colorName: string, colorMap: SalienceCmap,
renderColorLegend(legendLabel: string, colorMap: SalienceCmap,
numBlocks: number) {

function scale(val: number) { return colorMap.bgCmap(val); }
scale.domain = () => colorMap.colorScale.domain();

const tooltipText = legendLabel === 'Signed' ? LEGEND_INFO_TITLE_SIGNED :
LEGEND_INFO_TITLE_UNSIGNED;

return html`
<div class="color-legend-container">
<color-legend legendType=${LegendType.SEQUENTIAL}
selectedColorName=${colorName}
label=${legendLabel}
.paletteTooltipText=${tooltipText}
.scale=${scale}
numBlocks=${numBlocks}>
</color-legend>
<mwc-icon class="icon material-icon-outlined"
title=${colorName === 'Signed' ? LEGEND_INFO_TITLE_SIGNED :
LEGEND_INFO_TITLE_UNSIGNED}>
info_outline
</mwc-icon>
</div>`;
}

Expand Down Expand Up @@ -352,10 +350,11 @@ export class SalienceMapModule extends LitModule {

// reuse the slider from the squence salience module
return html`
<label for="gamma-slider"
title="A larger gamma value makes lower salience tokens more visibile">
Gamma:
</label>
<lit-tooltip .tooltipPosition=${'above'}
.content=${
"A larger gamma value makes lower salience tokens more visible."}>
<label for="gamma-slider" slot="tooltip-anchor">Gamma:</label>
</lit-tooltip>
<lit-slider min="0.25" max="6" step="0.25"
val="${this.cmapGamma}" .onInput=${onChangeGamma}></lit-slider>
<div class="gamma-value">${this.cmapGamma.toFixed(2)}</div>`;
Expand Down
2 changes: 1 addition & 1 deletion lit_nlp/client/modules/scalar_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ export class ScalarModule extends LitModule {
</div>
<div class="module-footer">
<color-legend legendType=${legendType} .scale=${colorOption.scale}
selectedColorName=${colorOption.name}>
label=${colorOption.name}>
</color-legend>
</div>
</div>`;
Expand Down
2 changes: 1 addition & 1 deletion lit_nlp/client/modules/sequence_salience_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ export class SequenceSalienceModule extends LitModule {
// clang-format off
return html`<div class="color-legend-container">
<color-legend legendType=${LegendType.SEQUENTIAL}
selectedColorName=${labelName}
label=${labelName}
?alignRight=${true}
.scale=${scale}
numBlocks=${isSigned ? 7 : 5}>
Expand Down

0 comments on commit bd0f7fc

Please sign in to comment.