|
@@ -9,24 +9,38 @@ namespace wispro.sp.winClient
|
|
|
{
|
|
|
public partial class FlowChart
|
|
|
{
|
|
|
- double TitleHeight = 60;
|
|
|
- double ChartWidth = 1000;
|
|
|
- double rectWidth = 120;
|
|
|
- double rectHeight = 60;
|
|
|
- double initRadius = 25;
|
|
|
- double EndRadius = 25;
|
|
|
- double hSeparation = 50;
|
|
|
+ [Parameter]
|
|
|
+ public double TitleHeight { get; set; } = 100;
|
|
|
+
|
|
|
|
|
|
- int rectFontSize = 24;
|
|
|
+ [Parameter]
|
|
|
+ public double ChartWidth { get; set; } = 1200;
|
|
|
+ [Parameter]
|
|
|
+ public double ChartHeight { get; set; } = 900;
|
|
|
+ [Parameter]
|
|
|
+ public double rectWidth { get; set; } = 150;
|
|
|
|
|
|
+ [Parameter]
|
|
|
+ public double rectHeight { get; set; } = 60;
|
|
|
+ [Parameter]
|
|
|
+ public double initRadius { get; set; } = 25;
|
|
|
+ [Parameter]
|
|
|
+ public double EndRadius { get; set; } = 25;
|
|
|
+ [Parameter]
|
|
|
+ public double hSeparation { get; set; } = 40;
|
|
|
|
|
|
- private List<entity.workflowDefine.Step> Steps { get; set; }
|
|
|
+ int rectFontSize { get; set; } = 18;
|
|
|
|
|
|
- private List<entity.workflowDefine.TrasferCondition> Transfers { get; set; }
|
|
|
+
|
|
|
+ public List<entity.workflowDefine.Step> Steps { get; set; }
|
|
|
|
|
|
- private List<entity.workflowDefine.Action> Actions { get; set; }
|
|
|
+
|
|
|
+ public List<entity.workflowDefine.TrasferCondition> Transfers { get; set; }
|
|
|
|
|
|
- [Parameter]
|
|
|
+
|
|
|
+ public List<entity.workflowDefine.Action> Actions { get; set; }
|
|
|
+
|
|
|
+
|
|
|
public entity.workflowDefine.Workflow workflow { get; set; }
|
|
|
|
|
|
internal class shapeNode
|
|
@@ -64,9 +78,7 @@ namespace wispro.sp.winClient
|
|
|
|
|
|
private shapeNode FindNode(int stepId, out int Level, List<shapeNode> lstNodes)
|
|
|
{
|
|
|
- //Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(lstNodes));
|
|
|
- Console.WriteLine(stepId.ToString());
|
|
|
- Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(Steps));
|
|
|
+
|
|
|
Level = 1;
|
|
|
foreach (var sNode in lstNodes)
|
|
|
{
|
|
@@ -82,7 +94,7 @@ namespace wispro.sp.winClient
|
|
|
|
|
|
var retObj = FindNode(stepId, out Level, sNode.Childrens);
|
|
|
|
|
|
- if(retObj != null)
|
|
|
+ if (retObj != null)
|
|
|
{
|
|
|
return retObj;
|
|
|
}
|
|
@@ -109,7 +121,7 @@ namespace wispro.sp.winClient
|
|
|
else
|
|
|
{
|
|
|
nodes.Add(sNode);
|
|
|
- levelNodes.Add(sNode.Level,nodes);
|
|
|
+ levelNodes.Add(sNode.Level, nodes);
|
|
|
}
|
|
|
|
|
|
GetShapeLevelNodes(levelNodes, sNode.Childrens);
|
|
@@ -120,59 +132,12 @@ namespace wispro.sp.winClient
|
|
|
shapeNode startNode;
|
|
|
shapeNode InitShape;
|
|
|
shapeNode endNode;
|
|
|
+ Dictionary<int, List<shapeNode>> LevelNodes = new Dictionary<int, List<shapeNode>>();
|
|
|
+
|
|
|
private void initShapeTree()
|
|
|
{
|
|
|
-
|
|
|
- #region Demo流程数据
|
|
|
- workflow = new entity.workflowDefine.Workflow();
|
|
|
- workflow.Name = "请假处理流程";
|
|
|
- workflow.Id = 1;
|
|
|
-
|
|
|
- workflow.InitAction = new entity.workflowDefine.Action();
|
|
|
- workflow.InitAction.Name = "填写请教条";
|
|
|
-
|
|
|
- Steps = new List<entity.workflowDefine.Step>();
|
|
|
- var step1 = new entity.workflowDefine.Step();
|
|
|
- step1.Name = "部门主管申核";
|
|
|
- step1.Id = 1;
|
|
|
- Steps.Add(step1);
|
|
|
-
|
|
|
- var step2 = new entity.workflowDefine.Step();
|
|
|
- step2.Name = "老板申核";
|
|
|
- step2.Id = 2;
|
|
|
- Steps.Add(step2);
|
|
|
-
|
|
|
- var step3 = new entity.workflowDefine.Step();
|
|
|
- step3.Name = "申核结果通知";
|
|
|
- step3.Id = 3;
|
|
|
- Steps.Add(step3);
|
|
|
-
|
|
|
- workflow.EndStepId = 3;
|
|
|
-
|
|
|
- Transfers = new List<entity.workflowDefine.TrasferCondition>();
|
|
|
- var t = new entity.workflowDefine.TrasferCondition();
|
|
|
- t.StepId = null;
|
|
|
- t.nextStepId = 1;
|
|
|
- Transfers.Add(t);
|
|
|
-
|
|
|
- var t1 = new entity.workflowDefine.TrasferCondition();
|
|
|
- t1.StepId = 1;
|
|
|
- t1.nextStepId = 2;
|
|
|
- Transfers.Add(t1);
|
|
|
-
|
|
|
- var t2 = new entity.workflowDefine.TrasferCondition();
|
|
|
- t2.StepId = 1;
|
|
|
- t2.nextStepId = 3;
|
|
|
- Transfers.Add(t2);
|
|
|
-
|
|
|
- var t3 = new entity.workflowDefine.TrasferCondition();
|
|
|
- t3.StepId = 2;
|
|
|
- t3.nextStepId = 3;
|
|
|
- Transfers.Add(t3);
|
|
|
- #endregion
|
|
|
-
|
|
|
shapeTrees = new List<shapeNode>();
|
|
|
-
|
|
|
+ LevelNodes = new Dictionary<int, List<shapeNode>>();
|
|
|
startNode = new shapeNode()
|
|
|
{
|
|
|
//NodeObject = workflow.InitAction,
|
|
@@ -180,16 +145,14 @@ namespace wispro.sp.winClient
|
|
|
OutCount = 0,
|
|
|
width = 2 * initRadius,
|
|
|
height = 2 * initRadius,
|
|
|
- Level =0
|
|
|
+ Level = 0
|
|
|
};
|
|
|
-
|
|
|
-
|
|
|
InitShape = new shapeNode()
|
|
|
{
|
|
|
NodeObject = workflow.InitAction,
|
|
|
InCount = 0,
|
|
|
OutCount = 0,
|
|
|
- Type = 1 ,
|
|
|
+ Type = 1,
|
|
|
Level = 1
|
|
|
};
|
|
|
|
|
@@ -209,105 +172,118 @@ namespace wispro.sp.winClient
|
|
|
|
|
|
shapeTrees.Add(startNode);
|
|
|
|
|
|
- //shapeTrees.Add(endNode);
|
|
|
|
|
|
#region 将步骤对象生成形状Node并添加到列表中
|
|
|
- foreach (var step in Steps)
|
|
|
+ if (Steps == null || Steps.Count == 0 || Steps.FirstOrDefault(s => s.Id == workflow.EndStepId) == null)
|
|
|
{
|
|
|
- var temNode = new shapeNode() { NodeObject = step, InCount = 0, OutCount = 0, Type = 1 };
|
|
|
-
|
|
|
- if (workflow.EndStepId == step.Id)
|
|
|
+ InitShape.Childrens = new List<shapeNode>();
|
|
|
+ InitShape.Childrens.Add(endNode);
|
|
|
+ InitShape.OutCount += 1;
|
|
|
+ endNode.Parents = new List<shapeNode>();
|
|
|
+ endNode.Parents.Add(InitShape);
|
|
|
+ endNode.InCount += 1;
|
|
|
+ endNode.Level = InitShape.Level + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach (var step in Steps)
|
|
|
{
|
|
|
- temNode.Childrens = new List<shapeNode>();
|
|
|
- temNode.Childrens.Add(endNode);
|
|
|
- endNode.Parents = new List<shapeNode>();
|
|
|
- endNode.Parents.Add(temNode);
|
|
|
- }
|
|
|
+ var temNode = new shapeNode() { NodeObject = step, InCount = 0, OutCount = 0, Type = 1 };
|
|
|
|
|
|
- shapeTrees.Add(temNode);
|
|
|
- }
|
|
|
+ if (workflow.EndStepId == step.Id)
|
|
|
+ {
|
|
|
+ temNode.Childrens = new List<shapeNode>();
|
|
|
+ temNode.Childrens.Add(endNode);
|
|
|
+ endNode.Parents = new List<shapeNode>();
|
|
|
+ endNode.Parents.Add(temNode);
|
|
|
+ }
|
|
|
+
|
|
|
+ shapeTrees.Add(temNode);
|
|
|
+ }
|
|
|
#endregion
|
|
|
|
|
|
#region 遍历转移条件,生成流程树
|
|
|
- foreach (var transfer in Transfers)
|
|
|
+ if (Transfers != null)
|
|
|
{
|
|
|
- var FromNode = InitShape;
|
|
|
- int FromLevel = 0;
|
|
|
-
|
|
|
- if (transfer.StepId != null)
|
|
|
+ foreach (var transfer in Transfers)
|
|
|
{
|
|
|
- FromNode = FindNode(transfer.StepId.Value, out FromLevel, shapeTrees);
|
|
|
- }
|
|
|
+ var FromNode = InitShape;
|
|
|
+ int FromLevel = 0;
|
|
|
|
|
|
- int ToLevel = 0;
|
|
|
- var ToNode = FindNode(transfer.nextStepId, out ToLevel, shapeTrees);
|
|
|
+ if (transfer.StepId != null)
|
|
|
+ {
|
|
|
+ FromNode = FindNode(transfer.StepId.Value, out FromLevel, shapeTrees);
|
|
|
+ }
|
|
|
|
|
|
- if (FromNode.Childrens == null)
|
|
|
- {
|
|
|
- FromNode.Childrens = new List<shapeNode>();
|
|
|
- }
|
|
|
- FromNode.Childrens.Add(ToNode);
|
|
|
+ int ToLevel = 0;
|
|
|
+ var ToNode = FindNode(transfer.nextStepId, out ToLevel, shapeTrees);
|
|
|
|
|
|
- if (ToNode.Parents == null)
|
|
|
- {
|
|
|
- ToNode.Parents = new List<shapeNode>();
|
|
|
- }
|
|
|
- ToNode.Parents.Add(FromNode);
|
|
|
+ if (FromNode.Childrens == null)
|
|
|
+ {
|
|
|
+ FromNode.Childrens = new List<shapeNode>();
|
|
|
+ }
|
|
|
+ FromNode.Childrens.Add(ToNode);
|
|
|
|
|
|
- FromNode.OutCount += 1;
|
|
|
- ToNode.InCount += 1;
|
|
|
+ if (ToNode.Parents == null)
|
|
|
+ {
|
|
|
+ ToNode.Parents = new List<shapeNode>();
|
|
|
+ }
|
|
|
+ ToNode.Parents.Add(FromNode);
|
|
|
|
|
|
- if (FromNode.Level >= ToLevel)
|
|
|
- {
|
|
|
- ToNode.Level = FromNode.Level + 1;
|
|
|
- }
|
|
|
+ FromNode.OutCount += 1;
|
|
|
+ ToNode.InCount += 1;
|
|
|
|
|
|
- if (shapeTrees.Contains(ToNode))
|
|
|
- {
|
|
|
+ if (FromNode.Level >= ToLevel)
|
|
|
+ {
|
|
|
+ ToNode.Level = FromNode.Level + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (shapeTrees.Contains(ToNode))
|
|
|
+ {
|
|
|
|
|
|
- shapeTrees.Remove(ToNode);
|
|
|
+ shapeTrees.Remove(ToNode);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- endNode.Level = endNode.Parents[0].Level + 1;
|
|
|
+ endNode.Level = endNode.Parents[0].Level + 1;
|
|
|
+ }
|
|
|
#endregion
|
|
|
|
|
|
- Dictionary<int, List<shapeNode>> LevelNodes = new Dictionary<int, List<shapeNode>>();
|
|
|
+
|
|
|
|
|
|
GetShapeLevelNodes(LevelNodes, shapeTrees);
|
|
|
|
|
|
#region 添加跨层连接的中间层的虚拟节点
|
|
|
- foreach (int level in LevelNodes.Keys)
|
|
|
- {
|
|
|
- foreach (var temNode in LevelNodes[level])
|
|
|
- {
|
|
|
- if (temNode.Childrens != null)
|
|
|
- {
|
|
|
- foreach (var temChildrenNode in temNode.Childrens)
|
|
|
- {
|
|
|
- if ((temChildrenNode.Level - temNode.Level) > 1)
|
|
|
- {
|
|
|
- temNode.Childrens.Remove(temChildrenNode);
|
|
|
- temChildrenNode.Parents.Remove(temNode);
|
|
|
-
|
|
|
- var parentNode = temNode;
|
|
|
-
|
|
|
- for (int iLevel = temNode.Level + 1; iLevel < temChildrenNode.Level; iLevel++)
|
|
|
- {
|
|
|
- var xnNode = new shapeNode() { Type = 3, Parents = new List<shapeNode>(), Childrens = new List<shapeNode>() };
|
|
|
- parentNode.Childrens.Add(xnNode);
|
|
|
- xnNode.Parents = new List<shapeNode>();
|
|
|
- xnNode.Parents.Add(parentNode);
|
|
|
- parentNode = xnNode;
|
|
|
- }
|
|
|
-
|
|
|
- parentNode.Childrens.Add(temChildrenNode);
|
|
|
- temChildrenNode.Parents.Add(parentNode);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ //foreach (int level in LevelNodes.Keys)
|
|
|
+ //{
|
|
|
+ // foreach (var temNode in LevelNodes[level])
|
|
|
+ // {
|
|
|
+ // if (temNode.Childrens != null)
|
|
|
+ // {
|
|
|
+ // foreach (var temChildrenNode in temNode.Childrens)
|
|
|
+ // {
|
|
|
+ // if ((temChildrenNode.Level - temNode.Level) > 1)
|
|
|
+ // {
|
|
|
+ // temNode.Childrens.Remove(temChildrenNode);
|
|
|
+ // temChildrenNode.Parents.Remove(temNode);
|
|
|
+
|
|
|
+ // var parentNode = temNode;
|
|
|
+
|
|
|
+ // for (int iLevel = temNode.Level + 1; iLevel < temChildrenNode.Level; iLevel++)
|
|
|
+ // {
|
|
|
+ // var xnNode = new shapeNode() { Type = 3, Parents = new List<shapeNode>(), Childrens = new List<shapeNode>() };
|
|
|
+ // parentNode.Childrens.Add(xnNode);
|
|
|
+ // xnNode.Parents = new List<shapeNode>();
|
|
|
+ // xnNode.Parents.Add(parentNode);
|
|
|
+ // parentNode = xnNode;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // parentNode.Childrens.Add(temChildrenNode);
|
|
|
+ // temChildrenNode.Parents.Add(parentNode);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ //}
|
|
|
#endregion
|
|
|
|
|
|
int MaxNodeLevel = 0;
|
|
@@ -350,6 +326,11 @@ namespace wispro.sp.winClient
|
|
|
LevelNodes[i] = LevelNodes[i].OrderBy(node =>
|
|
|
{
|
|
|
// calculate average position based on connected nodes in top layer
|
|
|
+ if (node.Parents == null)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
var connected_nodes = node.Parents
|
|
|
.Where(l => l.Level == (i - 1)).ToList();
|
|
|
|
|
@@ -384,15 +365,15 @@ namespace wispro.sp.winClient
|
|
|
|
|
|
ArrangeNodesInRows(LevelNodes);
|
|
|
|
|
|
+
|
|
|
}
|
|
|
|
|
|
-
|
|
|
private void ArrangeNodesInRows(Dictionary<int, List<shapeNode>> LevelNodes)
|
|
|
{
|
|
|
|
|
|
-
|
|
|
+
|
|
|
double preBotton = TitleHeight;
|
|
|
- for (int iLevel = 0; iLevel < LevelNodes.Count ; iLevel++)
|
|
|
+ for (int iLevel = 0; iLevel < LevelNodes.Count; iLevel++)
|
|
|
{
|
|
|
int iCount = 0;
|
|
|
foreach (var node in LevelNodes[iLevel])
|
|
@@ -411,8 +392,8 @@ namespace wispro.sp.winClient
|
|
|
double maxHeight = 0;
|
|
|
foreach (var node in LevelNodes[iLevel])
|
|
|
{
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
int max = (node.InCount > node.OutCount) ? node.InCount : node.OutCount;
|
|
|
if (max == 0)
|
|
|
{
|
|
@@ -432,7 +413,7 @@ namespace wispro.sp.winClient
|
|
|
}
|
|
|
iCount += max;
|
|
|
|
|
|
- if(node.height > maxHeight)
|
|
|
+ if (node.height > maxHeight)
|
|
|
{
|
|
|
maxHeight = node.height;
|
|
|
}
|
|
@@ -440,10 +421,10 @@ namespace wispro.sp.winClient
|
|
|
|
|
|
foreach (var node in LevelNodes[iLevel])
|
|
|
{
|
|
|
- node.y = preBotton + hSeparation + maxHeight/2;
|
|
|
+ node.y = preBotton + hSeparation + maxHeight / 2;
|
|
|
}
|
|
|
|
|
|
- preBotton = preBotton + hSeparation + maxHeight;
|
|
|
+ preBotton = preBotton + hSeparation + maxHeight;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -469,13 +450,28 @@ namespace wispro.sp.winClient
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
- public void OnInitialized()
|
|
|
+ public dynamic GetEndStepLine()
|
|
|
{
|
|
|
- initShapeTree();
|
|
|
+ var startNode = endNode.Parents[0];
|
|
|
+ dynamic ret = new ExpandoObject();
|
|
|
+ ret.x1 = startNode.x;
|
|
|
+ ret.y1 = startNode.y + startNode.height / 2;
|
|
|
+
|
|
|
+ ret.x2 = endNode.x;
|
|
|
+ ret.y2 = endNode.y - endNode.height / 2;
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+ public void Refresh()
|
|
|
+ {
|
|
|
+ System.Text.Json.JsonSerializer.Serialize(Actions);
|
|
|
+ initShapeTree();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
void ClickStep(entity.workflowDefine.Step step)
|
|
|
{
|
|
|
|
|
@@ -490,6 +486,13 @@ namespace wispro.sp.winClient
|
|
|
{
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+ void ClickNode(shapeNode node)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
}
|