Fix handling of large numbers of image tracks (#1451)

Fixes #1448

Image tracks will now automatically inline when possible. When not possible, we display a maximum of 5 tracks before we change them to a single column with colored dots.
This commit is contained in:
josephschorr 2016-05-11 03:15:34 +02:00 committed by Jimmy Zelinskie
parent 94e9448658
commit f0bf138448
4 changed files with 83 additions and 24 deletions

View file

@ -21,6 +21,8 @@ angular.module('quay').directive('repoPanelTags', function () {
controller: function($scope, $element, $filter, $location, ApiService, UIService, VulnerabilityService) {
var orderBy = $filter('orderBy');
$scope.maxTrackCount = 5;
$scope.checkedTags = UIService.createCheckStateController([], 'name');
$scope.checkedTags.setPage(0);
@ -45,8 +47,6 @@ angular.module('quay').directive('repoPanelTags', function () {
var tags = [];
var allTags = [];
var imageMap = {};
var imageTracks = [];
// Build a list of tags and filtered tags.
for (var tag in $scope.repository.tags) {
@ -71,6 +71,8 @@ angular.module('quay').directive('repoPanelTags', function () {
var ordered = orderBy(tags, $scope.options.predicate, $scope.options.reverse);
var checked = [];
var imageMap = {};
var imageIndexMap = {};
for (var i = 0; i < ordered.length; ++i) {
var tagInfo = ordered[i];
if (!imageMap[tagInfo.image_id]) {
@ -79,33 +81,76 @@ angular.module('quay').directive('repoPanelTags', function () {
}
imageMap[tagInfo.image_id].push(tagInfo);
if ($.inArray(tagInfo.name, $scope.selectedTags) >= 0) {
checked.push(tagInfo);
}
if (!imageIndexMap[tagInfo.image_id]) {
imageIndexMap[tagInfo.image_id] = {'start': i, 'end': i};
}
imageIndexMap[tagInfo.image_id]['end'] = i;
};
// Calculate the image tracks.
var colors = d3.scale.category10();
var index = 0;
var imageTracks = [];
var imageTrackEntries = [];
imageIDs.sort().map(function(image_id) {
if (imageMap[image_id].length >= 2){
imageTracks.push({
// Create the track entry.
var index = imageTrackEntries.length;
var trackEntry = {
'image_id': image_id,
'color': colors(index),
'count': imageMap[image_id].length,
'tags': imageMap[image_id]
});
};
imageTrackEntries.push(trackEntry);
imageMap[image_id]['color'] = colors(index);
var currentImageIndex = imageIndexMap[image_id];
++index;
// Find the track in which we can place the entry, if any.
var existingTrack = null;
for (var i = 0; i < imageTracks.length; ++i) {
// For the current track, ensure that the start and end index
// for the current entry is outside of the range of the track's
// entries. If so, then we can add the entry to the track.
var currentTrack = imageTracks[i];
var canAddToCurrentTrack = true;
for (var j = 0; j < currentTrack.entries.length; ++j) {
var currentTrackEntry = currentTrack.entries[j];
var entryInfo = imageIndexMap[currentTrackEntry.image_id];
if (Math.max(entryInfo.start, currentImageIndex.start) <= Math.min(entryInfo.end, currentImageIndex.end)) {
canAddToCurrentTrack = false;
break;
}
}
if (canAddToCurrentTrack) {
existingTrack = currentTrack;
break;
}
}
// Add the entry to the track or create a new track if necessary.
if (existingTrack) {
existingTrack.entries.push(trackEntry)
} else {
imageTracks.push({
'entries': [trackEntry]
});
}
}
});
$scope.imageMap = imageMap;
$scope.imageTracks = imageTracks;
$scope.imageTrackEntries = imageTrackEntries;
$scope.options.page = 0;
$scope.tags = ordered;