diff --git a/src/SatisfactoryTree.Tests/ProductionTests.cs b/src/SatisfactoryTree.Tests/ProductionTests.cs index e02ad67..1fa4ab2 100644 --- a/src/SatisfactoryTree.Tests/ProductionTests.cs +++ b/src/SatisfactoryTree.Tests/ProductionTests.cs @@ -249,20 +249,20 @@ public void ReinforcedIronPlateProductionTest() IronIngot--""Iron Ingot
(15 units/min)""-->IronRod "; string expectedWithImagesResult = @"flowchart LR - ReinforcedIronPlate(""
Assembler
x1 Assembler
(Reinforced Iron Plate)
"") - ReinforcedIronPlateOutput{{""
Reinforced Iron Plate
5 Reinforced Iron Plate
""}} - IronPlate(""
Constructor
x1.5 Constructor
(Iron Plate)
"") - IronIngot(""
Smelter
x2 Smelter
(Iron Ingot)
"") - IronOre(""
Mining Machine Mk1
x1 Mining Machine Mk1
(Iron Ore)
"") - Screw(""
Constructor
x1.5 Constructor
(Screw)
"") - IronRod(""
Constructor
x1 Constructor
(Iron Rod)
"") - IronPlate--Iron Plate
(30 units/min)-->ReinforcedIronPlate - Screw--Screw
(60 units/min)-->ReinforcedIronPlate - ReinforcedIronPlate--Reinforced Iron Plate
(5 units/min)-->ReinforcedIronPlateOutput - IronIngot--Iron Ingot
(45 units/min)-->IronPlate - IronOre--Iron Ore
(60 units/min)-->IronIngot - IronRod--Iron Rod
(15 units/min)-->Screw - IronIngot--Iron Ingot
(15 units/min)-->IronRod + ReinforcedIronPlate[""
Assembler
x1 Assembler
(Reinforced Iron Plate)
""] + ReinforcedIronPlate_Item([""
Reinforced Iron Plate
x5 Reinforced Iron Plate
""]) + IronPlate[""
Constructor
x1.5 Constructor
(Iron Plate)
""] + IronIngot[""
Smelter
x2 Smelter
(Iron Ingot)
""] + IronOre[""
Mining Machine Mk1
x1 Mining Machine Mk1
(Iron Ore)
""] + Screw[""
Constructor
x1.5 Constructor
(Screw)
""] + IronRod[""
Constructor
x1 Constructor
(Iron Rod)
""] + IronPlate--""Iron Plate
(30 units/min)""-->ReinforcedIronPlate + Screw--""Screw
(60 units/min)""-->ReinforcedIronPlate + ReinforcedIronPlate--""Reinforced Iron Plate
(5 units/min)""-->ReinforcedIronPlate_Item + IronIngot--""Iron Ingot
(45 units/min)""-->IronPlate + IronOre--""Iron Ore
(60 units/min)""-->IronIngot + IronRod--""Iron Rod
(15 units/min)""-->Screw + IronIngot--""Iron Ingot
(15 units/min)""-->IronRod "; //Act @@ -271,7 +271,7 @@ public void ReinforcedIronPlateProductionTest() result = graph.BuildProductionPlan(itemGoal); results = result.ProductionItems; mermaidResult = graph.ToMermaidString(); - mermaidWithImagesResult = graph.ToMermaidStringWithImages(); + mermaidWithImagesResult = graph.ToMermaidString(true); } //Assert @@ -469,7 +469,6 @@ public void PlasticProductionTest() string expectedResult = @"flowchart LR Plastic[""x1 Refinery
(Plastic)""] Plastic_Item([20 Plastic]) - Plastic[""x1 Refinery
(Plastic)""] HeavyOilResidue_Item([10 Heavy Oil Residue]) CrudeOil[""x0.3 Oil Extractor
(Crude Oil)""] CrudeOil--""Crude Oil
(30 units/min)""-->Plastic @@ -512,14 +511,13 @@ public void CircuitBoardProductionTest() CopperIngot[""x0.7 Smelter
(Copper Ingot)""] CopperOre[""x0.4 Mining Machine Mk1
(Copper Ore)""] Plastic[""x1 Refinery
(Plastic)""] - Plastic[""x1 Refinery
(Plastic)""] HeavyOilResidue_Item([10 Heavy Oil Residue]) CrudeOil[""x0.3 Oil Extractor
(Crude Oil)""] CopperSheet--""Copper Sheet
(10 units/min)""-->CircuitBoard - Plastic--""Plastic
(20.0 units/min)""-->CircuitBoard + Plastic--""Plastic
(20.1 units/min)""-->CircuitBoard CircuitBoard--""Circuit Board
(5 units/min)""-->CircuitBoard_Item CopperIngot--""Copper Ingot
(20 units/min)""-->CopperSheet - CopperOre--""Copper Ore
(20.0 units/min)""-->CopperIngot + CopperOre--""Copper Ore
(20.1 units/min)""-->CopperIngot CrudeOil--""Crude Oil
(30 units/min)""-->Plastic Plastic--""Heavy Oil Residue
(10 units/min)""-->HeavyOilResidue_Item "; @@ -562,14 +560,14 @@ public void AluminumIngotProductionTest() Bauxite[""x0.2 Mining Machine Mk1
(Bauxite)""] Coal[""x0.1 Mining Machine Mk1
(Coal)""] RawQuartz[""x0.2 Assembler
(Raw Quartz)""] - AluminumScrap--""Aluminum Scrap
(15.0 units/min)""-->AluminumIngot - Silica--""Silica
(12.5 units/min)""-->AluminumIngot + AluminumScrap--""Aluminum Scrap
(15.1 units/min)""-->AluminumIngot + Silica--""Silica
(12.6 units/min)""-->AluminumIngot AluminumIngot--""Aluminum Ingot
(10 units/min)""-->AluminumIngot_Item - AluminaSolution--""Alumina Solution
(10.0 units/min)""-->AluminumScrap - Coal--""Coal
(5.0 units/min)""-->AluminumScrap - Bauxite--""Bauxite
(10.0 units/min)""-->AluminaSolution - Water--""Water
(15.0 units/min)""-->AluminaSolution - RawQuartz--""Raw Quartz
(30.0 units/min)""-->Silica + AluminaSolution--""Alumina Solution
(10.1 units/min)""-->AluminumScrap + Coal--""Coal
(5.1 units/min)""-->AluminumScrap + Bauxite--""Bauxite
(10.1 units/min)""-->AluminaSolution + Water--""Water
(15.1 units/min)""-->AluminaSolution + RawQuartz--""Raw Quartz
(30.1 units/min)""-->Silica "; //Act diff --git a/src/SatisfactoryTree.Web/Controllers/HomeController.cs b/src/SatisfactoryTree.Web/Controllers/HomeController.cs index 0510360..f20c9eb 100644 --- a/src/SatisfactoryTree.Web/Controllers/HomeController.cs +++ b/src/SatisfactoryTree.Web/Controllers/HomeController.cs @@ -33,12 +33,15 @@ public IActionResult Index() public IActionResult Production() { SatisfactoryProduction satisfactoryProduction = new(); - Item productionItem = ItemPoolTier1.Plastic(); - decimal productionQuantity = 20M; + //Item productionItem = ItemPoolTier1.Plastic(); + //decimal productionQuantity = 20M; + Item productionItem = ItemPoolTier3.ReinforcedIronPlate(); + decimal productionQuantity = 5M; + ProductionCalculation productionCalculation = satisfactoryProduction.BuildProductionPlan(new ProductionItem(productionItem, productionQuantity)); if (productionCalculation != null) { - string graph3 = satisfactoryProduction.ToMermaidStringWithImages(); + string graph3 = satisfactoryProduction.ToMermaidString(true); //Debug.WriteLine(graph3); return View(model: graph3); } diff --git a/src/SatisfactoryTree.Web/Views/Home/Production.cshtml b/src/SatisfactoryTree.Web/Views/Home/Production.cshtml index 1112a9f..06dd1a1 100644 --- a/src/SatisfactoryTree.Web/Views/Home/Production.cshtml +++ b/src/SatisfactoryTree.Web/Views/Home/Production.cshtml @@ -6,11 +6,32 @@

