using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Media; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.WPF; using Syncfusion.UI.Xaml.Diagram; using Syncfusion.UI.Xaml.Diagram.Layout; using Color = System.Drawing.Color; namespace PRSDesktop { public class OrgChartDataModel : DiagramViewModel { private OrgChartAppearance _appearance = OrgChartAppearance.Vertical; private OrgChartLayout _layout = OrgChartLayout.Employee; public OrgChartDataModel() { Active = false; Menu = null; Tool = Tool.ZoomPan; DataSourceSettings = new DataSourceSettings { ParentId = "ParentID", Id = "ID" }; LayoutManager = new LayoutManager { RefreshFrequency = RefreshFrequency.Reset }; Data = new OrgChartEntries(); DataSourceSettings.DataSource = new ObservableCollection(); } public bool Active { get; set; } public OrgChartAppearance Appearance { get => _appearance; set { if (_appearance != value) { _appearance = value; if (Active) Refresh(); } } } public OrgChartLayout Layout { get => _layout; set { if (_layout != value) { _layout = value; if (Active) UpdateLayout(); } } } public OrgChartEntries Data { get; } public void UpdateLayout() { switch (_appearance) { case OrgChartAppearance.Vertical: LayoutManager.Layout = new DirectedTreeLayout { Type = LayoutType.Organization, HorizontalSpacing = 40, VerticalSpacing = 50, AvoidSegmentOverlapping = false }; DefaultConnectorType = ConnectorType.Orthogonal; break; case OrgChartAppearance.Horizontal: LayoutManager.Layout = new DirectedTreeLayout { Type = LayoutType.Hierarchical, HorizontalSpacing = 40, VerticalSpacing = 50, AvoidSegmentOverlapping = false }; DefaultConnectorType = ConnectorType.Orthogonal; break; case OrgChartAppearance.Radial: LayoutManager.Layout = new RadialTreeLayout { HorizontalSpacing = 40, VerticalSpacing = 50, Bounds = new Rect(0, 0, 1000, 1000) }; DefaultConnectorType = ConnectorType.Line; break; } } private void GetThumbnails(OrgChartEntries entries) { var thumbids = entries.Select(x => x.ImageID).Where(x => x != Guid.Empty).Distinct().ToArray(); if (thumbids.Any()) { var thumbs = new Client().Query( new Filter(x => x.ID).InList(thumbids), new Columns( x => x.ID, x => x.Data ) ); foreach (var row in thumbs.Rows) { var entry = entries.FirstOrDefault(x => x.ImageID == row.Get(c => c.ID)); if (entry != null) { var data = row.Get(c => c.Data); var image = ImageUtils.LoadImage(data); entry.Image = new ImageBrush(image); } } } } public void Refresh() { var query = new MultiQuery(); query.Add(); query.Add(); query.Add(); query.Add( LookupFactory.DefineFilter(), new Columns( x => x.ID, x => x.Name, x => x.Position.ID, x => x.Position.Description, x => x.OrgChart.ReportsTo.ID, x => x.OrgChart.Color, x => x.OrgChart.Visible, x => x.Thumbnail.ID ) ); query.Query(); var employees = query.Get(); Data.Clear(); if (_layout == OrgChartLayout.Employee) { foreach (var row in employees.Rows) { var entry = new OrgChartEntry { ID = row.Get(x => x.ID), ParentID = row.Get(x => x.OrgChart.ReportsTo.ID), Name = row.Get(x => x.Name), Position = row.Get(x => x.Position.Description), ImageID = row.Get(x => x.Thumbnail.ID), Color = row.Get(x => x.OrgChart.Color), Visible = row.Get(x => x.OrgChart.Visible) }; Data.Add(entry); } } else if (_layout == OrgChartLayout.Position) { var positions = query.Get(); foreach (var row in positions.Rows) { var entry = new OrgChartEntry { ID = row.Get(x => x.ID), ParentID = row.Get(x => x.OrgChart.ReportsTo.ID), Position = row.Get(x => x.Description), ImageID = Guid.Empty, Color = row.Get(x => x.OrgChart.Color), Visible = row.Get(x => x.OrgChart.Visible) }; entry.Name = string.Join("\n", employees.Rows .Where(r => r.Get(c => c.Position.ID) == entry.ID) .Select(r => r.Get(c => c.Name)) .OrderBy(x => x) ); if (string.IsNullOrWhiteSpace(entry.Name)) { entry.WarningColor = ImageUtils.ColorToString(Color.Red); entry.Name = "VACANT"; } Data.Add(entry); } } else if (_layout == OrgChartLayout.Role) { var roles = query.Get(); var emproles = query.Get(); foreach (var row in roles.Rows) { var id = row.Get(x => x.ID); var parentid = row.Get(x => x.OrgChart.ReportsTo.ID); var entry = new OrgChartEntry { ID = row.Get(x => x.ID), ParentID = row.Get(x => x.OrgChart.ReportsTo.ID), Position = row.Get(x => x.Name), ImageID = Guid.Empty, Color = row.Get(x => x.OrgChart.Color), Visible = row.Get(x => x.OrgChart.Visible) }; entry.Name = string.Join("\n", emproles.Rows .Where( r => r.Get(c => c.RoleLink.ID) == entry.ID ) .Select(r => r.Get(c => c.EmployeeLink.Name)) .OrderBy(x => x) ); if (string.IsNullOrWhiteSpace(entry.Name)) { entry.WarningColor = ImageUtils.ColorToString(Color.Red); entry.Name = "VACANT"; } Data.Add(entry); } } GetThumbnails(Data); UpdateLayout(); var source = DataSourceSettings.DataSource as ObservableCollection; source.Clear(); foreach (var entry in Data.Where(x => x.Visible)) source.Add(entry); //= Data.Where(x=>x.Visible).ToList(); } public event PropertyChangedEventHandler PropertyChanged; private void onPropertyChanged(string name) { if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name)); } } }