/// <summary> /// Filters and sort the <paramref name="source" /> with the <paramref name="sourceConfigurationViewModel" /> /// </summary> /// <param name="source">The <see cref="Thing" /> to filter</param> /// <param name="sourceConfigurationViewModel">The filter and sort settings</param> /// <returns>The filtered <see cref="Thing" /></returns> private IEnumerable <DefinedThing> FilterAndSortSourceByCategoryAndOwner(IReadOnlyList <DefinedThing> source, SourceConfigurationViewModel sourceConfigurationViewModel) { var sourceXCatThing = new List <DefinedThing>(); if (sourceConfigurationViewModel?.SelectedCategories == null || sourceConfigurationViewModel.SelectedCategories.Count == 0) { return(sourceXCatThing); } foreach (var definedThing in source) { if (!this.IsDefinedThingDisplayAllowed(definedThing)) { continue; } var thing = (ICategorizableThing)definedThing; if (RelationshipMatrixViewModel.IsCategoryApplicableToConfiguration(thing, sourceConfigurationViewModel)) { if (definedThing is IOwnedThing ownedThing) { if (sourceConfigurationViewModel.SelectedOwners.Contains(ownedThing.Owner)) { sourceXCatThing.Add(definedThing); } } else { sourceXCatThing.Add(definedThing); } } } if (sourceConfigurationViewModel.SelectedSortOrder == SortOrder.Ascending) { sourceXCatThing = sourceConfigurationViewModel.SelectedSortKind == DisplayKind.Name ? sourceXCatThing.OrderBy(x => x.Name).ToList() : sourceXCatThing.OrderBy(x => x.ShortName).ToList(); } else { sourceXCatThing = sourceConfigurationViewModel.SelectedSortKind == DisplayKind.Name ? sourceXCatThing.OrderByDescending(x => x.Name).ToList() : sourceXCatThing.OrderByDescending(x => x.ShortName).ToList(); } return(sourceXCatThing); }
/// <summary> /// Checks if the <see cref="ICategorizableThing" /> has any categories that fall under the filter criteria /// </summary> /// <param name="thing">The <see cref="ICategorizableThing" /> to check</param> /// <param name="sourceConfiguration">The <see cref="SourceConfigurationViewModel" /> that defines the parameters.</param> /// <returns>True if the criteria is met.</returns> public static bool IsCategoryApplicableToConfiguration(ICategorizableThing thing, SourceConfigurationViewModel sourceConfiguration) { var thingCategories = new List <Category>(thing.Category); // if the thing is ElementUsage, add the ElementDefinition categories if (thing is ElementUsage usage) { thingCategories.AddRange(usage.ElementDefinition.Category); } switch (sourceConfiguration.SelectedBooleanOperatorKind) { case CategoryBooleanOperatorKind.OR: // if subcategories should be selected, expand the list var allCategories = new List <Category>(sourceConfiguration.SelectedCategories); if (sourceConfiguration.IncludeSubcategories) { foreach (var category in sourceConfiguration.SelectedCategories) { allCategories.AddRange(category.AllDerivedCategories()); } } return(thingCategories.Intersect(allCategories).Any()); case CategoryBooleanOperatorKind.AND: var categoryLists = new List <bool>(); foreach (var category in sourceConfiguration.SelectedCategories) { var categoryGroup = new List <Category> { category }; if (sourceConfiguration.IncludeSubcategories) { categoryGroup.AddRange(category.AllDerivedCategories()); } categoryLists.Add(thingCategories.Intersect(categoryGroup).Any()); } return(categoryLists.All(x => x)); } return(false); }
/// <summary> /// Rebuilds the matrix /// </summary> /// <param name="sourceY">The <see cref="SourceConfigurationViewModel" /> of the Y axis.</param> /// <param name="sourceX">The <see cref="SourceConfigurationViewModel" /> of the X axis.</param> /// <param name="relationshipRule">The <see cref="BinaryRelationshipRule" /></param> /// <param name="showRelatedOnly">Show only the related rows and columns.</param> public void RebuildMatrix(SourceConfigurationViewModel sourceY, SourceConfigurationViewModel sourceX, BinaryRelationshipRule relationshipRule, bool showRelatedOnly) { this.Columns.Clear(); this.Records.Clear(); var unfilteredRecords = new List <IDictionary <string, MatrixCellViewModel> >(); this.Title = "-"; if (!sourceY.SelectedClassKind.HasValue || !sourceX.SelectedClassKind.HasValue || relationshipRule == null) { return; } this.Title = relationshipRule.Name; var things = this.session.Assembler.Cache .Where(x => x.Key.Iteration.HasValue && x.Key.Iteration.Value == this.iteration.Iid) .Select(x => x.Value.Value) .Where(x => x.ClassKind == sourceX.SelectedClassKind.Value || x.ClassKind == sourceY.SelectedClassKind.Value).ToList(); List <DefinedThing> sourceXThing; List <DefinedThing> sourceYThing; try { sourceXThing = things.Where(x => x.ClassKind == sourceX.SelectedClassKind.Value).Cast <DefinedThing>() .ToList(); sourceYThing = things.Where(x => x.ClassKind == sourceY.SelectedClassKind.Value).Cast <DefinedThing>() .ToList(); } catch (InvalidCastException) { return; } if (sourceYThing.Count == 0 || sourceXThing.Count == 0) { return; } var sourceXToUse = new List <DefinedThing>(this.FilterAndSortSourceByCategoryAndOwner(sourceXThing, sourceX)); var sourceYToUse = new List <DefinedThing>(this.FilterAndSortSourceByCategoryAndOwner(sourceYThing, sourceY)); if (sourceYToUse.Count == 0 || sourceXToUse.Count == 0) { return; } // get relationships var relationships = this.QueryBinaryRelationshipInContext(relationshipRule).ToList(); // create columns var unfilteredColumns = this.CreateColumns(sourceXToUse, sourceX.SelectedDisplayKind, showRelatedOnly, relationships); // create rows foreach (var definedThing in sourceYToUse) { if (showRelatedOnly && !relationships.Any(x => x.Source.Iid.Equals(definedThing.Iid) || x.Target.Iid.Equals(definedThing.Iid))) { // if thing is ont in any relationships, skip continue; } unfilteredRecords.Add(this.ComputeRow(definedThing, sourceXToUse, relationships, relationshipRule, sourceY.SelectedDisplayKind, unfilteredColumns)); } // secondary filter remove unwanted rows and columns if (showRelatedOnly) { this.Columns.AddRange(unfilteredColumns.Where(x => x.RelationshipCount != 0).ToList()); this.Records.AddRange(unfilteredRecords.Where(x => x.Any(c => c.Value.RelationshipDirection != RelationshipDirectionKind.None))); } else { this.Columns.AddRange(unfilteredColumns); this.Records.AddRange(unfilteredRecords); } }