Production Graph

Here is a mermaid diagram: -
+@*     
         @Html.Raw(Model)
-    
+
*@ +
+ +
+ \ No newline at end of file diff --git a/src/SatisfactoryTree/SatisfactoryProduction.cs b/src/SatisfactoryTree/SatisfactoryProduction.cs index 03adc94..12ce495 100644 --- a/src/SatisfactoryTree/SatisfactoryProduction.cs +++ b/src/SatisfactoryTree/SatisfactoryProduction.cs @@ -202,7 +202,7 @@ private bool ProcessOutputItem(ProductionItem targetItem) } //Create the mermaid string for the production plan - public string ToMermaidString() + public string ToMermaidString(bool includeImages = false) { string direction = "LR"; List nodes = []; @@ -210,15 +210,29 @@ public string ToMermaidString() { if (item != null && item.Item != null) { - nodes.Add(new(item.Item.Recipes[0].Name.Replace(" ", ""), '"' + "x" + RoundUpAndFormat(item.BuildingQuantityRequired) + " " + item.Item.Recipes[0].Building + "
(" + item.Item.Recipes[0].Name + ")" + '"')); + string recipeName = item.Item.Recipes[0].Name; + string recipeBuildingName = item.Item.Recipes[0].Building; + string recipeBuildingQuantity = RoundUpAndFormat(item.BuildingQuantityRequired); + string recipeBuildingImage = AllBuildings.FindBuilding(item.Item.Recipes[0].Building)?.Image; + string recipeText = '"' + "x" + recipeBuildingQuantity + " " + recipeBuildingName + "
(" + recipeName + ")" + '"'; + if (includeImages) + { + recipeText = "\"
" + recipeBuildingName + "
x" + recipeBuildingQuantity + " " + recipeBuildingName + "
(" + recipeName + ")
\""; + } + if (nodes.Find(p => p.Name == recipeName) == null) + { + nodes.Add(new(recipeName, recipeText)); + } + // If it's the final output, add an extra node to show the output item if (item.OutputItem == true) { - string finalItemQuantity = item.Quantity.ToString("0.0"); - if ((int)item.Quantity == item.Quantity) + string finalNode = item.Item?.Name + "_Item"; + string finalNodeText = RoundUpAndFormat(item.Quantity) + " " + item.Item?.Name; + if (includeImages) { - finalItemQuantity = item.Quantity.ToString("0"); + finalNodeText = "\"
" + item.Item?.Name + "
x" + RoundUpAndFormat(item.Quantity) + " " + item.Item?.Name + "
\""; } - nodes.Add(new(item.Item?.Name.Replace(" ", "") + "_Item", finalItemQuantity + " " + item.Item?.Name, MermaidDotNet.Models.Node.ShapeType.Stadium)); + nodes.Add(new(finalNode, finalNodeText, MermaidDotNet.Models.Node.ShapeType.Stadium)); } } } @@ -229,14 +243,9 @@ public string ToMermaidString() { foreach (KeyValuePair itemInput in item.Dependencies) { - string itemQuantity = itemInput.Value.ToString("0.0"); - if ((int)itemInput.Value == itemInput.Value) - { - itemQuantity = itemInput.Value.ToString("0"); - } - string source = itemInput.Key.Replace(" ", ""); - string destination = item.Item.Recipes[0].Name.Replace(" ", ""); - string text = '"' + itemInput.Key + "
(" + itemQuantity + " units/min)" + '"'; + string source = itemInput.Key; + string destination = item.Item.Recipes[0].Name; + string text = '"' + itemInput.Key + "
(" + RoundUpAndFormat(itemInput.Value) + " units/min)" + '"'; MermaidDotNet.Models.Link link = new(source, destination, text); if (!links.Any(g => g.SourceNode == link.SourceNode && g.DestinationNode == link.DestinationNode && @@ -247,17 +256,13 @@ public string ToMermaidString() } if (item.OutputItem == true) { - string? source; - string? destination; - source = item.Item.Recipes[0].Name.Replace(" ", ""); - destination = item.Item.Name.Replace(" ", "") + "_Item"; - if (source != null && destination != null) - { + string linkSource = item.Item.Recipes[0].Name; + string linkDestination = item.Item.Name + "_Item"; + string linkText = '"' + item.Item.Name + "
(" + RoundUpAndFormat(item.Quantity) + " units/min)" + '"'; links.Add(new MermaidDotNet.Models.Link( - source, - destination, - '"' + item.Item.Name + "
(" + RoundUpAndFormat(item.Quantity) + " units/min)" + '"')); - } + linkSource, + linkDestination, + linkText)); } } } @@ -265,40 +270,49 @@ public string ToMermaidString() return flowchart.CalculateFlowchart(); } - public string ToMermaidStringWithImages() - { - List nodes = []; - List links = []; - foreach (ProductionItem item in ProductionItems) - { - string buildingName = "none"; - if (item.Building != null && item.Building.Name != null) - { - buildingName = item.Building.Name; - } - string buildingImage = ""; - if (item.Building != null && item.Building.Image != null) - { - buildingImage = item.Building.Image; - } - string itemText = "\"
" + buildingName + "
x" + RoundUpAndFormat(item.BuildingQuantityRequired) + " " + buildingName + "
(" + item.Name + ")
\""; - MermaidDotNet.Models.Node node = new(item.Name, itemText, MermaidDotNet.Models.Node.ShapeType.Rounded); - nodes.Add(node); - foreach (KeyValuePair dependency in item.Dependencies) - { - MermaidDotNet.Models.Link link = new(dependency.Key, item.Name, dependency.Key + "
(" + RoundUpAndFormat(dependency.Value) + " units/min)"); - links.Add(link); - } - if (item.OutputItem == true) - { - nodes.Add(new(item.Name + "Output", "\"
" + item.Name + "
" + RoundUpAndFormat(item.Quantity) + " " + item.Name + "
\"", MermaidDotNet.Models.Node.ShapeType.Hexagon)); - MermaidDotNet.Models.Link link = new(item.Name, item.Name + "Output", item.Name + "
(" + RoundUpAndFormat(item.Quantity) + " units/min)"); - links.Add(link); - } - } - MermaidDotNet.Flowchart flowchart = new("LR", nodes, links); - return flowchart.CalculateFlowchart(); - } + //public string ToMermaidStringWithImages() + //{ + // string direction = "LR"; + // List nodes = []; + // foreach (ProductionItem item in ProductionItems) + // { + // string buildingName = "none"; + // if (item.Building != null && item.Building.Name != null) + // { + // buildingName = item.Building.Name; + // } + // string buildingImage = ""; + // if (item.Building != null && item.Building.Image != null) + // { + // buildingImage = item.Building.Image; + // } + // string itemText = "\"
" + buildingName + "
x" + RoundUpAndFormat(item.BuildingQuantityRequired) + " " + buildingName + "
(" + item.Name + ")
\""; + // MermaidDotNet.Models.Node node = new(item.Item.Recipes[0].Name, itemText, MermaidDotNet.Models.Node.ShapeType.Rounded); + // if (nodes.Find(nodes => nodes.Name == item.Item.Recipes[0].Name) == null) + // { + // nodes.Add(node); + // } + // //nodes.Add(node); + // } + + // List links = []; + // foreach (ProductionItem item in ProductionItems) + // { + // foreach (KeyValuePair dependency in item.Dependencies) + // { + // MermaidDotNet.Models.Link link = new(dependency.Key, item.Item.Recipes[0].Name, dependency.Key + "
(" + RoundUpAndFormat(dependency.Value) + " units/min)"); + // links.Add(link); + // } + // if (item.OutputItem == true) + // { + // nodes.Add(new(item.Name + "Output", "\"
" + item.Name + "
" + RoundUpAndFormat(item.Quantity) + " " + item.Name + "
\"", MermaidDotNet.Models.Node.ShapeType.Hexagon)); + // MermaidDotNet.Models.Link link = new(item.Item.Recipes[0].Name, item.Name + "Output", item.Name + "
(" + RoundUpAndFormat(item.Quantity) + " units/min)"); + // links.Add(link); + // } + // } + // MermaidDotNet.Flowchart flowchart = new(direction, nodes, links); + // return flowchart.CalculateFlowchart(); + //} //Round up to the nearest decimal point - if one exists private static string RoundUpAndFormat(decimal value)