Skip to content

Commit fffbf43

Browse files
authored
Merge pull request #1 from tensorflow/master
Let user know which tags are missing per run (tensorflow#967)
2 parents 95aacbc + 4d64e50 commit fffbf43

File tree

1 file changed

+85
-30
lines changed

1 file changed

+85
-30
lines changed

tensorboard/plugins/custom_scalar/tf_custom_scalar_dashboard/tf-custom-scalar-margin-chart-card.html

+85-30
Original file line numberDiff line numberDiff line change
@@ -99,31 +99,47 @@ <h1>[[_titleDisplayString]]</h1>
9999
</template>
100100
</div>
101101

102-
<template is="dom-if" if="[[_tagsWithNoData]]">
103-
<div id="error-content">
104-
<iron-icon class="error-icon" icon="icons:error"></iron-icon>
105-
No data found for these tags:
106-
<ul>
107-
<template is="dom-repeat" items="[[_tagsWithNoData]]">
108-
<li>[[item]]</li>
109-
</template>
110-
</ul>
111-
<br>
112-
Tags for the value, lower, and upper bounds of margin charts in the Layout
113-
proto must match tags in the SCALARS dashboard.
102+
<!-- here -->
103+
<template is="dom-if" if="[[_missingTags.length]]">
104+
<div class="collapsible-list-title">
105+
<paper-icon-button
106+
icon="[[_getToggleCollapsibleIcon(_missingTagsCollapsibleOpened)]]"
107+
on-click="_toggleMissingTagsCollapsibleOpen"
108+
class="toggle-collapsible-button">
109+
</paper-icon-button>
110+
<span class="collapsible-title-text">
111+
<iron-icon icon="icons:error"></iron-icon> Missing Tags
112+
</span>
114113
</div>
114+
<iron-collapse opened="[[_missingTagsCollapsibleOpened]]">
115+
<div class="error-content">
116+
<iron-icon class="error-icon" icon="icons:error"></iron-icon>
117+
<template is="dom-repeat"
118+
items="[[_missingTags]]"
119+
as="missingEntry">
120+
<div class="missing-tags-for-run-container">
121+
Run "[[missingEntry.run]]" lacks data for tags
122+
<ul>
123+
<template is="dom-repeat" items="[[missingEntry.tags]]" as="tag">
124+
<li>[[tag]]</li>
125+
</template>
126+
</ul>
127+
</div>
128+
</template>
129+
</div>
130+
</iron-collapse>
115131
</template>
116132

117133
<template is="dom-if" if="[[_tagFilterInvalid]]">
118-
<div id="error-content">
134+
<div class="error-content">
119135
<iron-icon class="error-icon" icon="icons:error"></iron-icon>
120136
This regular expresion is invalid:<br>
121137
<span class="invalid-regex">[[_tagFilter]]</span>
122138
</div>
123139
</template>
124140

125141
<template is="dom-if" if="[[_stepsMismatch]]">
126-
<div id="error-content">
142+
<div class="error-content">
127143
<iron-icon class="error-icon" icon="icons:error"></iron-icon>
128144
The steps for value, lower, and upper tags do not match:
129145
<ul>
@@ -144,16 +160,16 @@ <h1>[[_titleDisplayString]]</h1>
144160
</template>
145161

146162
<div id="matches-container">
147-
<div id="matches-list-title">
163+
<div class="collapsible-list-title">
148164
<template is="dom-if" if="[[_dataSeriesStrings.length]]">
149165
<paper-icon-button
150-
icon="[[_getToggleMatchesIcon(_matchesListOpened)]]"
166+
icon="[[_getToggleCollapsibleIcon(_matchesListOpened)]]"
151167
on-click="_toggleMatchesOpen"
152168
class="toggle-matches-button">
153169
</paper-icon-button>
154170
</template>
155171

156-
<span class="matches-text">
172+
<span class="collapsible-title-text">
157173
Matches ([[_dataSeriesStrings.length]])
158174
</span>
159175
</div>
@@ -179,7 +195,7 @@ <h1>[[_titleDisplayString]]</h1>
179195
</div>
180196
<style include="tf-custom-scalar-card-style"></style>
181197
<style>
182-
#error-content {
198+
.error-content {
183199
background: #f00;
184200
border-radius: 5px;
185201
color: #fff;
@@ -197,7 +213,7 @@ <h1>[[_titleDisplayString]]</h1>
197213
font-weight: bold;
198214
}
199215

200-
#error-content ul {
216+
.error-content ul {
201217
margin: 1px 0 0 0;
202218
padding: 0 0 0 19px;
203219
}
@@ -206,10 +222,14 @@ <h1>[[_titleDisplayString]]</h1>
206222
font-weight: bold;
207223
}
208224

