public Dictionary <string, Dictionary <string, ColorableObject> > LoadColorCSV() { string customColorSource = AppSettings.ColorDir + "CustomColors.csv"; string fn = MethodBase.GetCurrentMethod().Name; try { Dictionary <string, Dictionary <string, ColorableObject> > colorableObjects = new Dictionary <string, Dictionary <string, ColorableObject> >(); if (File.Exists(customColorSource)) { using (StreamReader sr = new StreamReader(customColorSource)) { string line = sr.ReadLine(); //header if (line != "\"Type\",\"Name\",\"TypeGrouping\",\"Parent\",\"ParentType\",\"A\",\"R\",\"G\",\"B\",\"A2\",\"R2\",\"G2\",\"B2\"") { //Header isn't right...stopping now to prevent problems return(colorableObjects); } string[] header = line.Split(','); int fillAlphaIndex = 0; int borderAlphaIndex = 0; int i = 0; foreach (string s in header) { if (s == "\"A\"") { fillAlphaIndex = i; } if (s == "\"A2\"") { borderAlphaIndex = i; } i++; } line = sr.ReadLine(); while (line != null) { string[] values = line.Split(','); List <string> valueCorrection = new List <string>(); string appendedValue = ""; foreach (string value in values) { if (value.Length < 2) { if (!string.IsNullOrEmpty(value) && value != "\"") { appendedValue += ","; appendedValue += value; continue; } else if (!string.IsNullOrEmpty(appendedValue) && value == "\"") { appendedValue += ","; valueCorrection.Add(appendedValue); appendedValue = ""; continue; } else { //I believe this shouldn't get hit but if the value is null, don't worry about it... continue; } } if (value.First() == '"' && value.Last() == '"') { valueCorrection.Add(value.Substring(1, value.Length - 2)); } else if (value.First() == '"') { appendedValue = value.Substring(1, value.Length - 1); } else if (value.Last() == '"') { appendedValue += ","; appendedValue += value.Substring(0, value.Length - 1); valueCorrection.Add(appendedValue); appendedValue = ""; } else { appendedValue += ","; appendedValue += value; } } values = valueCorrection.ToArray(); ColorableObject obj; if (values[fillAlphaIndex] != "") { //It has a color obj = new ColorableObject(values[1], values[0], values[2], values[3], values[4], Color.FromArgb(Convert.ToInt32(values[fillAlphaIndex]), Convert.ToInt32(values[fillAlphaIndex + 1]), Convert.ToInt32(values[fillAlphaIndex + 2]), Convert.ToInt32(values[fillAlphaIndex + 3]))); } else { //It doesn't have a color obj = new ColorableObject(values[1], values[0], values[2], values[3], values[4]); } if (values[borderAlphaIndex] != "") { obj.BorderColor = Color.FromArgb(Convert.ToInt32(values[borderAlphaIndex]), Convert.ToInt32(values[borderAlphaIndex + 1]), Convert.ToInt32(values[borderAlphaIndex + 2]), Convert.ToInt32(values[borderAlphaIndex + 3])); } if (colorableObjects.ContainsKey(obj.Type)) { //Category has been created already colorableObjects[obj.Type][obj.Name] = obj; } else { //Category needs to be created colorableObjects[obj.Type] = new Dictionary <string, ColorableObject>(); colorableObjects[obj.Type][obj.Name] = obj; } line = sr.ReadLine(); } sr.Close(); } } return(colorableObjects); } catch (Exception exc) { Util.HandleExc(this, fn, exc); return(null); } }
private Dictionary <string, Color> BestMatchMethod(List <string> lookupValues, Dictionary <string, Dictionary <string, ColorableObject> > customColorDict, Dictionary <string, string> manyToOneLookup = null, bool getBorderColor = false) { //This finds the best matching category based on how well the lookupValues match up with each custom color category //It will work for any list of strings that match up with the names of the ColorableObjects //What is returned is a dictionary with the lookup value as the key and the cooresponding color as the value //manyToOneLookup must have values that match the names of items in the colorableColorDict. For example, C3S results as the key and the model as the value if (customColorDict == null || customColorDict.Count == 0) { return(new Dictionary <string, Color>()); } customColorDict["Many to One Custom Key"] = new Dictionary <string, ColorableObject>(); if (manyToOneLookup != null) { foreach (string manyToOneLookupKey in manyToOneLookup.Keys) { customColorDict["Many to One Custom Key"][manyToOneLookupKey] = new ColorableObject(manyToOneLookupKey, "Unknown"); } } Dictionary <string, Color> colorLookupDict = new Dictionary <string, Color>(); float bestMatchPercent = 0; int bestFuzzyMatchCount = 0; int bestExactMatchCount = 0; string bestMatchCat = ""; foreach (var cat in customColorDict) { int exactMatchCount = 0; int fuzzyMatchCount = 0; foreach (ColorableObject obj in cat.Value.Values) { if (lookupValues.Contains(obj.Name)) { fuzzyMatchCount++; } foreach (string lookupValue in lookupValues) { if (lookupValue == obj.Name) { exactMatchCount++; } } } if (exactMatchCount > bestExactMatchCount) { //The best category to choose is where the most fields match exactly what we were given bestExactMatchCount = exactMatchCount; bestFuzzyMatchCount = fuzzyMatchCount; bestMatchPercent = (exactMatchCount + fuzzyMatchCount) / (cat.Value.Count / 2); bestMatchCat = cat.Key; } else if (exactMatchCount == bestExactMatchCount && fuzzyMatchCount > bestFuzzyMatchCount) { //If there is an exact match tie, go with the one with more fuzzy matches bestFuzzyMatchCount = fuzzyMatchCount; bestMatchPercent = (exactMatchCount + fuzzyMatchCount) / (cat.Value.Count / 2); bestMatchCat = cat.Key; } else if (exactMatchCount == bestExactMatchCount && fuzzyMatchCount == bestFuzzyMatchCount && (Convert.ToDouble(fuzzyMatchCount) + Convert.ToDouble(exactMatchCount)) / (Convert.ToDouble(cat.Value.Count) * 2) > bestMatchPercent) { //In the case of a tie with both match types, go with the one with the highest % of matches bestMatchPercent = fuzzyMatchCount / cat.Value.Count; bestMatchCat = cat.Key; } } if (bestMatchCat != "") { if (bestMatchCat != "Many to One Custom Key") { foreach (string lookupValue in lookupValues) { if (customColorDict[bestMatchCat].ContainsKey(lookupValue)) { ColorableObject obj = customColorDict[bestMatchCat][lookupValue]; if (!getBorderColor) { if (obj.FillColor != Color.Empty) { colorLookupDict[lookupValue] = customColorDict[bestMatchCat][lookupValue].FillColor; } else if (!string.IsNullOrEmpty(obj.Parent) && customColorDict.ContainsKey(obj.ParentType) && customColorDict[obj.ParentType].ContainsKey(obj.Parent) && customColorDict[obj.ParentType][obj.Parent].FillColor != Color.Empty) { //Wow that is a mess of an if....lol //If it didn't have a color itself but it's parent did, use the parent's color... colorLookupDict[lookupValue] = customColorDict[obj.ParentType][obj.Parent].FillColor; } } else { if (obj.BorderColor != Color.Empty) { colorLookupDict[lookupValue] = customColorDict[bestMatchCat][lookupValue].BorderColor; } else if (!string.IsNullOrEmpty(obj.Parent) && customColorDict.ContainsKey(obj.ParentType) && customColorDict[obj.ParentType].ContainsKey(obj.Parent) && customColorDict[obj.ParentType][obj.Parent].BorderColor != Color.Empty) { //Wow that is a mess of an if....lol //If it didn't have a color itself but it's parent did, use the parent's color... colorLookupDict[lookupValue] = customColorDict[obj.ParentType][obj.Parent].BorderColor; } } } } } else { //Getting recursive up in here! Dictionary <string, Color> tempColorLookupDict = BestMatchMethod(manyToOneLookup.Values.ToList(), customColorDict); foreach (var lookupValue in lookupValues) { if (manyToOneLookup.ContainsKey(lookupValue) && tempColorLookupDict.ContainsKey(manyToOneLookup[lookupValue])) { //A bit confusing but many to one uses the values we were passed to get the corresponding colorable object colorLookupDict[lookupValue] = tempColorLookupDict[manyToOneLookup[lookupValue]]; } } } } return(colorLookupDict); }
private string BestMatchMethod_ReturnCategory(List <string> lookupValues, Dictionary <string, Dictionary <string, ColorableObject> > customColorDict, Dictionary <string, string> manyToOneLookup = null) { //This is a copy of the best match method but it will return the category instead of the color lookup... if (customColorDict == null || customColorDict.Count == 0) { return(null); } customColorDict["Many to One Custom Key"] = new Dictionary <string, ColorableObject>(); if (manyToOneLookup != null) { foreach (string manyToOneLookupKey in manyToOneLookup.Keys) { customColorDict["Many to One Custom Key"][manyToOneLookupKey] = new ColorableObject(manyToOneLookupKey, "Unknown"); } } float bestMatchPercent = 0; int bestFuzzyMatchCount = 0; int bestExactMatchCount = 0; string bestMatchCat = ""; foreach (var cat in customColorDict) { int exactMatchCount = 0; int fuzzyMatchCount = 0; foreach (ColorableObject obj in cat.Value.Values) { if (lookupValues.Contains(obj.Name)) { fuzzyMatchCount++; } foreach (string lookupValue in lookupValues) { if (lookupValue == obj.Name) { exactMatchCount++; } } } if (exactMatchCount > bestExactMatchCount) { //The best category to choose is where the most fields match exactly what we were given bestExactMatchCount = exactMatchCount; bestFuzzyMatchCount = fuzzyMatchCount; bestMatchPercent = (exactMatchCount + fuzzyMatchCount) / (cat.Value.Count / 2); bestMatchCat = cat.Key; } else if (exactMatchCount == bestExactMatchCount && fuzzyMatchCount > bestFuzzyMatchCount) { //If there is an exact match tie, go with the one with more fuzzy matches bestFuzzyMatchCount = fuzzyMatchCount; bestMatchPercent = (exactMatchCount + fuzzyMatchCount) / (cat.Value.Count / 2); bestMatchCat = cat.Key; } else if (exactMatchCount == bestExactMatchCount && fuzzyMatchCount == bestFuzzyMatchCount && (Convert.ToDouble(fuzzyMatchCount) + Convert.ToDouble(exactMatchCount)) / (Convert.ToDouble(cat.Value.Count) * 2) > bestMatchPercent) { //In the case of a tie with both match types, go with the one with the highest % of matches bestMatchPercent = fuzzyMatchCount / cat.Value.Count; bestMatchCat = cat.Key; } } if (bestMatchCat != "") { if (bestMatchCat != "Many to One Custom Key") { return(bestMatchCat); } else { //Getting recursive up in here! return(BestMatchMethod_ReturnCategory(manyToOneLookup.Values.ToList(), customColorDict)); } } return(null); }