2 つの再帰的メソッドが次々に続き、それぞれが各ノードのデータを任意のサイズのツリーに生成します。(2 番目は最初の結果に依存するため、2 つを結合することはできません。また、最初の反復はリーフからルートへ、2 番目はルートからリーフへの反復です。)ノードの追加/位置の更新ごとにデータを生成する必要があります。ツリーのステータスが更新されるたびに、キャッシュされたビットマップにツリーを描画する必要があります。
現在、これには BackgroundWorker を使用していますが、ユーザーが多数のノードを追加すると、タスクが UI と同じスレッドで動作しているかのように遅延が発生し始めます。(BackgroundWorker を使用したのはこれが初めてですが、一般的なスレッドの処理には使用しません)
Matt の投稿に一度出くわしました: BackgroundWorker vs background Thread 代わりに System.Thread に戻す必要がありますか、それとも別のオプションでしょうか? プロセスが終了したら、結果のツリーと整数値をメイン スレッドに格納する必要があります。
[Threading]
private void Commence()
{
if (worker.IsBusy)
{
try
{
// I was thinking of fixing this with a timer instead
worker.CancelAsync();
while (worker.IsBusy) Thread.Sleep(10);
}
catch { return; }
}
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
// int radMax; TreeNodeEx rTNH;
// Call the two recursive methods
radMax = GenerateDataFromNodes(rTNH, radMax);
UpdateRenderRegion(); // draw result to cached bitmap
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// draw bitmap to screen
if (!e.Cancelled) Invalidate();
}
[Algorithm]
private int GenerateDataFromNodes(TreeNodeEx hierarchy, int max)
{
// set hierarchy values
max = GenerateScaleAndRadius(hierarchy, max);
GenerateStartAndSweep(hierarchy);
return max;
}
private int GenerateScaleAndRadius(TreeNodeEx hierarchy, int max, int radius = 2)
{
for (int i = 0; i < hierarchy.Nodes.Count; i++)
{
max = GenerateScaleAndRadius((TreeNodeEx)hierarchy.Nodes[i], max, radius+1);
}
// generation a
return max;
}
private void GenerateStartAndSweep(TreeNodeEx hierarchy)
{
for (int i = 0; i < hierarchy.Nodes.Count; i++)
{
// generation b-1
}
}
private void node_SweepAngleChagned(object sender, EventArgs e)
{
for (int i = 0; i < ((TreeNode)sender).Nodes.Count; i++)
{
// generation b-2
}
}
[Invalidation]
private void UpdateRenderRegion()
{
if (rTNH != null)
{
renderArea = new Bitmap(radMax * rScale * 2, radMax * rScale * 2);
Graphics gfx = Graphics.FromImage(renderArea);
gfx.SmoothingMode = SmoothingMode.AntiAlias;
// pens, graphicspaths, and pathgradients
// draw parent first
// draw generations next using the same structure as the parent
DrawNodes(gfx, p, rTNH, rScale, w, h);
gfx.Dispose();
}
}