209-
#matches-list-title {
225+
.collapsible-list-title {
210226
margin: 10px 0 5px 0;
211227
}
212228

229+
.collapsible-title-text {
230+
vertical-align: middle;
231+
}
232+
213233
#matches-list {
214234
font-size: 0.8em;
215235
max-height: 200px;
@@ -226,8 +246,8 @@ <h1>[[_titleDisplayString]]</h1>
226246
width: 10px;
227247
}
228248

229-
.matches-text {
230-
vertical-align: middle;
249+
.missing-tags-for-run-container {
250+
margin: 8px 0 0 0;
231251
}
232252
</style>
233253
</template>
@@ -381,7 +401,22 @@ <h1>[[_titleDisplayString]]</h1>
381401
];
382402
}
383403
},
384-
_tagsWithNoData: String,
404+
/**
405+
* A list of objects encapsulating missing tags. Each object within this
406+
* list has the following properties:
407+
* run: A string denoting the relevant run.
408+
* tags: A non-empty list of tags (strings) missing for that run.
409+
* A run only has an entry in this list if some (but not all) of its 3
410+
* tags (value, lower, upper) are missing.
411+
*/
412+
_missingTags: {
413+
type: Array,
414+
value: [],
415+
},
416+
_missingTagsCollapsibleOpened: {
417+
type: Boolean,
418+
value: false,
419+
},
385420
/**
386421
* This field is only set if data retrieved from the server exhibits a
387422
* step mismatch: if the lists of values, lower bounds, and upper bounds
@@ -517,13 +552,28 @@ <h1>[[_titleDisplayString]]</h1>
517552
run, tagsObject.value, seriesName, dataPoints);
518553
}
519554
});
555+
this.set('_nameToDataSeries', newMapping);
520556

521-
if (tagsNotFound.length) {
522-
// At least 1 tag could not be found. Show an error message.
523-
this.set('_tagsWithNoData', tagsNotFound);
557+
const entryIndex = _.findIndex(this._missingTags, (entry) => {
558+
return entry.run === run;
559+
});
560+
if (tagsNotFound.length && tagsNotFound.length != 3) {
561+
// Some but not all tags were found. Show a warning message.
562+
const entry = {
563+
run: run,
564+
tags: tagsNotFound,
565+
};
566+
if (entryIndex >= 0) {
567+
// Remove the previous entry. Insert the new one.
568+
this.splice('_missingTags', entryIndex, 1, entry);
569+
} else {
570+
// Insert a new entry.
571+
this.push('_missingTags', entry);
572+
}
573+
} else if (entryIndex >= 0) {
574+
// Remove the previous entry if it exists.
575+
this.splice('_missingTags', entryIndex, 1);
524576
}
525-
526-
this.set('_nameToDataSeries', newMapping);
527577
});
528578
},
529579
_findStepMismatch(tagsObject, valueSteps, lowerSteps, upperSteps) {
@@ -606,8 +656,8 @@ <h1>[[_titleDisplayString]]</h1>
606656
_escapeRegexCharacters(stringValue) {
607657
return stringValue.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
608658
},
609-
_getToggleMatchesIcon(matchesListOpened) {
610-
return matchesListOpened ? 'expand-less' : 'expand-more';
659+
_getToggleCollapsibleIcon(listOpened) {
660+
return listOpened ? 'expand-less' : 'expand-more';
611661
},
612662
_toggleMatchesOpen() {
613663
this.set('_matchesListOpened', !this._matchesListOpened);
@@ -620,6 +670,11 @@ <h1>[[_titleDisplayString]]</h1>
620670
_separateWithCommas(numbers) {
621671
return numbers.join(', ');
622672
},
673+
_toggleMissingTagsCollapsibleOpen() {
674+
this.set(
675+
'_missingTagsCollapsibleOpened',
676+
!this._missingTagsCollapsibleOpened);
677+
},
623678
});
624679
</script>
625680
</dom-module>

0 commit comments

Comments
 (0)