DateTimeTree_ja - Houzkin/TreeStructures GitHub Wiki

DateTimeTree

日付を分類してツリーを作ります。
サンプルを示すため、以下のAnniversaryクラスを定義します。

public class Anniversary {
	public DateTime Date { get; set; }
	public string Name { get; set; }
	public override string ToString() {
		return $"{Name} : {Date}";
	}
}

このAnniversaryクラスにランダムな日付を設定するRandomDateTimeクラスと、DateTimeTreeの各ノードをラップするAnnivWrapperクラスを定義します。

class RandomDateTime {
	DateTime start;
	Random gen;
	int range;
	public RandomDateTime(DateTime start, DateTime until) {
		this.start = start;
		this.gen = new Random();
		range = (until - start).Days;
	}
	public DateTime Next() {
		return start.AddDays(gen.Next(range)).AddHours(gen.Next(0, 24)).AddMinutes(gen.Next(0, 60)).AddSeconds(gen.Next(0, 60));
	}
}

public class AnnivWrapper : BindableTreeNodeWrapper<DateTimeTree<Anniversary>.Node, AnnivWrapper> {
	public AnnivWrapper(DateTimeTree<Anniversary>.Node node) : base(node) { }
	protected override AnnivWrapper GenerateChild(DateTimeTree<Anniversary>.Node sourceChildNode) {
		return new AnnivWrapper(sourceChildNode);
	}
	public string HeaderString {
		get{
			if(this.Source.HasValue){
				return this.Source.Value.ToString();
			}
			var str = this.Source.Depth() switch {
				0 => string.Empty,
				1 => $"FY{Source.NodeClass}",
				2 => toMonth(Source.NodeClass > 12 ? Source.NodeClass - 12 : Source.NodeClass),
				3 => Source.NodeClass.ToString()+"th",
				_ => this.Source.ToString()
			}; ;
			return str;
		}
	}
	private string toMonth(int month){
		string str = month switch {
			1 => "Jan.",
			2 => "Feb.",
			3 => "Mar.",
			4 => "Apr.",
			5 => "May ",
			6 => "Jun.",
			7 => "Jul.",
			8 => "Aug.",
			9 => "Sep.",
			10 => "Oct.",
			11 => "Nov.",
			12 => "Dec.",
			_ => string.Empty,
		};
		return str;
	}
}

上記クラスを使用して、以下のコードを実行します。

var rmd = new RandomDateTime(new DateTime(2021, 1, 1), new DateTime(2022, 1, 1));
var Anniversarys = new ObservableCollection<Anniversary>();
var anys = "ABCDEFGHIJKLMNOPQRSTU".ToCharArray().Select(x => new Anniversary() { Name = x.ToString(), Date = rmd.Next() });

foreach (var item in anys) Anniversarys.Add(item);

var tree = new DateTimeTree<Anniversary>(Anniversarys,
	x => x.Date, 
    d => d.Month < 4 ? d.Year - 1 : d.Year,
    d => d.Month < 4 ? d.Month + 12 : d.Month,
    d => d.Day);

var DispTree = new AnnivWrapper(tree.Root);
Console.WriteLine(DispTree.ToTreeDiagram(x => x.HeaderString));

DateTimeTreeのコンストラクタで指定したint型の値によって、兄弟ノードはソートされます。
各、年度ごと、月ごと、日にちごとにツリー状に分類されます。
screenshot 36

この例のように、Observableなコレクションであれば、コレクションの変更によってツリーも更新されます。

Anniversarys.RemoveAt(0);
Anniversarys.Add(new Anniversary() { Name = "X",Date = rmd.Next() });
Console.WriteLine(DispTree.ToTreeDiagram(x=> x.HeaderString));
⚠️ **GitHub.com Fallback** ⚠️