Skip to content

HParams: Create filter dialog component #6493

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

Merged
merged 8 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 24 additions & 23 deletions tensorboard/defs/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ load("@npm//@bazel/concatjs:index.bzl", "karma_web_test_suite", "ts_library")
load("@npm//@bazel/esbuild:index.bzl", "esbuild")
load("@npm//@bazel/typescript:index.bzl", "ts_config")


def tensorboard_webcomponent_library(**kwargs):
"""Rules referencing this will be deleted from the codebase soon."""
pass
Expand Down Expand Up @@ -72,8 +71,8 @@ def tf_js_binary(
# the global level and tends to overwrite `window` functions. "iife" is
# just a thin wrapper around "esm" (it adds 11 bytes) and doesn't
# suffer from the same overwriting problem.
format="iife",
minify= False if dev_mode_only else True,
format = "iife",
Copy link
Contributor

Choose a reason for hiding this comment

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

You have unrelated changes here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The observer effect (aka ide autoformat) is alive and strong. Sorry I missed this.

minify = False if dev_mode_only else True,
args = {
# Must specify that 'mjs' extensions are preferred, since that is
# the extension that is used for es2015/esm code generated by
Expand All @@ -91,7 +90,6 @@ def tf_js_binary(
**kwargs
)


def tf_ng_prod_js_binary(
name,
compile,
Expand All @@ -114,7 +112,7 @@ def tf_ng_prod_js_binary(
https://esbuild.github.io/api/ for more details.
"""

app_bundle_name = '%s_app_bundle' % name
app_bundle_name = "%s_app_bundle" % name
app_bundle(
name = app_bundle_name,
**kwargs
Expand All @@ -124,8 +122,8 @@ def tf_ng_prod_js_binary(
# through a terser pass to be the output of this rule.
copy_file(
name = name,
src = '%s.min.js' % app_bundle_name,
out = '%s.js' % name,
src = "%s.min.js" % app_bundle_name,
out = "%s.js" % name,
)

def tf_ts_config(**kwargs):
Expand All @@ -148,22 +146,24 @@ def tf_ts_library(srcs = [], strict_checks = True, **kwargs):
kwargs.setdefault("deps", []).extend(["@npm//tslib", "//tensorboard/defs:strict_types"])

new_srcs = []

# Find test.ts and testbed.ts files and rename to test.spec.ts to be
# compatible with spec_bundle() tooling.
for s in srcs:
if s.endswith("_test.ts") or s.endswith("-test.ts") or s.endswith("_testbed.ts"):
# Make a copy of the file with name .spec.ts and switch to that as
# the src file.
new_src = s[0:s.rindex('.ts')] + ".spec.ts"
copy_file(
name = new_src + '_spec_copy',
src = s,
out = new_src,
allow_symlink = True)
new_srcs.append(new_src)
else:
# Not a test file. Nothing to do here.
new_srcs.append(s)
if s.endswith("_test.ts") or s.endswith("-test.ts") or s.endswith("_testbed.ts"):
# Make a copy of the file with name .spec.ts and switch to that as
# the src file.
new_src = s[0:s.rindex(".ts")] + ".spec.ts"
copy_file(
name = new_src + "_spec_copy",
src = s,
out = new_src,
allow_symlink = True,
)
new_srcs.append(new_src)
else:
# Not a test file. Nothing to do here.
new_srcs.append(s)

ts_library(
srcs = new_srcs,
Expand All @@ -176,7 +176,8 @@ def tf_ts_library(srcs = [], strict_checks = True, **kwargs):
prodmode_target = "es2020",
devmode_target = "es2020",
devmode_module = "esnext",
**kwargs)
**kwargs
)

def tf_ng_web_test_suite(name, deps = [], **kwargs):
"""TensorBoard wrapper for the rule for a Karma web test suite.
Expand Down Expand Up @@ -231,7 +232,7 @@ def tf_ng_web_test_suite(name, deps = [], **kwargs):
# karma_web_test_suite() will rebundle it along with the test framework
# in a CommonJS bundle.
deps = [
"%s_bundle" % name,
"%s_bundle" % name,
],
)

Expand All @@ -256,7 +257,7 @@ def tf_sass_binary(deps = [], include_paths = [], strict_deps = True, **kwargs):
internally.
"""
if (strict_deps):
fail("all tf_sass_binary calls need to have the strict_deps = False override for internal calls");
fail("all tf_sass_binary calls need to have the strict_deps = False override for internal calls")
sass_binary(
deps = deps,
include_paths = include_paths + [
Expand Down
1 change: 1 addition & 0 deletions tensorboard/webapp/hparams/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ tf_ts_library(
deps = [
"//tensorboard/webapp/runs/data_source",
"//tensorboard/webapp/runs/data_source:backend_types",
"//tensorboard/webapp/widgets/data_table:types",
],
)

Expand Down
24 changes: 2 additions & 22 deletions tensorboard/webapp/hparams/_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
import {
HparamValue,
MetricValue,
DiscreteHparamValues,
DomainType,
HparamSpec,
MetricSpec,
} from '../runs/data_source/runs_data_source_types';

export {DiscreteFilter, IntervalFilter} from '../widgets/data_table/types';

export {
DatasetType,
DiscreteHparamValue,
Expand Down Expand Up @@ -50,21 +48,3 @@ export interface HparamAndMetricSpec {
hparams: HparamSpec[];
metrics: MetricSpec[];
}

export interface DiscreteFilter {
type: DomainType.DISCRETE;
includeUndefined: boolean;
possibleValues: DiscreteHparamValues;
// Subset of `possibleValues`
filterValues: DiscreteHparamValues;
}

export interface IntervalFilter {
type: DomainType.INTERVAL;
includeUndefined: boolean;
minValue: number;
maxValue: number;
// Filter values have to be in between min and max values (inclusive).
filterLowerValue: number;
filterUpperValue: number;
}
1 change: 1 addition & 0 deletions tensorboard/webapp/runs/data_source/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ tf_ng_module(
deps = [
":backend_types",
"//tensorboard/webapp/webapp_data_source:http_client",
"//tensorboard/webapp/widgets/data_table:types",
"@npm//@angular/core",
"@npm//rxjs",
],
Expand Down
2 changes: 1 addition & 1 deletion tensorboard/webapp/runs/data_source/runs_data_source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import {
TBHttpClient,
} from '../../webapp_data_source/tb_http_client';
import * as backendTypes from './runs_backend_types';
import {DomainType} from '../../widgets/data_table/types';
import {
Domain,
DomainType,
HparamsAndMetadata,
HparamSpec,
HparamValue,
Expand Down
8 changes: 3 additions & 5 deletions tensorboard/webapp/runs/data_source/runs_data_source_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import {Injectable} from '@angular/core';
import {Observable} from 'rxjs';
import * as backendTypes from './runs_backend_types';

import {DomainType} from '../../widgets/data_table/types';
export {DomainType} from '../../widgets/data_table/types';

export {
BackendHparamsValueType as HparamsValueType,
DatasetType,
Expand All @@ -41,11 +44,6 @@ export interface RunToHparamsAndMetrics {
};
}

export enum DomainType {
DISCRETE,
INTERVAL,
}

interface IntervalDomain {
type: DomainType.INTERVAL;
minValue: number;
Expand Down
40 changes: 40 additions & 0 deletions tensorboard/webapp/widgets/data_table/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ tf_sass_binary(
],
)

tf_sass_binary(
name = "filter_dialog_styles",
src = "filter_dialog_component.scss",
strict_deps = False,
deps = [
"//tensorboard/webapp:angular_material_sass_deps",
"//tensorboard/webapp/theme",
],
)

tf_ng_module(
name = "data_table",
srcs = [
Expand All @@ -71,12 +81,14 @@ tf_ng_module(
deps = [
":column_selector",
":data_table_header",
":filter_dialog",
":types",
"//tensorboard/webapp/angular:expect_angular_material_button",
"//tensorboard/webapp/angular:expect_angular_material_icon",
"//tensorboard/webapp/metrics/views/card_renderer:scalar_card_types",
"//tensorboard/webapp/widgets/custom_modal",
"//tensorboard/webapp/widgets/line_chart_v2/lib:formatter",
"//tensorboard/webapp/widgets/range_input:types",
"@npm//@angular/common",
"@npm//@angular/core",
"@npm//rxjs",
Expand Down Expand Up @@ -123,6 +135,27 @@ tf_ng_module(
],
)

tf_ng_module(
name = "filter_dialog",
srcs = [
"filter_dialog_component.ts",
"filter_dialog_module.ts",
],
assets = [
"filter_dialog_component.ng.html",
":filter_dialog_styles",
],
deps = [
":types",
"//tensorboard/webapp/angular:expect_angular_material_checkbox",
"//tensorboard/webapp/widgets/filter_input",
"//tensorboard/webapp/widgets/range_input",
"//tensorboard/webapp/widgets/range_input:types",
"@npm//@angular/common",
"@npm//@angular/core",
],
)

tf_ts_library(
name = "types",
srcs = [
Expand All @@ -137,16 +170,23 @@ tf_ts_library(
"column_selector_test.ts",
"content_cell_component_test.ts",
"data_table_test.ts",
"filter_dialog_test.ts",
"header_cell_component_test.ts",
],
deps = [
":column_selector",
":data_table",
":filter_dialog",
":types",
"//tensorboard/webapp/angular:expect_angular_cdk_testing",
"//tensorboard/webapp/angular:expect_angular_cdk_testing_testbed",
"//tensorboard/webapp/angular:expect_angular_core_testing",
"//tensorboard/webapp/angular:expect_angular_material_checkbox",
"//tensorboard/webapp/angular:expect_angular_platform_browser_animations",
"//tensorboard/webapp/testing:mat_icon",
"//tensorboard/webapp/widgets/custom_modal",
"//tensorboard/webapp/widgets/range_input",
"//tensorboard/webapp/widgets/range_input:types",
"@npm//@angular/core",
"@npm//@angular/forms",
"@npm//@angular/platform-browser",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!--
@license
Copyright 2023 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<div class="filter-dialog">
<div
*ngIf="filter.type === DomainType.DISCRETE"
class="discrete-filters-area"
>
<tb-filter-input
*ngIf="filter.possibleValues"
[value]="discreteValueFilter"
(keyup)="discreteValueKeyUp($event)"
placeholder="Filter Discrete Values (regex)"
></tb-filter-input>
<div *ngIf="!getPossibleValues().length" class="no-matches">
No Matching Values
</div>
<div
*ngFor="let value of getPossibleValues(); index"
(click)="$event.stopPropagation()"
>
<mat-checkbox
[checked]="filter.filterValues.includes(value)"
(change)="discreteFilterChanged.emit(value)"
><span>{{ value }}</span></mat-checkbox
>
</div>
</div>

<div
*ngIf="filter.type === DomainType.INTERVAL"
(click)="$event.stopPropagation()"
class="range-input-container"
disableRipple
>
<tb-range-input
[min]="filter.minValue"
[max]="filter.maxValue"
[lowerValue]="filter.filterLowerValue"
[upperValue]="filter.filterUpperValue"
(rangeValuesChanged)="intervalFilterChanged.emit($event)"
></tb-range-input>
</div>

<mat-checkbox
[checked]="filter.includeUndefined"
(change)="includeUndefinedToggled.emit()"
>Include Undefined</mat-checkbox
>
</div>
44 changes: 44 additions & 0 deletions tensorboard/webapp/widgets/data_table/filter_dialog_component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* Copyright 2023 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
@use '@angular/material' as mat;
@import 'tensorboard/webapp/theme/tb_theme';

.filter-dialog {
padding: 8px;
border-radius: 4px;
border: 1px solid;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
border-color: mat.get-color-from-palette($tb-foreground, border);
background-color: mat.get-color-from-palette($tb-background, background);

@include tb-dark-theme {
border-color: mat.get-color-from-palette($tb-dark-foreground, border);
background-color: mat.get-color-from-palette(
$tb-dark-background,
'background'
);
}

.discrete-filters-area {
max-height: 100px;
overflow-y: auto;
}

.no-matches {
// 12px is the width of the checkbox so the text should match the
// indentation of the selectable filters.
padding: 8px 12px;
}
}
Loading