Only make 1 collapsible for each run.
Previously, we could possibly make several collapsibles for each run because of how tag names were broken up. Change: 155305237
This commit is contained in:
parent
24a61445f4
commit
1968b8b3f9
@ -46,6 +46,7 @@ tensorboard_typescript_genrule(
|
|||||||
],
|
],
|
||||||
typings = [
|
typings = [
|
||||||
"@org_definitelytyped//:d3.d.ts",
|
"@org_definitelytyped//:d3.d.ts",
|
||||||
|
"@org_definitelytyped//:lodash.d.ts",
|
||||||
"//tensorflow/tensorboard/components/vz_sorting:ts_typings",
|
"//tensorflow/tensorboard/components/vz_sorting:ts_typings",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -72,24 +72,31 @@ module Categorizer {
|
|||||||
if (tags.length === 0) {
|
if (tags.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
let sortedTags = tags.slice().sort(VZ.Sorting.compareTagNames);
|
|
||||||
let categories: Category[] = [];
|
// Maps between top-level name and category. We use the mapping to avoid
|
||||||
let currentCategory = {
|
// duplicating categories per run.
|
||||||
name: extractor(sortedTags[0]),
|
const categoryMapping: {[key: string]: Category} = {};
|
||||||
tags: [],
|
|
||||||
};
|
tags.forEach((t: string) => {
|
||||||
sortedTags.forEach((t: string) => {
|
const topLevel = extractor(t);
|
||||||
let topLevel = extractor(t);
|
if (!categoryMapping[topLevel]) {
|
||||||
if (currentCategory.name !== topLevel) {
|
const newCategory = {
|
||||||
categories.push(currentCategory);
|
|
||||||
currentCategory = {
|
|
||||||
name: topLevel,
|
name: topLevel,
|
||||||
tags: [],
|
tags: [],
|
||||||
};
|
};
|
||||||
|
categoryMapping[topLevel] = newCategory;
|
||||||
}
|
}
|
||||||
currentCategory.tags.push(t);
|
|
||||||
|
categoryMapping[topLevel].tags.push(t);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort categories into alphabetical order.
|
||||||
|
const categories =
|
||||||
|
_.map(_.keys(categoryMapping).sort(), key => categoryMapping[key]);
|
||||||
|
_.forEach(categories, (category) => {
|
||||||
|
// Sort the tags within each category.
|
||||||
|
category.tags.sort(VZ.Sorting.compareTagNames);
|
||||||
});
|
});
|
||||||
categories.push(currentCategory);
|
|
||||||
return categories;
|
return categories;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,18 @@ module Categorizer {
|
|||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
topLevelNamespaceCategorizer(['a']), [{name: 'a', tags: ['a']}]);
|
topLevelNamespaceCategorizer(['a']), [{name: 'a', tags: ['a']}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('only create 1 category per run', () => {
|
||||||
|
// TensorBoard separates runs from tags using the / and _ characters
|
||||||
|
// *only* during sorting. The categorizer should group all tags under
|
||||||
|
// their correct categories - and create only 1 category per run.
|
||||||
|
const tags = ['foo/bar', 'foo_in_between_run/baz', 'foo/quux'];
|
||||||
|
const expected = [
|
||||||
|
{name: 'foo', tags: ['foo/bar', 'foo/quux']},
|
||||||
|
{name: 'foo_in_between_run', tags: ['foo_in_between_run/baz']},
|
||||||
|
];
|
||||||
|
assert.deepEqual(topLevelNamespaceCategorizer(tags), expected);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('customCategorizer', () => {
|
describe('customCategorizer', () => {
|
||||||
|
@ -73,24 +73,31 @@ function extractorToCategorizer(extractor: (s: string) => string): Categorizer {
|
|||||||
if (tags.length === 0) {
|
if (tags.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
let sortedTags = tags.slice().sort(compareTagNames);
|
|
||||||
let categories: Category[] = [];
|
// Maps between top-level name and category. We use the mapping to avoid
|
||||||
let currentCategory = {
|
// duplicating categories per run.
|
||||||
name: extractor(sortedTags[0]),
|
const categoryMapping: {[key: string]: Category} = {};
|
||||||
tags: [],
|
|
||||||
};
|
tags.forEach((t: string) => {
|
||||||
sortedTags.forEach((t: string) => {
|
const topLevel = extractor(t);
|
||||||
let topLevel = extractor(t);
|
if (!categoryMapping[topLevel]) {
|
||||||
if (currentCategory.name !== topLevel) {
|
const newCategory = {
|
||||||
categories.push(currentCategory);
|
|
||||||
currentCategory = {
|
|
||||||
name: topLevel,
|
name: topLevel,
|
||||||
tags: [],
|
tags: [],
|
||||||
};
|
};
|
||||||
|
categoryMapping[topLevel] = newCategory;
|
||||||
}
|
}
|
||||||
currentCategory.tags.push(t);
|
|
||||||
|
categoryMapping[topLevel].tags.push(t);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort categories into alphabetical order.
|
||||||
|
const categories =
|
||||||
|
_.map(_.keys(categoryMapping).sort(), key => categoryMapping[key]);
|
||||||
|
_.forEach(categories, (category) => {
|
||||||
|
// Sort the tags within each category.
|
||||||
|
category.tags.sort(compareTagNames);
|
||||||
});
|
});
|
||||||
categories.push(currentCategory);
|
|
||||||
return categories;
|
return categories;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -180,4 +187,4 @@ Polymer({
|
|||||||
this._setCategories(categories);
|
this._setCategories(categories);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user