OrgChartDataModel.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. using System;
  2. using System.Collections.ObjectModel;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Windows;
  6. using System.Windows.Media;
  7. using Comal.Classes;
  8. using InABox.Clients;
  9. using InABox.Core;
  10. using InABox.WPF;
  11. using Syncfusion.UI.Xaml.Diagram;
  12. using Syncfusion.UI.Xaml.Diagram.Layout;
  13. using Color = System.Drawing.Color;
  14. namespace PRSDesktop
  15. {
  16. public class OrgChartDataModel : DiagramViewModel
  17. {
  18. private OrgChartAppearance _appearance = OrgChartAppearance.Vertical;
  19. private OrgChartLayout _layout = OrgChartLayout.Employee;
  20. public OrgChartDataModel()
  21. {
  22. Active = false;
  23. Menu = null;
  24. Tool = Tool.ZoomPan;
  25. DataSourceSettings = new DataSourceSettings
  26. {
  27. ParentId = "ParentID",
  28. Id = "ID"
  29. };
  30. LayoutManager = new LayoutManager { RefreshFrequency = RefreshFrequency.Reset };
  31. Data = new OrgChartEntries();
  32. DataSourceSettings.DataSource = new ObservableCollection<OrgChartEntry>();
  33. }
  34. public bool Active { get; set; }
  35. public OrgChartAppearance Appearance
  36. {
  37. get => _appearance;
  38. set
  39. {
  40. if (_appearance != value)
  41. {
  42. _appearance = value;
  43. if (Active)
  44. Refresh();
  45. }
  46. }
  47. }
  48. public OrgChartLayout Layout
  49. {
  50. get => _layout;
  51. set
  52. {
  53. if (_layout != value)
  54. {
  55. _layout = value;
  56. if (Active)
  57. UpdateLayout();
  58. }
  59. }
  60. }
  61. public OrgChartEntries Data { get; }
  62. public void UpdateLayout()
  63. {
  64. switch (_appearance)
  65. {
  66. case OrgChartAppearance.Vertical:
  67. LayoutManager.Layout = new DirectedTreeLayout
  68. {
  69. Type = LayoutType.Organization,
  70. HorizontalSpacing = 40,
  71. VerticalSpacing = 50,
  72. AvoidSegmentOverlapping = false
  73. };
  74. DefaultConnectorType = ConnectorType.Orthogonal;
  75. break;
  76. case OrgChartAppearance.Horizontal:
  77. LayoutManager.Layout = new DirectedTreeLayout
  78. {
  79. Type = LayoutType.Hierarchical,
  80. HorizontalSpacing = 40,
  81. VerticalSpacing = 50,
  82. AvoidSegmentOverlapping = false
  83. };
  84. DefaultConnectorType = ConnectorType.Orthogonal;
  85. break;
  86. case OrgChartAppearance.Radial:
  87. LayoutManager.Layout = new RadialTreeLayout
  88. {
  89. HorizontalSpacing = 40,
  90. VerticalSpacing = 50,
  91. Bounds = new Rect(0, 0, 1000, 1000)
  92. };
  93. DefaultConnectorType = ConnectorType.Line;
  94. break;
  95. }
  96. }
  97. private void GetThumbnails(OrgChartEntries entries)
  98. {
  99. var thumbids = entries.Select(x => x.ImageID).Where(x => x != Guid.Empty).Distinct().ToArray();
  100. if (thumbids.Any())
  101. {
  102. var thumbs = new Client<Document>().Query(
  103. new Filter<Document>(x => x.ID).InList(thumbids),
  104. new Columns<Document>(
  105. x => x.ID,
  106. x => x.Data
  107. )
  108. );
  109. foreach (var row in thumbs.Rows)
  110. {
  111. var entry = entries.FirstOrDefault(x => x.ImageID == row.Get<Document, Guid>(c => c.ID));
  112. if (entry != null)
  113. {
  114. var data = row.Get<Document, byte[]>(c => c.Data);
  115. var image = ImageUtils.LoadImage(data);
  116. entry.Image = new ImageBrush(image);
  117. }
  118. }
  119. }
  120. }
  121. public void Refresh()
  122. {
  123. var query = new MultiQuery();
  124. query.Add<EmployeePosition>();
  125. query.Add<Role>();
  126. query.Add<EmployeeRole>();
  127. query.Add(
  128. LookupFactory.DefineFilter<Employee>(),
  129. new Columns<Employee>(
  130. x => x.ID,
  131. x => x.Name,
  132. x => x.Position.ID,
  133. x => x.Position.Description,
  134. x => x.OrgChart.ReportsTo.ID,
  135. x => x.OrgChart.Color,
  136. x => x.OrgChart.Visible,
  137. x => x.Thumbnail.ID
  138. )
  139. );
  140. query.Query();
  141. var employees = query.Get<Employee>();
  142. Data.Clear();
  143. if (_layout == OrgChartLayout.Employee)
  144. {
  145. foreach (var row in employees.Rows)
  146. {
  147. var entry = new OrgChartEntry
  148. {
  149. ID = row.Get<Employee, Guid>(x => x.ID),
  150. ParentID = row.Get<Employee, Guid>(x => x.OrgChart.ReportsTo.ID),
  151. Name = row.Get<Employee, string>(x => x.Name),
  152. Position = row.Get<Employee, string>(x => x.Position.Description),
  153. ImageID = row.Get<Employee, Guid>(x => x.Thumbnail.ID),
  154. Color = row.Get<Employee, string>(x => x.OrgChart.Color),
  155. Visible = row.Get<Employee, bool>(x => x.OrgChart.Visible)
  156. };
  157. Data.Add(entry);
  158. }
  159. }
  160. else if (_layout == OrgChartLayout.Position)
  161. {
  162. var positions = query.Get<EmployeePosition>();
  163. foreach (var row in positions.Rows)
  164. {
  165. var entry = new OrgChartEntry
  166. {
  167. ID = row.Get<EmployeePosition, Guid>(x => x.ID),
  168. ParentID = row.Get<EmployeePosition, Guid>(x => x.OrgChart.ReportsTo.ID),
  169. Position = row.Get<EmployeePosition, string>(x => x.Description),
  170. ImageID = Guid.Empty,
  171. Color = row.Get<EmployeePosition, string>(x => x.OrgChart.Color),
  172. Visible = row.Get<Employee, bool>(x => x.OrgChart.Visible)
  173. };
  174. entry.Name = string.Join("\n",
  175. employees.Rows
  176. .Where(r => r.Get<Employee, Guid>(c => c.Position.ID) == entry.ID)
  177. .Select(r => r.Get<Employee, string>(c => c.Name))
  178. .OrderBy(x => x)
  179. );
  180. if (string.IsNullOrWhiteSpace(entry.Name))
  181. {
  182. entry.WarningColor = ImageUtils.ColorToString(Color.Red);
  183. entry.Name = "VACANT";
  184. }
  185. Data.Add(entry);
  186. }
  187. }
  188. else if (_layout == OrgChartLayout.Role)
  189. {
  190. var roles = query.Get<Role>();
  191. var emproles = query.Get<EmployeeRole>();
  192. foreach (var row in roles.Rows)
  193. {
  194. var id = row.Get<Role, Guid>(x => x.ID);
  195. var parentid = row.Get<Role, Guid>(x => x.OrgChart.ReportsTo.ID);
  196. var entry = new OrgChartEntry
  197. {
  198. ID = row.Get<Role, Guid>(x => x.ID),
  199. ParentID = row.Get<Role, Guid>(x => x.OrgChart.ReportsTo.ID),
  200. Position = row.Get<Role, string>(x => x.Name),
  201. ImageID = Guid.Empty,
  202. Color = row.Get<Role, string>(x => x.OrgChart.Color),
  203. Visible = row.Get<Employee, bool>(x => x.OrgChart.Visible)
  204. };
  205. entry.Name = string.Join("\n",
  206. emproles.Rows
  207. .Where(
  208. r => r.Get<EmployeeRole, Guid>(c => c.RoleLink.ID) == entry.ID
  209. )
  210. .Select(r => r.Get<EmployeeRole, string>(c => c.EmployeeLink.Name))
  211. .OrderBy(x => x)
  212. );
  213. if (string.IsNullOrWhiteSpace(entry.Name))
  214. {
  215. entry.WarningColor = ImageUtils.ColorToString(Color.Red);
  216. entry.Name = "VACANT";
  217. }
  218. Data.Add(entry);
  219. }
  220. }
  221. GetThumbnails(Data);
  222. UpdateLayout();
  223. var source = DataSourceSettings.DataSource as ObservableCollection<OrgChartEntry>;
  224. source.Clear();
  225. foreach (var entry in Data.Where(x => x.Visible))
  226. source.Add(entry);
  227. //= Data.Where(x=>x.Visible).ToList();
  228. }
  229. public event PropertyChangedEventHandler PropertyChanged;
  230. private void onPropertyChanged(string name)
  231. {
  232. if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name));
  233. }
  234. }
  235. }