2017-04-12 15 views
1

私は20の項目と色のリストがあります:私は二重の値によって&グループを注文、GetColorsにリストを渡しているグループの数に基づいてリストから均等に選択しますか?

this.colors = new List<Color> { 
    (Color)ColorConverter.ConvertFromString("#DEEBF7"), 
    (Color)ColorConverter.ConvertFromString("#D2E1EF"), 
    (Color)ColorConverter.ConvertFromString("#C7D7E8"), 
    (Color)ColorConverter.ConvertFromString("#BCCDE0"), 
    (Color)ColorConverter.ConvertFromString("#B0C3D9"), 
    (Color)ColorConverter.ConvertFromString("#A5B9D2"), 
    (Color)ColorConverter.ConvertFromString("#9AAFCA"), 
    (Color)ColorConverter.ConvertFromString("#8FA6C3"), 
    (Color)ColorConverter.ConvertFromString("#839CBC"), 
    (Color)ColorConverter.ConvertFromString("#7892B4"), 
    (Color)ColorConverter.ConvertFromString("#6D88AD"), 
    (Color)ColorConverter.ConvertFromString("#627EA5"), 
    (Color)ColorConverter.ConvertFromString("#56749E"), 
    (Color)ColorConverter.ConvertFromString("#4B6B97"), 
    (Color)ColorConverter.ConvertFromString("#40618F"), 
    (Color)ColorConverter.ConvertFromString("#355788"), 
    (Color)ColorConverter.ConvertFromString("#294D81"), 
    (Color)ColorConverter.ConvertFromString("#1E4379"), 
    (Color)ColorConverter.ConvertFromString("#133972"), 
    (Color)ColorConverter.ConvertFromString("#08306B") 
}; 

public SortedDictionary<Guid, Color> GetColors(IList<Tuple<Guid, double>> heightsAboveGroundByGuid) 
{ 
    // Order providers by measurement height from ground 
    IEnumerable<IGrouping<double, Tuple<Guid, double>>> groupedOrderedList = heightsAboveGroundByGuid.OrderBy(h => h.Item2).GroupBy(o => o.Item2); 

    int numberOfGroups = groupedOrderedList.Count(); 

    SortedDictionary<Guid, Color> seriesColorsByGuid = new SortedDictionary<Guid, Color>();  

    int index = 0; 
    foreach (IGrouping<double, Tuple<Guid, double>> item in groupedOrderedList) 
    { 
     if (index <= this.colors.Count() - 1) 
     { 
      foreach (Tuple<Guid, double> childItem in item) 
      { 
       seriesColorsByGuid.Add(childItem.Item1, this.colors[index]); 
      }     
     } 

     index = Not sure how to implement this!; 
    } 

    return seriesColorsByGuid; 
} 

たとえば、実行時にダブルス40,40,40,50,50,60,60である。私は3つのグループを持っています。このシナリオでは、最初のグループ(40)が0のインデックス、2番目のグループ(50)のインデックス9 &、19の最終グループ(60)インデックス(リストの最後の色)を返すようにします。

渡されるグループの数によって均等に色分けされた色を設定するにはどうすればよいですか?

答えて

2

あなたは次のような状況を持っている(3、4、5グループの場合):

0 --- X --- 19
0 --- X --- X II --- 19
0 --- X I --- X II --- X III --- 19
など。

---でも(っぽい)のギャップであり、X Nあなたが見つけようとしている番号です。

3つのグループがあるときは2つのギャップがあり、4つのグループがあるときは3つのギャップがあり、n個のグループがあるときはn-1のギャップがあることは明らかです。したがって、グループの数より1つ少ない数で色数を分割し、毎回それをあなたのインデックスに追加することができます。次のコードは、あなたが何をしているのかを行います。新しいコード行の前にコメントを追加しました。

public SortedDictionary<Guid, Color> GetSeriesColors(IList<Tuple<Guid, double>> heightsAboveGroundByGuid) 
{ 
    IEnumerable<IGrouping<double, Tuple<Guid, double>>> groupedOrderedList = heightsAboveGroundByGuid.OrderBy(h => h.Item2).GroupBy(o => o.Item2); 

    int numberOfGroups = groupedOrderedList.Count(); 

    SortedDictionary<Guid, Color> seriesColorsByGuid = new SortedDictionary<Guid, Color>(); 

    int index = 0; 

    //calculate the size of the gaps. 
    float gap = (this.colors.Count() - 1)/(float)(numberofGroups - 1); 
    //keep track of how many multiples of gap we need 
    int gapsUsed = 1; 

    foreach (IGrouping<double, Tuple<Guid, double>> item in groupedOrderedList) 
    { 
     if (index <= this.colors.Count() - 1) 
     { 
      foreach (Tuple<Guid, double> childItem in item) 
      { 
       seriesColorsByGuid.Add(childItem.Item1, this.colors[index]); 
      } 
     } 
     //set the index to the gap * gapsUsed and cast it to an int 
     index = (int)(gap * gapsUsed); 
     //increment gaps used 
     gapsUsed++; 
    } 

    return seriesColorsByGuid; 
} 
+0

ありがとうございます!私はほとんどあなたのギャップの変数をインデックスに設定することでそれを得ましたが、私はgap&gapUsed変数を宣言すると、よりクリーンで読みやすくなりました。 – Hardgraf

1

この問題を解決する方法の1つは、グループの予想色間の距離を計算することです。それが役に立てば幸い!

public SortedDictionary<Guid, Color> GetColors(IEnumerable<Tuple<Guid, double>> heightsAboveGroundByGuid) 
{ 
     // Order providers by measurement height from ground 
     var groups = heightsAboveGroundByGuid.OrderBy(h => h.Item2).GroupBy(x => x.Item2).ToList(); 

     var colorsByGuid = new SortedDictionary<Guid, Color> 
     { 
      [groups.First().First().Item1] = _colors.First(), 
      [groups.Last().First().Item1] = _colors.Last() 
     }; 

     if (groups.Count < 3) return colorsByGuid; 

     var distance = _colors.Count/(groups.Count - 1); 
     for (var step = 1; step < groups.Count - 1; step++) 
     { 
      var groupId = groups[step].First().Item1; 
      colorsByGuid[groupId] = _colors.Skip(distance * step).First(); 
     } 

     return colorsByGuid; 
    } 
関連する問題