Exemple #1
0
        // Public members

        public static async Task <string> Save(Species species, AncestryTreeGenerationFlags flags)
        {
            // Generate the ancestry tree.

            TreeNode <AncestryTree.NodeData> ancestry_tree_root = await AncestryTree.GenerateTreeAsync(species, flags);

            TreeNode <AncestryTreeRendererNodeData> root = TreeUtils.CopyAs(ancestry_tree_root, x => {
                return(new AncestryTreeRendererNodeData {
                    Species = x.Value.Species,
                    IsAncestor = x.Value.IsAncestor,
                    Bounds = new RectangleF()
                });
            });

            // Generate the evolution tree image.

            using (Font font = new Font("Calibri", 12)) {
                // Calculate the size of each node.

                float horizontal_padding = 5.0f;

                TreeUtils.PostOrderTraverse(root, (node) => {
                    SizeF size = GraphicsUtils.MeasureString(node.Value.Species.ShortName, font);

                    node.Value.Bounds.Width  = size.Width + horizontal_padding;
                    node.Value.Bounds.Height = size.Height;
                });

                // Calculate node placements.

                _calculateNodePlacements(root);

                // Calculate the size of the tree.

                RectangleF bounds = _calculateTreeBounds(root);

                // Shift the tree so that the entire thing is visible.

                float min_x = 0.0f;

                TreeUtils.PostOrderTraverse(root, (node) => {
                    if (node.Value.Bounds.X < min_x)
                    {
                        min_x = bounds.X;
                    }
                });

                _shiftTree(root, -min_x, 0.0f);

                // Create the bitmap.

                using (Bitmap bmp = new Bitmap((int)bounds.Width, (int)bounds.Height))
                    using (Graphics gfx = Graphics.FromImage(bmp)) {
                        gfx.Clear(Color.FromArgb(54, 57, 63));
                        gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                        gfx.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                        _drawSpeciesTreeNode(gfx, root, species, font);

                        // Save the result.

                        string out_dir = Global.TempDirectory + "anc";

                        if (!System.IO.Directory.Exists(out_dir))
                        {
                            System.IO.Directory.CreateDirectory(out_dir);
                        }

                        string fpath = System.IO.Path.Combine(out_dir, species.ShortName + ".png");

                        bmp.Save(fpath);

                        return(fpath);
                    }
            }
        }
Exemple #2
0
        public static async Task <TreeNode <NodeData> > GenerateTreeAsync(Species species, AncestryTreeGenerationFlags flags)
        {
            // Start by finding the earliest ancestor of this species.

            List <long> ancestor_ids = new List <long>();

            if (!flags.HasFlag(AncestryTreeGenerationFlags.DescendantsOnly))
            {
                ancestor_ids.AddRange(await SpeciesUtils.GetAncestorIdsAsync(species.Id));
            }

            ancestor_ids.Add(species.Id);

            // Starting from the earliest ancestor, generate all tiers, down to the latest descendant.

            TreeNode <NodeData> root = new TreeNode <NodeData> {
                Value = new NodeData {
                    Species    = await SpeciesUtils.GetSpeciesAsync(ancestor_ids.First()),
                    IsAncestor = true
                }
            };

            Queue <TreeNode <NodeData> > queue = new Queue <TreeNode <NodeData> >();

            queue.Enqueue(root);

            while (queue.Count() > 0)
            {
                Species[] descendants = await SpeciesUtils.GetDirectDescendantsAsync(queue.First().Value.Species);

                foreach (Species descendant in descendants)
                {
                    TreeNode <NodeData> node = new TreeNode <NodeData> {
                        Value = new NodeData {
                            Species    = descendant,
                            IsAncestor = ancestor_ids.Contains(descendant.Id)
                        }
                    };

                    if (!flags.HasFlag(AncestryTreeGenerationFlags.AncestorsOnly) || node.Value.IsAncestor)
                    {
                        queue.First().AddChild(node);
                        queue.Enqueue(node);
                    }
                }

                queue.Dequeue();
            }

            return(root);
        }