diff --git a/tensorboard/webapp/metrics/BUILD b/tensorboard/webapp/metrics/BUILD index 603556cce1..ddf5208910 100644 --- a/tensorboard/webapp/metrics/BUILD +++ b/tensorboard/webapp/metrics/BUILD @@ -35,7 +35,6 @@ tf_ts_library( ], deps = [ ":internal_types", - "//tensorboard/webapp/metrics/store:types", ], ) diff --git a/tensorboard/webapp/metrics/actions/BUILD b/tensorboard/webapp/metrics/actions/BUILD index eb45146603..873f281de0 100644 --- a/tensorboard/webapp/metrics/actions/BUILD +++ b/tensorboard/webapp/metrics/actions/BUILD @@ -10,7 +10,7 @@ tf_ts_library( "index.ts", ], deps = [ - "//tensorboard/webapp/metrics:internal_types", + "//tensorboard/webapp/metrics:types", "//tensorboard/webapp/metrics/data_source", "//tensorboard/webapp/metrics/views/card_renderer:scalar_card_types", "//tensorboard/webapp/util:dom", diff --git a/tensorboard/webapp/metrics/actions/index.ts b/tensorboard/webapp/metrics/actions/index.ts index 594ba6fdd2..8edd99aa9a 100644 --- a/tensorboard/webapp/metrics/actions/index.ts +++ b/tensorboard/webapp/metrics/actions/index.ts @@ -29,7 +29,7 @@ import { PluginType, TooltipSort, XAxisType, -} from '../internal_types'; +} from '../types'; import { ColumnHeader, SortingInfo, diff --git a/tensorboard/webapp/metrics/internal_types.ts b/tensorboard/webapp/metrics/internal_types.ts index 0df0f47e0c..ccec830d21 100644 --- a/tensorboard/webapp/metrics/internal_types.ts +++ b/tensorboard/webapp/metrics/internal_types.ts @@ -23,18 +23,6 @@ export enum PluginType { IMAGES = 'images', } -// When adding a new value to the enum, please implement the deserializer on -// data_source/metrics_data_source.ts. -// When editing a value of the enum, please write a backward compatible -// deserializer in data_source/metrics_data_source.ts. -export enum TooltipSort { - DEFAULT = 'default', - ALPHABETICAL = 'alphabetical', - ASCENDING = 'ascending', - DESCENDING = 'descending', - NEAREST = 'nearest', -} - export enum XAxisType { STEP, RELATIVE, diff --git a/tensorboard/webapp/metrics/metrics_module.ts b/tensorboard/webapp/metrics/metrics_module.ts index bd80c8ac42..bac6530cd0 100644 --- a/tensorboard/webapp/metrics/metrics_module.ts +++ b/tensorboard/webapp/metrics/metrics_module.ts @@ -83,7 +83,7 @@ export function getMetricsIgnoreOutliersSettingFactory() { export function getMetricsTooltipSortSettingFactory() { return createSelector(getMetricsTooltipSort, (tooltipSort) => { - return {tooltipSortString: String(tooltipSort)}; + return {tooltipSort: String(tooltipSort)}; }); } diff --git a/tensorboard/webapp/metrics/store/BUILD b/tensorboard/webapp/metrics/store/BUILD index d627a40e1f..957a12812c 100644 --- a/tensorboard/webapp/metrics/store/BUILD +++ b/tensorboard/webapp/metrics/store/BUILD @@ -18,7 +18,7 @@ tf_ts_library( "//tensorboard/webapp/app_routing:types", "//tensorboard/webapp/app_routing/actions", "//tensorboard/webapp/core/actions", - "//tensorboard/webapp/metrics:internal_types", + "//tensorboard/webapp/metrics:types", "//tensorboard/webapp/metrics:utils", "//tensorboard/webapp/metrics/actions", "//tensorboard/webapp/metrics/data_source", @@ -68,7 +68,7 @@ tf_ts_library( ], deps = [ "//tensorboard/webapp/app_routing:namespaced_state_reducer_helper", - "//tensorboard/webapp/metrics:internal_types", + "//tensorboard/webapp/metrics:types", "//tensorboard/webapp/metrics/data_source", "//tensorboard/webapp/metrics/views/card_renderer:scalar_card_types", "//tensorboard/webapp/types", @@ -92,8 +92,8 @@ tf_ts_library( "//tensorboard/webapp/app_routing:types", "//tensorboard/webapp/app_routing/actions", "//tensorboard/webapp/core/actions", - "//tensorboard/webapp/metrics:internal_types", "//tensorboard/webapp/metrics:test_lib", + "//tensorboard/webapp/metrics:types", "//tensorboard/webapp/metrics/actions", "//tensorboard/webapp/metrics/data_source", "//tensorboard/webapp/persistent_settings", diff --git a/tensorboard/webapp/metrics/store/metrics_reducers.ts b/tensorboard/webapp/metrics/store/metrics_reducers.ts index 760ef90215..092747afa6 100644 --- a/tensorboard/webapp/metrics/store/metrics_reducers.ts +++ b/tensorboard/webapp/metrics/store/metrics_reducers.ts @@ -44,7 +44,7 @@ import { SCALARS_SMOOTHING_MIN, TooltipSort, URLDeserializedState, -} from '../internal_types'; +} from '../types'; import {groupCardIdWithMetdata} from '../utils'; import {ColumnHeaderType} from '../views/card_renderer/scalar_card_types'; import { @@ -426,23 +426,11 @@ const reducer = createReducer( }), on(globalSettingsLoaded, (state, {partialSettings}) => { const metricsSettings: Partial = {}; - if (partialSettings.tooltipSortString) { - switch (partialSettings.tooltipSortString) { - case TooltipSort.DEFAULT: - case TooltipSort.ALPHABETICAL: - metricsSettings.tooltipSort = TooltipSort.ALPHABETICAL; - break; - case TooltipSort.ASCENDING: - metricsSettings.tooltipSort = TooltipSort.ASCENDING; - break; - case TooltipSort.DESCENDING: - metricsSettings.tooltipSort = TooltipSort.DESCENDING; - break; - case TooltipSort.NEAREST: - metricsSettings.tooltipSort = TooltipSort.NEAREST; - break; - default: - } + if ( + partialSettings.tooltipSort && + Object.values(TooltipSort).includes(partialSettings.tooltipSort) + ) { + metricsSettings.tooltipSort = partialSettings.tooltipSort; } if (typeof partialSettings.timeSeriesCardMinWidth === 'number') { metricsSettings.cardMinWidth = partialSettings.timeSeriesCardMinWidth; diff --git a/tensorboard/webapp/metrics/store/metrics_reducers_test.ts b/tensorboard/webapp/metrics/store/metrics_reducers_test.ts index efbca27cf7..f3990a2285 100644 --- a/tensorboard/webapp/metrics/store/metrics_reducers_test.ts +++ b/tensorboard/webapp/metrics/store/metrics_reducers_test.ts @@ -26,13 +26,6 @@ import { ScalarStepDatum, TagMetadata as DataSourceTagMetadata, } from '../data_source'; -import { - CardId, - CardMetadata, - HistogramMode, - TooltipSort, - XAxisType, -} from '../internal_types'; import { buildDataSourceTagMetadata, buildMetricsSettingsState, @@ -46,6 +39,13 @@ import { createScalarStepData, createTimeSeriesData, } from '../testing'; +import { + CardId, + CardMetadata, + HistogramMode, + TooltipSort, + XAxisType, +} from '../types'; import {reducers} from './metrics_reducers'; import {getCardId, getPinnedCardId} from './metrics_store_internal_utils'; import { @@ -2359,7 +2359,7 @@ describe('metrics reducers', () => { globalSettingsLoaded({ partialSettings: { ignoreOutliers: true, - tooltipSortString: 'descending', + tooltipSort: TooltipSort.DESCENDING, }, }) ); @@ -2387,7 +2387,7 @@ describe('metrics reducers', () => { beforeState, globalSettingsLoaded({ partialSettings: { - tooltipSortString: 'yo', + tooltipSort: 'yo' as TooltipSort, }, }) ); diff --git a/tensorboard/webapp/metrics/store/metrics_selectors.ts b/tensorboard/webapp/metrics/store/metrics_selectors.ts index 4378309d46..3cd02061ac 100644 --- a/tensorboard/webapp/metrics/store/metrics_selectors.ts +++ b/tensorboard/webapp/metrics/store/metrics_selectors.ts @@ -29,7 +29,7 @@ import { TimeSelection, TooltipSort, XAxisType, -} from '../internal_types'; +} from '../types'; import {ColumnHeader} from '../views/card_renderer/scalar_card_types'; import * as storeUtils from './metrics_store_internal_utils'; import { diff --git a/tensorboard/webapp/metrics/store/metrics_selectors_test.ts b/tensorboard/webapp/metrics/store/metrics_selectors_test.ts index 6abdc96765..e0eae51bb7 100644 --- a/tensorboard/webapp/metrics/store/metrics_selectors_test.ts +++ b/tensorboard/webapp/metrics/store/metrics_selectors_test.ts @@ -15,7 +15,6 @@ limitations under the License. import {DataLoadState} from '../../types/data'; import {nextElementId} from '../../util/dom'; import {PluginType} from '../data_source'; -import {HistogramMode, TooltipSort, XAxisType} from '../internal_types'; import { appStateFromMetricsState, buildMetricsSettingsState, @@ -26,6 +25,7 @@ import { createScalarStepData, createTimeSeriesData, } from '../testing'; +import {HistogramMode, TooltipSort, XAxisType} from '../types'; import * as selectors from './metrics_selectors'; describe('metrics selectors', () => { diff --git a/tensorboard/webapp/metrics/store/metrics_types.ts b/tensorboard/webapp/metrics/store/metrics_types.ts index 90cefbf70b..88f73c1bb1 100644 --- a/tensorboard/webapp/metrics/store/metrics_types.ts +++ b/tensorboard/webapp/metrics/store/metrics_types.ts @@ -35,7 +35,7 @@ import { TimeSelection, TooltipSort, XAxisType, -} from '../internal_types'; +} from '../types'; import {ColumnHeader} from '../views/card_renderer/scalar_card_types'; export const METRICS_FEATURE_KEY = 'metrics'; diff --git a/tensorboard/webapp/metrics/types.ts b/tensorboard/webapp/metrics/types.ts index bc2af3751a..350694ef8d 100644 --- a/tensorboard/webapp/metrics/types.ts +++ b/tensorboard/webapp/metrics/types.ts @@ -13,3 +13,16 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ export * from './internal_types'; + +// When adding a new value to the enum, please implement the deserializer on +// data_source/metrics_data_source.ts. +// When editing a value of the enum, please write a backward compatible +// deserializer in tensorboard/webapp/metrics/store/metrics_reducers.ts +export enum TooltipSort { + DEFAULT = 'default', + ALPHABETICAL = 'alphabetical', + ASCENDING = 'ascending', + DESCENDING = 'descending', + NEAREST = 'nearest', + NEAREST_Y = 'nearest_Y', +} diff --git a/tensorboard/webapp/metrics/views/card_renderer/scalar_card_component.ng.html b/tensorboard/webapp/metrics/views/card_renderer/scalar_card_component.ng.html index 9a44004c0c..814e03a266 100644 --- a/tensorboard/webapp/metrics/views/card_renderer/scalar_card_component.ng.html +++ b/tensorboard/webapp/metrics/views/card_renderer/scalar_card_component.ng.html @@ -119,7 +119,8 @@ @@ -136,7 +137,8 @@ @@ -153,14 +155,15 @@ >{{ datum.metadata.displayName }} - + - - + + diff --git a/tensorboard/webapp/metrics/views/card_renderer/scalar_card_component.ts b/tensorboard/webapp/metrics/views/card_renderer/scalar_card_component.ts index 97400854aa..420c208bfd 100644 --- a/tensorboard/webapp/metrics/views/card_renderer/scalar_card_component.ts +++ b/tensorboard/webapp/metrics/views/card_renderer/scalar_card_component.ts @@ -58,7 +58,6 @@ import {TimeSelectionView} from './utils'; type ScalarTooltipDatum = TooltipDatum< ScalarCardSeriesMetadata & { - distSqToCursor: number; closest: boolean; } >; @@ -163,7 +162,8 @@ export class ScalarCardComponent { getCursorAwareTooltipData( tooltipData: TooltipDatum[], - cursorLoc: {x: number; y: number} + cursorLocationInDataCoord: {x: number; y: number}, + cursorLocation: {x: number; y: number} ): ScalarTooltipDatum[] { const scalarTooltipData = tooltipData.map((datum) => { return { @@ -171,10 +171,12 @@ export class ScalarCardComponent { metadata: { ...datum.metadata, closest: false, - distSqToCursor: Math.hypot( - datum.point.x - cursorLoc.x, - datum.point.y - cursorLoc.y + distToCursorPixels: Math.hypot( + datum.domPoint.x - cursorLocation.x, + datum.domPoint.y - cursorLocation.y ), + distToCursorX: datum.dataPoint.x - cursorLocationInDataCoord.x, + distToCursorY: datum.dataPoint.y - cursorLocationInDataCoord.y, }, }; }); @@ -182,8 +184,8 @@ export class ScalarCardComponent { let minDist = Infinity; let minIndex = 0; for (let index = 0; index < scalarTooltipData.length; index++) { - if (minDist > scalarTooltipData[index].metadata.distSqToCursor) { - minDist = scalarTooltipData[index].metadata.distSqToCursor; + if (minDist > scalarTooltipData[index].metadata.distToCursorPixels) { + minDist = scalarTooltipData[index].metadata.distToCursorPixels; minIndex = index; } } @@ -194,12 +196,16 @@ export class ScalarCardComponent { switch (this.tooltipSort) { case TooltipSort.ASCENDING: - return scalarTooltipData.sort((a, b) => a.point.y - b.point.y); + return scalarTooltipData.sort((a, b) => a.dataPoint.y - b.dataPoint.y); case TooltipSort.DESCENDING: - return scalarTooltipData.sort((a, b) => b.point.y - a.point.y); + return scalarTooltipData.sort((a, b) => b.dataPoint.y - a.dataPoint.y); case TooltipSort.NEAREST: return scalarTooltipData.sort((a, b) => { - return a.metadata.distSqToCursor - b.metadata.distSqToCursor; + return a.metadata.distToCursorPixels - b.metadata.distToCursorPixels; + }); + case TooltipSort.NEAREST_Y: + return scalarTooltipData.sort((a, b) => { + return a.metadata.distToCursorY - b.metadata.distToCursorY; }); case TooltipSort.DEFAULT: case TooltipSort.ALPHABETICAL: diff --git a/tensorboard/webapp/metrics/views/card_renderer/scalar_card_test.ts b/tensorboard/webapp/metrics/views/card_renderer/scalar_card_test.ts index 1d2d0612b1..db4c71e386 100644 --- a/tensorboard/webapp/metrics/views/card_renderer/scalar_card_test.ts +++ b/tensorboard/webapp/metrics/views/card_renderer/scalar_card_test.ts @@ -67,6 +67,7 @@ import { import { DataSeries, DataSeriesMetadataMap, + Point, RendererType, ScaleType, TooltipDatum, @@ -115,7 +116,8 @@ import {VisLinkedTimeSelectionWarningModule} from './vis_linked_time_selection_w [ngTemplateOutlet]="tooltipTemplate" [ngTemplateOutletContext]="{ data: tooltipDataForTesting, - cursorLocationInDataCoord: cursorLocForTesting + cursorLocationInDataCoord: cursorLocationInDataCoordForTesting, + cursorLocation: cursorLocationForTesting }" > (); - // This input does not exist on real line-chart and is devised to make tooltipTemplate + // These inputs do not exist on the real line-chart and is devised to make tooltipTemplate // testable without using the real implementation. @Input() tooltipDataForTesting: TooltipDatum[] = []; - @Input() cursorLocForTesting: {x: number; y: number} = {x: 0, y: 0}; + @Input() cursorLocationInDataCoordForTesting: {x: number; y: number} = { + x: 0, + y: 0, + }; + @Input() cursorLocationForTesting: {x: number; y: number} = {x: 0, y: 0}; private isViewBoxOverridden = new ReplaySubject(1); @@ -1142,7 +1148,8 @@ describe('scalar card', () => { describe('tooltip', () => { function buildTooltipDatum( metadata?: ScalarCardSeriesMetadata, - point: Partial = {} + dataPoint: Partial = {}, + domPoint: Point = {x: 0, y: 0} ): TooltipDatum { return { id: metadata?.id ?? 'a', @@ -1156,15 +1163,16 @@ describe('scalar card', () => { ...metadata, }, closestPointIndex: 0, - point: { + dataPoint: { x: 0, y: 0, value: 0, step: 0, wallTime: 0, relativeTimeInMs: 0, - ...point, + ...dataPoint, }, + domPoint, }; } @@ -1180,11 +1188,17 @@ describe('scalar card', () => { function setCursorLocation( fixture: ComponentFixture, - cursorLocInDataCoord?: {x: number; y: number} + dataPoint?: {x: number; y: number}, + domPoint?: Point ) { const lineChart = fixture.debugElement.query(Selector.LINE_CHART); - lineChart.componentInstance.cursorLocForTesting = cursorLocInDataCoord; + if (dataPoint) { + lineChart.componentInstance.dataPointForTesting = dataPoint; + } + if (domPoint) { + lineChart.componentInstance.cursorLocationForTesting = domPoint; + } lineChart.componentInstance.changeDetectorRef.markForCheck(); } @@ -1616,6 +1630,10 @@ describe('scalar card', () => { y: 1000, value: 1000, wallTime: new Date('2020-01-01').getTime(), + }, + { + x: 0, + y: 100, } ), buildTooltipDatum( @@ -1634,6 +1652,10 @@ describe('scalar card', () => { y: -500, value: -500, wallTime: new Date('2020-12-31').getTime(), + }, + { + x: 50, + y: 0, } ), buildTooltipDatum( @@ -1652,10 +1674,14 @@ describe('scalar card', () => { y: 3, value: 3, wallTime: new Date('2021-01-01').getTime(), + }, + { + x: 1000, + y: 30, } ), ]); - setCursorLocation(fixture, {x: 500, y: -100}); + setCursorLocation(fixture, {x: 500, y: -100}, {x: 50, y: 0}); fixture.detectChanges(); assertTooltipRows(fixture, [ ['', 'Row 2', '-500', '1,000', anyString, anyString], @@ -1663,7 +1689,7 @@ describe('scalar card', () => { ['', 'Row 3', '3', '10,000', anyString, anyString], ]); - setCursorLocation(fixture, {x: 500, y: 600}); + setCursorLocation(fixture, {x: 500, y: 600}, {x: 50, y: 80}); fixture.detectChanges(); assertTooltipRows(fixture, [ ['', 'Row 1', '1000', '0', anyString, anyString], @@ -1671,7 +1697,7 @@ describe('scalar card', () => { ['', 'Row 3', '3', '10,000', anyString, anyString], ]); - setCursorLocation(fixture, {x: 10000, y: -100}); + setCursorLocation(fixture, {x: 10000, y: -100}, {x: 1000, y: 20}); fixture.detectChanges(); assertTooltipRows(fixture, [ ['', 'Row 3', '3', '10,000', anyString, anyString], @@ -1680,7 +1706,7 @@ describe('scalar card', () => { ]); // Right between row 1 and row 2. When tied, original order is used. - setCursorLocation(fixture, {x: 500, y: 250}); + setCursorLocation(fixture, {x: 500, y: 250}, {x: 25, y: 50}); fixture.detectChanges(); assertTooltipRows(fixture, [ ['', 'Row 1', '1000', '0', anyString, anyString], diff --git a/tensorboard/webapp/metrics/views/right_pane/settings_view_component.ts b/tensorboard/webapp/metrics/views/right_pane/settings_view_component.ts index c3ca9cc252..a212f05a75 100644 --- a/tensorboard/webapp/metrics/views/right_pane/settings_view_component.ts +++ b/tensorboard/webapp/metrics/views/right_pane/settings_view_component.ts @@ -86,7 +86,8 @@ export class SettingsViewComponent { {value: TooltipSort.ALPHABETICAL, displayText: 'Alphabetical'}, {value: TooltipSort.ASCENDING, displayText: 'Ascending'}, {value: TooltipSort.DESCENDING, displayText: 'Descending'}, - {value: TooltipSort.NEAREST, displayText: 'Nearest'}, + {value: TooltipSort.NEAREST, displayText: 'Nearest Pixel'}, + {value: TooltipSort.NEAREST_Y, displayText: 'Nearest Y'}, ]; @Input() tooltipSort!: TooltipSort; @Output() tooltipSortChanged = new EventEmitter(); diff --git a/tensorboard/webapp/persistent_settings/_data_source/BUILD b/tensorboard/webapp/persistent_settings/_data_source/BUILD index 152c8b6369..5dc7515fc8 100644 --- a/tensorboard/webapp/persistent_settings/_data_source/BUILD +++ b/tensorboard/webapp/persistent_settings/_data_source/BUILD @@ -10,6 +10,7 @@ tf_ng_module( ], deps = [ ":types", + "//tensorboard/webapp/metrics:types", "@npm//@angular/core", "@npm//@ngrx/store", "@npm//rxjs", @@ -21,6 +22,9 @@ tf_ng_module( srcs = [ "types.ts", ], + deps = [ + "//tensorboard/webapp/metrics:types", + ], ) tf_ng_module( @@ -48,6 +52,7 @@ tf_ng_module( ":_data_source", ":types", "//tensorboard/webapp/angular:expect_angular_core_testing", + "//tensorboard/webapp/metrics:types", "@npm//@angular/core", "@npm//@types/jasmine", "@npm//rxjs", diff --git a/tensorboard/webapp/persistent_settings/_data_source/persistent_settings_data_source.ts b/tensorboard/webapp/persistent_settings/_data_source/persistent_settings_data_source.ts index 0ee706328f..99417fb3d9 100644 --- a/tensorboard/webapp/persistent_settings/_data_source/persistent_settings_data_source.ts +++ b/tensorboard/webapp/persistent_settings/_data_source/persistent_settings_data_source.ts @@ -51,10 +51,10 @@ export class OSSSettingsConverter extends SettingsConverter< if (settings.scalarSmoothing !== undefined) { serializableSettings.scalarSmoothing = settings.scalarSmoothing; } - if (settings.tooltipSortString !== undefined) { + if (settings.tooltipSort !== undefined) { // TooltipSort is a string enum and has string values; no need to // serialize it differently to account for their unintended changes. - serializableSettings.tooltipSort = settings.tooltipSortString; + serializableSettings.tooltipSort = settings.tooltipSort; } if (settings.autoReload !== undefined) { serializableSettings.autoReload = settings.autoReload; @@ -117,7 +117,7 @@ export class OSSSettingsConverter extends SettingsConverter< backendSettings.hasOwnProperty('tooltipSort') && typeof backendSettings.tooltipSort === 'string' ) { - settings.tooltipSortString = backendSettings.tooltipSort; + settings.tooltipSort = backendSettings.tooltipSort; } if ( diff --git a/tensorboard/webapp/persistent_settings/_data_source/persistent_settings_data_source_test.ts b/tensorboard/webapp/persistent_settings/_data_source/persistent_settings_data_source_test.ts index 5cda2e2c36..caf77bcef3 100644 --- a/tensorboard/webapp/persistent_settings/_data_source/persistent_settings_data_source_test.ts +++ b/tensorboard/webapp/persistent_settings/_data_source/persistent_settings_data_source_test.ts @@ -15,6 +15,7 @@ limitations under the License. import {Injectable} from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {firstValueFrom} from 'rxjs'; +import {TooltipSort} from '../../metrics/types'; import { OSSSettingsConverter, PersistentSettingsDataSourceImpl, @@ -289,7 +290,7 @@ describe('persistent_settings data_source test', () => { expect(actual).toEqual({ scalarSmoothing: 0.3, - tooltipSortString: 'ascending', + tooltipSort: 'ascending' as TooltipSort, notificationLastReadTimeInMs: 3, }); }); @@ -311,7 +312,7 @@ describe('persistent_settings data_source test', () => { expect(actual).toEqual({ scalarSmoothing: 0.5, - tooltipSortString: 'default', + tooltipSort: TooltipSort.DEFAULT, notificationLastReadTimeInMs: 100, }); }); diff --git a/tensorboard/webapp/persistent_settings/_data_source/types.ts b/tensorboard/webapp/persistent_settings/_data_source/types.ts index 3df55ef954..2a9d1a4aaa 100644 --- a/tensorboard/webapp/persistent_settings/_data_source/types.ts +++ b/tensorboard/webapp/persistent_settings/_data_source/types.ts @@ -13,6 +13,8 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ +import {TooltipSort} from '../../metrics/types'; + export enum ThemeValue { BROWSER_DEFAULT = 'browser_default', LIGHT = 'light', @@ -28,7 +30,7 @@ export enum ThemeValue { */ export declare interface BackendSettings { scalarSmoothing?: number; - tooltipSort?: string; + tooltipSort?: TooltipSort; ignoreOutliers?: boolean; autoReload?: boolean; autoReloadPeriodInMs?: number; @@ -50,7 +52,7 @@ export declare interface BackendSettings { */ export interface PersistableSettings { scalarSmoothing?: number; - tooltipSortString?: string; + tooltipSort?: TooltipSort; ignoreOutliers?: boolean; autoReload?: boolean; autoReloadPeriodInMs?: number; diff --git a/tensorboard/webapp/widgets/line_chart_v2/sub_view/line_chart_interactive_view.ng.html b/tensorboard/webapp/widgets/line_chart_v2/sub_view/line_chart_interactive_view.ng.html index c184103159..bc451ed4f8 100644 --- a/tensorboard/webapp/widgets/line_chart_v2/sub_view/line_chart_interactive_view.ng.html +++ b/tensorboard/webapp/widgets/line_chart_v2/sub_view/line_chart_interactive_view.ng.html @@ -26,9 +26,9 @@ *ngFor="let datum of cursoredData; trackBy: trackBySeriesName" > @@ -67,7 +67,8 @@ [ngTemplateOutlet]="tooltipTemplate ? tooltipTemplate : defaultTooltip" [ngTemplateOutletContext]="{ data: cursoredData, - cursorLocationInDataCoord: cursorLocationInDataCoord + cursorLocationInDataCoord: cursorLocationInDataCoord, + cursorLocation: cursorLocation }" > @@ -92,8 +93,8 @@ - - + + diff --git a/tensorboard/webapp/widgets/line_chart_v2/sub_view/line_chart_interactive_view.ts b/tensorboard/webapp/widgets/line_chart_v2/sub_view/line_chart_interactive_view.ts index 460c4c4035..5d3eebaa2e 100644 --- a/tensorboard/webapp/widgets/line_chart_v2/sub_view/line_chart_interactive_view.ts +++ b/tensorboard/webapp/widgets/line_chart_v2/sub_view/line_chart_interactive_view.ts @@ -67,7 +67,8 @@ export interface TooltipDatum< id: string; metadata: Metadata; closestPointIndex: number; - point: PointDatum; + dataPoint: PointDatum; + domPoint: Point; } const SCROLL_ZOOM_SPEED_FACTOR = 0.01; @@ -202,6 +203,7 @@ export class LineChartInteractiveViewComponent ]; cursorLocationInDataCoord: {x: number; y: number} | null = null; + cursorLocation: {x: number; y: number} | null = null; cursoredData: TooltipDatum[] = []; tooltipDisplayAttached: boolean = false; @@ -522,6 +524,10 @@ export class LineChartInteractiveViewComponent x: this.getDataX(event.offsetX), y: this.getDataY(event.offsetY), }; + this.cursorLocation = { + x: event.offsetX, + y: event.offsetY, + }; this.updateCursoredDataAndTooltipVisibility(); } @@ -550,10 +556,15 @@ export class LineChartInteractiveViewComponent }) .map(({seriesDatum, metadata}) => { const index = findClosestIndex(seriesDatum.points, cursorLoc.x); + const dataPoint = seriesDatum.points[index]; return { id: seriesDatum.id, closestPointIndex: index, - point: seriesDatum.points[index], + dataPoint, + domPoint: { + x: this.getDomX(dataPoint.x), + y: this.getDomY(dataPoint.y), + }, metadata, }; })
- {{ valueFormatter.formatShort(datum.point.y) }} + {{ valueFormatter.formatShort(datum.dataPoint.y) }} {{ valueFormatter.formatShort(datum.point.value) }}{{ valueFormatter.formatShort(datum.dataPoint.value) }} {{ stepFormatter.formatShort(datum.point.step) }}{{ datum.point.wallTime | date: 'short' }}{{ stepFormatter.formatShort(datum.dataPoint.step) }}{{ datum.dataPoint.wallTime | date: 'short' }} - {{ relativeXFormatter.formatReadable(datum.point.relativeTimeInMs) + {{ + relativeXFormatter.formatReadable(datum.dataPoint.relativeTimeInMs) }}
{{ datum.metadata.displayName }}{{ datum.point.y }}{{ datum.point.x }}{{ datum.dataPoint.y }}{{ datum.dataPoint.x }}