ChartWindow: wip
This commit is contained in:
		| @@ -3,52 +3,31 @@ using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text.Json.Nodes; | ||||
| using System.Windows.Documents; | ||||
|  | ||||
| namespace Elwig.Helpers.Billing { | ||||
|     public class Graph : ICloneable { | ||||
|  | ||||
|         public BillingData.CurveMode Mode { get; set; } | ||||
|         public int Id { get; set; } | ||||
|         private int MinX { get; set; } | ||||
|         private int MaxX { get; set; } | ||||
|         public List<Tuple<string, string>> Contracts { get; set; } | ||||
|         public double[] DataX { get; set; } | ||||
|         public double[] DataY { get; set; } | ||||
|  | ||||
|         public Graph(int id, BillingData.CurveMode mode, int minX, int maxX) { | ||||
|             Id = id; | ||||
|             Mode = mode; | ||||
|             Contracts = new List<Tuple<string, string>>(); | ||||
|             MinX = minX; | ||||
|             MaxX = maxX; | ||||
|  | ||||
|             DataX = DataGen.Range(MinX, MaxX + 1); | ||||
|             DataY = DataGen.Zeros(MaxX - MinX + 1); | ||||
|         public Graph(int minX, int maxX) { | ||||
|             DataX = DataGen.Range(minX, maxX + 1); | ||||
|             DataY = DataGen.Zeros(maxX - minX + 1); | ||||
|         } | ||||
|  | ||||
|         public Graph(int id, BillingData.CurveMode mode, Dictionary<double, decimal> data, int minX, int maxX) { | ||||
|             Id = id; | ||||
|             Mode = mode; | ||||
|             Contracts = new List<Tuple<string, string>>(); | ||||
|             MinX = minX; | ||||
|             MaxX = maxX; | ||||
|  | ||||
|             DataX = DataGen.Range(MinX, MaxX + 1); | ||||
|             DataY = DataGen.Zeros(MaxX - MinX + 1); | ||||
|             ParseGraphData(data); | ||||
|         public Graph(Dictionary<double, decimal> data, int minX, int maxX) { | ||||
|             DataX = DataGen.Range(minX, maxX + 1); | ||||
|             DataY = DataGen.Zeros(maxX - minX + 1); | ||||
|             ParseGraphData(data, minX, maxX); | ||||
|         } | ||||
|  | ||||
|         public Graph(int id, BillingData.CurveMode mode, int minX, int maxX, List<Tuple<string, string>> contracts, double[] dataX, double[] dataY) { | ||||
|             Id = id; | ||||
|             Mode = mode; | ||||
|             MinX = minX; | ||||
|             MaxX = maxX; | ||||
|             Contracts = contracts; | ||||
|         public Graph(double[] dataX, double[] dataY) { | ||||
|             DataX = dataX; | ||||
|             DataY = dataY; | ||||
|         } | ||||
|  | ||||
|         private void ParseGraphData(Dictionary<double, decimal> graphPoints) { | ||||
|         private void ParseGraphData(Dictionary<double, decimal> graphPoints, int minX, int maxX) { | ||||
|             if (graphPoints.Keys.Count < 1) { | ||||
|                 return; | ||||
|             } | ||||
| @@ -56,11 +35,11 @@ namespace Elwig.Helpers.Billing { | ||||
|             var minKey = graphPoints.Keys.Order().First(); | ||||
|             var maxKey = graphPoints.Keys.OrderDescending().First(); | ||||
|  | ||||
|             if (!graphPoints.ContainsKey(MinX)) { | ||||
|                 graphPoints.Add(MinX, graphPoints.GetValueOrDefault(minKey)); | ||||
|             if (!graphPoints.ContainsKey(minX)) { | ||||
|                 graphPoints.Add(minX, graphPoints.GetValueOrDefault(minKey)); | ||||
|             } | ||||
|             if (!graphPoints.ContainsKey(MaxX)) { | ||||
|                 graphPoints.Add(MaxX, graphPoints.GetValueOrDefault(maxKey)); | ||||
|             if (!graphPoints.ContainsKey(maxX)) { | ||||
|                 graphPoints.Add(maxX, graphPoints.GetValueOrDefault(maxKey)); | ||||
|             } | ||||
|  | ||||
|             var keys = graphPoints.Keys.Order().ToArray(); | ||||
| @@ -70,56 +49,60 @@ namespace Elwig.Helpers.Billing { | ||||
|                 if (i + 1 < keys.Length) { | ||||
|                     decimal point2Value = graphPoints[keys[i + 1]]; | ||||
|                     if (point1Value == point2Value) { | ||||
|                         for (int j = (int)(keys[i] - MinX); j < keys[i + 1] - MinX; j++) { | ||||
|                         for (int j = (int)(keys[i] - minX); j < keys[i + 1] - minX; j++) { | ||||
|                             DataY[j] = (double)point1Value; | ||||
|                         } | ||||
|                     } else { | ||||
|                         int steps = (int)Math.Abs(keys[i + 1] - keys[i]); | ||||
|                         decimal step = (point2Value - point1Value) / steps; | ||||
|  | ||||
|                         DataY[(int)(keys[i] - MinX)] = (double)point1Value; | ||||
|                         DataY[(int)(keys[i + 1] - MinX)] = (double)point2Value; | ||||
|                         DataY[(int)(keys[i] - minX)] = (double)point1Value; | ||||
|                         DataY[(int)(keys[i + 1] - minX)] = (double)point2Value; | ||||
|  | ||||
|                         for (int j = (int)(keys[i] - MinX); j < keys[i + 1] - MinX - 1; j++) { | ||||
|                         for (int j = (int)(keys[i] - minX); j < keys[i + 1] - minX - 1; j++) { | ||||
|                             DataY[j + 1] = Math.Round(DataY[j] + (double)step, 4); // TODO richtig runden | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 else { | ||||
|                     for (int j = (int)(keys[i] - MinX); j < DataX.Length; j++) { | ||||
|                     for (int j = (int)(keys[i] - minX); j < DataX.Length; j++) { | ||||
|                         DataY[j] = (double)point1Value; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public JsonObject ToJson() { | ||||
|             var graph = new JsonObject { | ||||
|                 ["id"] = Id, | ||||
|                 ["mode"] = Mode.ToString().ToLower(), | ||||
|             }; | ||||
|         public void FlattenGraph(int begin, int end, double value) { | ||||
|             for (int i = begin; i <= end; i++) { | ||||
|                 DataY[i] = value; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void LinearIncreaseGraph(int begin, int end, double inc) { | ||||
|             for (int i = begin; i < end; i++) { | ||||
|                 DataY[i + 1] = DataY[i] + inc; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public JsonObject ToJson(string mode) { | ||||
|             var data = new JsonObject(); | ||||
|  | ||||
|             if (DataY[0] != DataY[1]) { | ||||
|                 data.Add(new KeyValuePair<string, JsonNode?>(DataX[0] + Mode.ToString().ToLower(), Math.Round(DataY[0], 4))); | ||||
|                 data.Add(new KeyValuePair<string, JsonNode?>(DataX[0] + mode, Math.Round(DataY[0], 4))); | ||||
|             } | ||||
|             for (int i = 1; i < DataX.Length - 1; i++) { | ||||
|                 if (Math.Round(DataY[i] - DataY[i - 1], 10) != Math.Round(DataY[i + 1] - DataY[i], 10)) { | ||||
|                     data.Add(new KeyValuePair<string, JsonNode?>(DataX[i] + Mode.ToString().ToLower(), Math.Round(DataY[i], 4))); | ||||
|                     data.Add(new KeyValuePair<string, JsonNode?>(DataX[i] + mode, Math.Round(DataY[i], 4))); | ||||
|                 } | ||||
|             } | ||||
|             if (DataY[^1] != DataY[^2]) { | ||||
|                 data.Add(new KeyValuePair<string, JsonNode?>(DataX[^1] + Mode.ToString().ToLower(), Math.Round(DataY[^1], 4))); | ||||
|                 data.Add(new KeyValuePair<string, JsonNode?>(DataX[^1] + mode, Math.Round(DataY[^1], 4))); | ||||
|             } | ||||
|  | ||||
|             graph["data"] = data; | ||||
|  | ||||
|             return graph; | ||||
|             return data; | ||||
|         } | ||||
|  | ||||
|         public object Clone() { | ||||
|             return new Graph(Id, Mode, MinX, MaxX, Contracts.ConvertAll(item => new Tuple<string, string>(item.Item1, item.Item2)), (double[])DataX.Clone(), (double[])DataY.Clone()); | ||||
|             return new Graph((double[])DataX.Clone(), (double[])DataY.Clone()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										66
									
								
								Elwig/Helpers/Billing/GraphEntry.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								Elwig/Helpers/Billing/GraphEntry.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Text.Json.Nodes; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace Elwig.Helpers.Billing { | ||||
|     public class GraphEntry { | ||||
|  | ||||
|         public int Id { get; set; } | ||||
|         public BillingData.CurveMode Mode { get; set; } | ||||
|         public Graph DataGraph { get; set; } | ||||
|         public Graph? GebundenGraph { get; set; } | ||||
|         public decimal? GebundenFlatPrice { get; set; } | ||||
|         public List<string> Contracts { get; set; } | ||||
|         private int MinX { get; set; } | ||||
|         private int MaxX { get; set; } | ||||
|  | ||||
|         public GraphEntry(int id, BillingData.CurveMode mode, int minX, int maxX) { | ||||
|             Id = id; | ||||
|             Mode = mode; | ||||
|             MinX = minX; | ||||
|             MaxX = maxX; | ||||
|             DataGraph = new Graph(minX, maxX); | ||||
|             Contracts = []; | ||||
|         } | ||||
|  | ||||
|         public GraphEntry(int id, BillingData.CurveMode mode, Dictionary<double, decimal> data, int minX, int maxX) : this(id, mode, minX, maxX) { | ||||
|             DataGraph = new Graph(data, minX, maxX); | ||||
|         } | ||||
|  | ||||
|         private GraphEntry(int id, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph, | ||||
|             decimal? gebundenFlatPrice, List<string> contracts, int minX, int maxX) { | ||||
|             Id = id; | ||||
|             Mode = mode; | ||||
|             MinX = minX; | ||||
|             MaxX = maxX; | ||||
|             DataGraph = dataGraph; | ||||
|             GebundenGraph = gebundenGraph; | ||||
|             GebundenFlatPrice = gebundenFlatPrice; | ||||
|             Contracts = contracts; | ||||
|         } | ||||
|  | ||||
|         public JsonObject ToJson() { | ||||
|             var curve = new JsonObject { | ||||
|                 ["id"] = Id, | ||||
|                 ["mode"] = Mode.ToString().ToLower(), | ||||
|             }; | ||||
|  | ||||
|             curve["data"] = DataGraph.ToJson(Mode.ToString().ToLower()); | ||||
|  | ||||
|             if (GebundenFlatPrice != null) { | ||||
|                 curve["geb"] = GebundenFlatPrice.ToString(); | ||||
|             } else if (GebundenGraph != null) { | ||||
|                 curve["geb"] = GebundenGraph.ToJson(Mode.ToString().ToLower()); | ||||
|             } | ||||
|  | ||||
|             return curve; | ||||
|         } | ||||
|  | ||||
|         public GraphEntry Copy(int id) { | ||||
|             return new GraphEntry(id, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), GebundenFlatPrice, Contracts, MinX, MaxX); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,4 +1,4 @@ | ||||
| <local:AdministrationWindow | ||||
| <local:ContextWindow | ||||
|         x:Class="Elwig.Windows.ChartWindow" | ||||
|         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||||
|         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||
| @@ -8,7 +8,7 @@ | ||||
|         xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" | ||||
|         xmlns:ScottPlot="clr-namespace:ScottPlot;assembly=ScottPlot.WPF" | ||||
|         mc:Ignorable="d" | ||||
|         Title="Auszahlung - Elwig" Height="700" Width="1500" | ||||
|         Title="Auszahlung - Elwig" Height="700" Width="1500" MinWidth="1000" MinHeight="500" | ||||
|         Loaded="Window_Loaded"> | ||||
|  | ||||
|     <Window.Resources> | ||||
| @@ -43,94 +43,77 @@ | ||||
|  | ||||
|     <Grid> | ||||
|         <Grid.RowDefinitions> | ||||
|             <RowDefinition Height="19"/> | ||||
|             <RowDefinition Height="40"/> | ||||
|             <RowDefinition Height="*"/> | ||||
|         </Grid.RowDefinitions> | ||||
|         <Grid.ColumnDefinitions> | ||||
|             <ColumnDefinition Width="330"/> | ||||
|             <ColumnDefinition Width="230"/> | ||||
|             <ColumnDefinition Width="1*"/> | ||||
|             <ColumnDefinition Width="200"/> | ||||
|         </Grid.ColumnDefinitions> | ||||
|  | ||||
|         <Grid Grid.Row="1" Margin="5,0,0,0"> | ||||
|             <Grid.RowDefinitions> | ||||
|                 <RowDefinition Height="*"/> | ||||
|                 <RowDefinition Height="42"/> | ||||
|             </Grid.RowDefinitions> | ||||
|         <Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"> | ||||
|             <Grid.ColumnDefinitions> | ||||
|                 <ColumnDefinition Width="*"/> | ||||
|                 <ColumnDefinition Width="*"/> | ||||
|                 <ColumnDefinition Width="*"/> | ||||
|                 <ColumnDefinition Width="150"/> | ||||
|                 <ColumnDefinition Width="500"/> | ||||
|             </Grid.ColumnDefinitions> | ||||
|              | ||||
|             <DataGrid x:Name="GraphList" AutoGenerateColumns="False" HeadersVisibility="Column" IsReadOnly="True" GridLinesVisibility="None" SelectionMode="Single" | ||||
|                       CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False" | ||||
|                       SelectionChanged="GraphList_SelectionChanged" | ||||
|                       Margin="5,15,5,0" Grid.Row="0" FontSize="14" Grid.ColumnSpan="3"> | ||||
|                 <DataGrid.Columns> | ||||
|                     <DataGridTextColumn Header="Nr."    Binding="{Binding Id}"       Width="40"> | ||||
|                         <DataGridTextColumn.ElementStyle> | ||||
|                             <Style> | ||||
|                                 <Setter Property="TextBlock.TextWrapping" Value="Wrap" /> | ||||
|                             </Style> | ||||
|                         </DataGridTextColumn.ElementStyle> | ||||
|                     </DataGridTextColumn> | ||||
|                     <DataGridTextColumn Header="Modus"    Binding="{Binding Mode}"       Width="40"/> | ||||
|                     <DataGridTextColumn Header="Angewandte Verträge" Binding="{Binding Contracts}" Width="4*"/> | ||||
|                 </DataGrid.Columns> | ||||
|             </DataGrid> | ||||
|  | ||||
|             <Button x:Name="NewButton" Content="Neu" | ||||
|                     HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="2" | ||||
|                     Click="NewButton_Click"/> | ||||
|             <Button x:Name="EditButton" Content="Bearbeiten" IsEnabled="False" | ||||
|                     HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,2.5,10" Grid.Column="1" Grid.Row="2" | ||||
|                     Click="EditButton_Click"/> | ||||
|             <Button x:Name="DeleteButton" Content="Löschen" IsEnabled="False" | ||||
|                     HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,5,10" Grid.Column="2" Grid.Row="2" | ||||
|                     Click="DeleteButton_Click"/> | ||||
|             <Label Content="Graph:" Margin="10,0,0,0" FontSize="14" Grid.Column="0" VerticalAlignment="Center"/> | ||||
|             <TextBlock x:Name="GraphNum" Margin="0,0,40,0" FontSize="14" Width="50" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right"/> | ||||
|  | ||||
|             <Button x:Name="SaveButton" Content="Speichern" IsEnabled="False" Visibility="Hidden" | ||||
|                     HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="2" | ||||
|                     Click="SaveButton_Click"/> | ||||
|             <Button x:Name="ResetButton" Content="Zurücksetzen" IsEnabled="False" Visibility="Hidden" | ||||
|                     HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,2.5,10" Grid.Column="1" Grid.Row="2" | ||||
|                     Click="ResetButton_Click"/> | ||||
|             <Button x:Name="CancelButton" Content="Abbrechen" IsEnabled="False" Visibility="Hidden" IsCancel="True" | ||||
|                     HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,5,10" Grid.Column="2" Grid.Row="2" | ||||
|                     Click="CancelButton_Click"/> | ||||
|             <Label Content="Für:" Margin="10,0,0,0" FontSize="14" Grid.Column="1" VerticalAlignment="Center"/> | ||||
|             <xctk:CheckComboBox x:Name="AppliedInput" Margin="0,10,10,10" Grid.Column="1" | ||||
|                                         Delimiter=", " AllItemsSelectedContent="Alle" | ||||
|                                         Width="400" HorizontalAlignment="Right"> | ||||
|                 <!--<xctk:CheckComboBox.ItemTemplate> | ||||
|                     <DataTemplate> | ||||
|                         <StackPanel Orientation="Horizontal"> | ||||
|                             <TextBlock Text="{}" Width="40"/> | ||||
|                         </StackPanel> | ||||
|                     </DataTemplate> | ||||
|                 </xctk:CheckComboBox.ItemTemplate>--> | ||||
|             </xctk:CheckComboBox> | ||||
|         </Grid> | ||||
|  | ||||
|         <ListBox x:Name="GraphList" Margin="10,10,35,50" Grid.Column="0" Grid.Row="1" SelectionChanged="GraphList_SelectionChanged"> | ||||
|             <ListBox.ItemTemplate> | ||||
|                 <DataTemplate> | ||||
|                     <StackPanel Orientation="Horizontal"> | ||||
|                         <TextBlock Text="{Binding Id}" Width="40"/> | ||||
|                         <TextBlock Text="{Binding Contracts}" Width="100"/> | ||||
|                     </StackPanel> | ||||
|                 </DataTemplate> | ||||
|             </ListBox.ItemTemplate> | ||||
|         </ListBox> | ||||
|  | ||||
|         <Button x:Name="SaveButton" Content="Speichern" IsEnabled="True" | ||||
|             HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="10,5,35,15" Grid.Column="0" Grid.Row="2" | ||||
|             Click="SaveButton_Click"/> | ||||
|  | ||||
|         <Button x:Name="AddButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" ToolTip="Neue Auszahlungsvariante hinzufügen" | ||||
|             VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,0,5,60" Grid.Column="0" Grid.Row="1" | ||||
|             Click="AddButton_Click"/> | ||||
|         <Button x:Name="CopyButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="12" Padding="0,0,0,0" IsEnabled="False" ToolTip="Ausgewählte Auszahlungsvariante duplizieren" | ||||
|             VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="0,0,5,0" Grid.Column="0" Grid.Row="1" | ||||
|             Click="CopyButton_Click"/> | ||||
|         <Button x:Name="DeleteButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" IsEnabled="False" ToolTip="Ausgewählte Auszahlungsvariante löschen" | ||||
|                 VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,60,5,0" Grid.Column="0" Grid.Row="1" | ||||
|                 Click="DeleteButton_Click"/> | ||||
|  | ||||
|         <Grid Grid.Row="1" Grid.Column="1"> | ||||
|             <ScottPlot:WpfPlot x:Name="OechslePricePlot" MouseMove="OechslePricePlot_MouseMove" MouseDown="OechslePricePlot_MouseDown" IsEnabled="False"/> | ||||
|         </Grid> | ||||
|  | ||||
|         <Grid Grid.Row="1" Grid.Column="2" Margin="0,0,5,0"> | ||||
|         <Grid Grid.Row="1" Grid.Column="2" Margin="0,0,5,36"> | ||||
|             <Grid.RowDefinitions> | ||||
|                 <RowDefinition Height="120"/> | ||||
|                 <RowDefinition Height="120"/> | ||||
|                 <RowDefinition Height="90"/> | ||||
|                 <RowDefinition Height="210"/> | ||||
|                 <RowDefinition Height="1*"/> | ||||
|                 <RowDefinition Height="110"/> | ||||
|                 <RowDefinition Height="42"/> | ||||
|             </Grid.RowDefinitions> | ||||
|  | ||||
|             <GroupBox Header="Graph" Grid.Row="0" Margin="0,5,5,5"> | ||||
|                 <Grid> | ||||
|                     <Grid.ColumnDefinitions> | ||||
|                         <ColumnDefinition Width="85"/> | ||||
|                         <ColumnDefinition Width="*"/> | ||||
|                     </Grid.ColumnDefinitions> | ||||
|  | ||||
|                     <Label Content="Nummer:" Margin="10,10,0,0" Grid.Column="0"/> | ||||
|                     <TextBox x:Name="GraphNumberInput" Grid.Column="1" HorizontalAlignment="Left" Margin="0,10,0,0" Text="" Width="90" TextChanged="GraphNumberInput_TextChanged" LostFocus="GraphNumberInput_LostFocus"/> | ||||
|  | ||||
|                     <Label Content="Typ:" Margin="10,45,0,0" Grid.Column="0"/> | ||||
|                     <RadioButton x:Name="OechsleGraphType_Input" GroupName="GraphType" Grid.Column="1" Margin="0,45,0,0">Oechsle</RadioButton> | ||||
|                     <RadioButton x:Name="KmwGraphType_Input" GroupName="GraphType" Grid.Column="1" Margin="0,60,0,0">KMW</RadioButton> | ||||
|                 </Grid> | ||||
|             </GroupBox> | ||||
|  | ||||
|             <GroupBox Header="Datenpunkt" Grid.Row="1" Margin="0,5,5,5"> | ||||
|             <GroupBox Header="Datenpunkt" Grid.Row="0" Margin="0,5,5,5"> | ||||
|                 <Grid> | ||||
|                     <Grid.ColumnDefinitions> | ||||
|                         <ColumnDefinition Width="85"/> | ||||
| @@ -146,6 +129,23 @@ | ||||
|                 </Grid> | ||||
|             </GroupBox> | ||||
|  | ||||
|             <GroupBox Header="Gebunden" Grid.Row="1" Margin="0,5,5,5"> | ||||
|                 <Grid> | ||||
|                     <Grid.ColumnDefinitions> | ||||
|                         <ColumnDefinition Width="85"/> | ||||
|                         <ColumnDefinition Width="*"/> | ||||
|                     </Grid.ColumnDefinitions> | ||||
|  | ||||
|                     <StackPanel Margin="10,10,0,0"> | ||||
|                         <RadioButton GroupName="GebundenType">Fix</RadioButton> | ||||
|                         <RadioButton GroupName="GebundenType">Graph</RadioButton> | ||||
|                         <RadioButton GroupName="GebundenType" IsChecked="True">Nein</RadioButton> | ||||
|                     </StackPanel> | ||||
|  | ||||
|                     <TextBox x:Name="GebundenBonus" IsReadOnly="True" Grid.Column="1" HorizontalAlignment="Left" Margin="0,12,0,0" Text="" Width="90" TextChanged="GebundenBonus_TextChanged"/> | ||||
|                  </Grid> | ||||
|             </GroupBox> | ||||
|  | ||||
|             <GroupBox Header="Aktionen" Grid.Row="2" Margin="0,5,5,5"> | ||||
|                 <Grid> | ||||
|                     <Grid.ColumnDefinitions> | ||||
| @@ -166,7 +166,7 @@ | ||||
|                 </Grid> | ||||
|             </GroupBox> | ||||
|  | ||||
|             <GroupBox Header="Optionen" Grid.Row="3" Margin="0,5,5,5"> | ||||
|             <GroupBox Header="Optionen" Grid.Row="4" Margin="0,5,5,5"> | ||||
|                 <Grid> | ||||
|                     <Grid.ColumnDefinitions> | ||||
|                         <ColumnDefinition Width="*"/> | ||||
| @@ -186,4 +186,4 @@ | ||||
|             </GroupBox> | ||||
|         </Grid> | ||||
|     </Grid> | ||||
| </local:AdministrationWindow> | ||||
| </local:ContextWindow> | ||||
|   | ||||
| @@ -17,10 +17,11 @@ using ScottPlot; | ||||
| using ScottPlot.Plottable; | ||||
|  | ||||
| namespace Elwig.Windows { | ||||
|     public partial class ChartWindow : AdministrationWindow { | ||||
|     public partial class ChartWindow : ContextWindow { | ||||
|  | ||||
|         public readonly int Year; | ||||
|         public readonly int AvNr; | ||||
|         private readonly PaymentVar PaymentVar; | ||||
|  | ||||
|         private ScatterPlot OechslePricePlotScatter; | ||||
|         private MarkerPlot HighlightedPoint; | ||||
| @@ -38,21 +39,18 @@ namespace Elwig.Windows { | ||||
|         private const int MinOechsle = 50; | ||||
|         private const int MaxOechsle = 140; | ||||
|  | ||||
|         private Graph? Graph; | ||||
|         private List<GraphEntry> GraphEntries = []; | ||||
|         private GraphEntry? SelectedGraphEntry; | ||||
|  | ||||
|         public ChartWindow(int year, int avnr) { | ||||
|             InitializeComponent(); | ||||
|             Year = year; | ||||
|             AvNr = avnr; | ||||
|             var v = Context.PaymentVariants.Find(year, avnr); | ||||
|             Title = $"{v?.Name} - Lese {year} - Elwig"; | ||||
|             ExemptInputs = [ | ||||
|                 GraphList, OechsleInput, PriceInput, FreeZoomInput, GradationLinesInput, TooltipInput | ||||
|             ]; | ||||
|             PaymentVar = Context.PaymentVariants.Find(year, avnr) ?? throw new ArgumentException("PaymentVar not found"); | ||||
|             Title = $"{PaymentVar?.Name} - Lese {year} - Elwig"; | ||||
|         } | ||||
|  | ||||
|         private void Window_Loaded(object sender, RoutedEventArgs evt) { | ||||
|             LockInputs(); | ||||
|             OechslePricePlot.IsEnabled = false; | ||||
|         } | ||||
|  | ||||
| @@ -70,20 +68,27 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private async Task RefreshGraphListQuery(bool updateSort = false) { | ||||
|             var paymentVar = await Context.PaymentVariants.FindAsync(Year, AvNr); | ||||
|             if (paymentVar == null) return; | ||||
|             var data = ParseData(paymentVar); | ||||
|             var data = ParseData(PaymentVar); | ||||
|             if (data == null) return; | ||||
|  | ||||
|             var curves = BillingData.GetCurves(data, BillingData.CalculationMode.Elwig); | ||||
|             List<Graph> graphs = []; | ||||
|  | ||||
|             foreach (var (id, curve) in curves) { | ||||
|                 graphs.Add(new Graph(id, curve.Mode, curve.Normal, MinOechsle, MaxOechsle)); | ||||
|                 GraphEntries.Add(new GraphEntry(id, curve.Mode, curve.Normal, MinOechsle, MaxOechsle)); | ||||
|             } | ||||
|  | ||||
|             ControlUtils.RenewItemsSource(GraphList, graphs, g => (g as Graph)?.Id); | ||||
|             if (graphs.Count == 1) { | ||||
|             var attrVariants = Context.DeliveryParts | ||||
|                 .Where(d => d.Year == Year) | ||||
|                 .Select(d => $"{d.SortId}{d.AttrId}") | ||||
|                 .Distinct() | ||||
|                 .ToList() | ||||
|                 .Union(Context.WineVarieties.Select(v => v.SortId)) | ||||
|                 .Order() | ||||
|                 .ToList(); | ||||
|             ControlUtils.RenewItemsSource(AppliedInput, attrVariants, g => (g as GraphEntry)?.Id); | ||||
|  | ||||
|             ControlUtils.RenewItemsSource(GraphList, GraphEntries, g => (g as GraphEntry)?.Id); | ||||
|             if (GraphEntries.Count == 1) { | ||||
|                 GraphList.SelectedIndex = 0; | ||||
|             } | ||||
|  | ||||
| @@ -91,201 +96,46 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private string ParseContracts(JsonObject auszahlungsSorten, int num) { | ||||
|             List<string> contracts = []; | ||||
|  | ||||
|             foreach (var sorte in auszahlungsSorten) { | ||||
|                 if (sorte.Key == "Kurven") continue; | ||||
|                 foreach (var attribut in sorte.Value.AsObject()) { | ||||
|                     foreach (var bindung in attribut.Value.AsObject()) { | ||||
|                         if ((int)bindung.Value.AsValue() == num) { | ||||
|                             contracts.Add($"{sorte.Key}/{attribut.Key}/{bindung.Key}"); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return string.Join("\n", contracts); | ||||
|         } | ||||
|  | ||||
|         private async Task<bool> RemoveGraph(int num) { | ||||
|             var paymentVar = await Context.PaymentVariants.FindAsync(Year, AvNr); | ||||
|             if (paymentVar == null) return false; | ||||
|             var data = ParseData(paymentVar); | ||||
|             if (data == null) return false; | ||||
|  | ||||
|             MessageBox.Show("1"); | ||||
|  | ||||
|  | ||||
|             JsonArray? curves; | ||||
|             JsonObject? payment; | ||||
|  | ||||
|             if (data["mode"]?.GetValue<string>() == "elwig") { | ||||
|                 curves = data["curves"]?.AsArray(); | ||||
|                 payment = data["payment"]?.AsObject(); | ||||
|             } else if (data["mode"]?.GetValue<string>() == "wgmaster") { | ||||
|                 curves = data["Kurven"]?.AsArray(); | ||||
|                 payment = data["AuszahlungSorten"]?.AsObject(); | ||||
|             } else { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             MessageBox.Show("2"); | ||||
|  | ||||
|  | ||||
|             if (curves == null || payment == null) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             MessageBox.Show("3"); | ||||
|  | ||||
|             foreach (var curve in curves) { | ||||
|                 MessageBox.Show("LOOP"); | ||||
|                 if (curve?.AsObject()?["id"]?.GetValue<int>() == num) { | ||||
|                     MessageBox.Show(curve.ToJsonString()); | ||||
|                     curves.Remove(curve); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             MessageBox.Show("4"); | ||||
|  | ||||
|             var keysToRemove = new List<string>(); | ||||
|             foreach (var sorte in payment) { | ||||
|                 MessageBox.Show(sorte.Value.GetType().ToString()); | ||||
|                 if (sorte.Value.AsValue().TryGetValue(out string? curve) && curve.Equals($"curve:{num}")) { | ||||
|                     keysToRemove.Add(sorte.Key); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             foreach (var key in keysToRemove) { | ||||
|                 payment.Remove(key); | ||||
|             } | ||||
|  | ||||
|             MessageBox.Show("5"); | ||||
|  | ||||
|             EntityEntry<PaymentVar>? tr = null; | ||||
|             try { | ||||
|                 paymentVar.Data = data.ToString(); | ||||
|                 tr = Context.Update(paymentVar); | ||||
|  | ||||
|                 await Context.SaveChangesAsync(); | ||||
|                 await App.HintContextChange(); | ||||
|             } catch (Exception exc) { | ||||
|                 if (tr != null) await tr.ReloadAsync(); | ||||
|                 var str = "Der Eintrag konnte nicht in der Datenbank gelöscht werden!\n\n" + exc.Message; | ||||
|                 if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; | ||||
|                 MessageBox.Show(str, "Graph löschen", MessageBoxButton.OK, MessageBoxImage.Error); | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         private async Task<int?> UpdateGraph(Graph g) { | ||||
|             var paymentVar = await Context.PaymentVariants.FindAsync(Year, AvNr); | ||||
|             if (paymentVar == null) return null; | ||||
|  | ||||
|             var data = ParseData(paymentVar); | ||||
|             if (data == null) return null; | ||||
|  | ||||
|             JsonArray? curves; | ||||
|             JsonObject? payment; | ||||
|              | ||||
|             if (data["mode"]?.GetValue<string>() == "elwig") { | ||||
|                 curves = data["curves"]?.AsArray(); | ||||
|                 payment = data["payment"]?.AsObject(); | ||||
|             } else if (data["mode"]?.GetValue<string>() == "wgmaster") { | ||||
|                 curves = data["Kurven"]?.AsArray(); | ||||
|                 payment = data["AuszahlungSorten"]?.AsObject(); | ||||
|             } else { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             if (curves == null || payment == null) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             if (IsEditing) { | ||||
|                 int i = 0; | ||||
|                 foreach (var curve in curves) { | ||||
|                     if (curve?.AsObject()?["id"]?.GetValue<int>() == g.Id) { | ||||
|                         curves[i] = g.ToJson(); | ||||
|                         break; | ||||
|                     } | ||||
|                     i++; | ||||
|                 } | ||||
|             } else if(IsCreating) { | ||||
|                 curves.Add(g.ToJson()); | ||||
|             } else { | ||||
|                 return null; | ||||
|             } | ||||
|              | ||||
|             EntityEntry<PaymentVar>? tr = null; | ||||
|             try { | ||||
|                 paymentVar.Data = data.ToString(); | ||||
|                 tr = Context.Update(paymentVar); | ||||
|  | ||||
|                 await Context.SaveChangesAsync(); | ||||
|                 await App.HintContextChange(); | ||||
|             } catch (Exception exc) { | ||||
|                 if (tr != null) await tr.ReloadAsync(); | ||||
|                 var str = "Der Eintrag konnte nicht in der Datenbank gelöscht werden!\n\n" + exc.Message; | ||||
|                 if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; | ||||
|                 MessageBox.Show(str, "Graph löschen", MessageBoxButton.OK, MessageBoxImage.Error); | ||||
|             } | ||||
|  | ||||
|             return g.Id; | ||||
|             return ""; | ||||
|         } | ||||
|  | ||||
|         | ||||
|         private void RefreshInputs(bool validate = false) { | ||||
|             ResetPlot(); | ||||
|             ClearInputStates(); | ||||
|             if (GraphList.SelectedItem is Graph g) { | ||||
|                 EditButton.IsEnabled = true; | ||||
|                 DeleteButton.IsEnabled = true; | ||||
|                 EnableOptionButtons(); | ||||
|                 FillInputs(g); | ||||
|             } else { | ||||
|                 EditButton.IsEnabled = false; | ||||
|             if (!PaymentVar.TestVariant) { | ||||
|                 AddButton.IsEnabled = false; | ||||
|                 CopyButton.IsEnabled = false; | ||||
|                 DeleteButton.IsEnabled = false; | ||||
|                 OechsleInput.IsReadOnly = true; | ||||
|                 PriceInput.IsReadOnly = true; | ||||
|             } else if (SelectedGraphEntry != null) { | ||||
|                 CopyButton.IsEnabled = true; | ||||
|                 DeleteButton.IsEnabled = true; | ||||
|                 OechsleInput.IsReadOnly = false; | ||||
|                 EnableOptionButtons(); | ||||
|                 FillInputs(); | ||||
|             } else { | ||||
|                 CopyButton.IsEnabled = false; | ||||
|                 DeleteButton.IsEnabled = false; | ||||
|                 OechsleInput.IsReadOnly = true; | ||||
|                 DisableOptionButtons(); | ||||
|                 ClearOriginalValues(); | ||||
|                 ClearInputs(validate); | ||||
|                 ClearInputStates(); | ||||
|             } | ||||
|             GC.Collect(); | ||||
|         } | ||||
|  | ||||
|         private void FillInputs(Graph g) { | ||||
|             ClearOriginalValues(); | ||||
|  | ||||
|             Graph = (Graph)g.Clone(); | ||||
|              | ||||
|             GraphNumberInput.Text = Graph.Id.ToString(); | ||||
|             if (Graph.Mode == BillingData.CurveMode.Oe) { | ||||
|                 OechsleGraphType_Input.IsChecked = true; | ||||
|             } else if (Graph.Mode == BillingData.CurveMode.Kmw) { | ||||
|                 KmwGraphType_Input.IsChecked = true; | ||||
|             } | ||||
|         private void FillInputs() { | ||||
|             GraphNum.Text = SelectedGraphEntry.Id.ToString(); | ||||
|  | ||||
|             InitPlot(); | ||||
|             OechslePricePlot.IsEnabled = true; | ||||
|  | ||||
|             FinishInputFilling(); | ||||
|         } | ||||
|  | ||||
|         private void InitInputs() { | ||||
|             GraphNumberInput.Text = (GraphList.Items.Count + 1).ToString(); | ||||
|             OechsleGraphType_Input.IsChecked = true; | ||||
|             FinishInputFilling(); | ||||
|         } | ||||
|  | ||||
|         protected override async Task OnRenewContext() { | ||||
|             await base.OnRenewContext(); | ||||
|             await RefreshGraphList(); | ||||
|         } | ||||
|  | ||||
|         private void InitPlot() { | ||||
|             OechslePricePlotScatter = OechslePricePlot.Plot.AddScatter(Graph.DataX, Graph.DataY); | ||||
|             OechslePricePlotScatter = OechslePricePlot.Plot.AddScatter(SelectedGraphEntry.DataGraph.DataX, SelectedGraphEntry.DataGraph.DataY); | ||||
|  | ||||
|             OechslePricePlot.Configuration.DoubleClickBenchmark = false; | ||||
|             OechslePricePlotScatter.LineColor = Color.Blue; | ||||
| @@ -326,7 +176,6 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private void ResetPlot() { | ||||
|             Graph = null; | ||||
|             PrimaryMarkedPointIndex = -1; | ||||
|             OechslePricePlot.Plot.Remove(OechslePricePlotScatter); | ||||
|             OechslePricePlot.Plot.Clear(); | ||||
| @@ -341,16 +190,12 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private void FlattenGraph(int begin, int end, double value) { | ||||
|             for (int i = begin; i <= end; i++) { | ||||
|                 Graph.DataY[i] = value; | ||||
|             } | ||||
|             SelectedGraphEntry.DataGraph.FlattenGraph(begin, end, value); | ||||
|             OechslePricePlot.Render(); | ||||
|         } | ||||
|  | ||||
|         private void LinearIncreaseGraph(int begin, int end, double inc) { | ||||
|             for (int i = begin; i < end; i++) { | ||||
|                 Graph.DataY[i + 1] = Graph.DataY[i] + inc; | ||||
|             } | ||||
|             SelectedGraphEntry.DataGraph.LinearIncreaseGraph(begin, end, inc); | ||||
|             OechslePricePlot.Render(); | ||||
|         } | ||||
|  | ||||
| @@ -441,8 +286,6 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private void OechsleInput_TextChanged(object sender, TextChangedEventArgs evt) { | ||||
|             IntegerInput_TextChanged(sender, evt); | ||||
|  | ||||
|             bool success = int.TryParse(OechsleInput.Text, out int oechsle); | ||||
|  | ||||
|             SecondaryMarkedPointIndex = -1; | ||||
| @@ -451,12 +294,13 @@ namespace Elwig.Windows { | ||||
|             if (success) { | ||||
|                 if (oechsle >= MinOechsle && oechsle <= MaxOechsle) { | ||||
|                     PrimaryMarkedPointIndex = oechsle - MinOechsle; | ||||
|                     ChangeMarker(PrimaryMarkedPoint, true, Graph.DataX[PrimaryMarkedPointIndex], Graph.DataY[PrimaryMarkedPointIndex]); | ||||
|                     ChangeMarker(PrimaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[PrimaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]); | ||||
|  | ||||
|                     PriceInput.Text = Graph.DataY[PrimaryMarkedPointIndex].ToString(); | ||||
|                     PriceInput.Text = SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex].ToString(); | ||||
|  | ||||
|                     if (IsEditing || IsCreating) EnableActionButtons(); | ||||
|                     EnableActionButtons(); | ||||
|                     OechslePricePlot.Render(); | ||||
|                     PriceInput.IsReadOnly = false; | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
| @@ -466,6 +310,7 @@ namespace Elwig.Windows { | ||||
|             DisableActionButtons(); | ||||
|             PriceInput.Text = ""; | ||||
|             OechslePricePlot.Render(); | ||||
|             PriceInput.IsReadOnly = true; | ||||
|         } | ||||
|  | ||||
|         private void PriceInput_TextChanged(object sender, RoutedEventArgs evt) { | ||||
| @@ -473,10 +318,8 @@ namespace Elwig.Windows { | ||||
|                 bool success = Double.TryParse(PriceInput.Text, out double price); | ||||
|  | ||||
|                 if (success) { | ||||
|                     Graph.DataY[PrimaryMarkedPointIndex] = price; | ||||
|                     SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex] = price; | ||||
|                     PrimaryMarkedPoint.Y = price; | ||||
|                     SaveButton.IsEnabled = true; | ||||
|                     ResetButton.IsEnabled = true; | ||||
|                     OechslePricePlot.Refresh(); | ||||
|                 } | ||||
|             } | ||||
| @@ -486,18 +329,14 @@ namespace Elwig.Windows { | ||||
|             if (PrimaryMarkedPointIndex == -1) { | ||||
|                 return; | ||||
|             } | ||||
|             FlattenGraph(0, PrimaryMarkedPointIndex, Graph.DataY[PrimaryMarkedPointIndex]); | ||||
|             SaveButton.IsEnabled = true; | ||||
|             ResetButton.IsEnabled = true; | ||||
|             FlattenGraph(0, PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]); | ||||
|         } | ||||
|  | ||||
|         private void RightFlatButton_Click(object sender, RoutedEventArgs evt) { | ||||
|             if (PrimaryMarkedPointIndex == -1) { | ||||
|                 return; | ||||
|             } | ||||
|             FlattenGraph(PrimaryMarkedPointIndex, Graph.DataY.Length - 1, Graph.DataY[PrimaryMarkedPointIndex]); | ||||
|             SaveButton.IsEnabled = true; | ||||
|             ResetButton.IsEnabled = true; | ||||
|             FlattenGraph(PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY.Length - 1, SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]); | ||||
|         } | ||||
|  | ||||
|         private void InterpolateButton_Click(object sender, RoutedEventArgs evt) { | ||||
| @@ -507,13 +346,11 @@ namespace Elwig.Windows { | ||||
|             } | ||||
|             var (lowIndex, highIndex) = PrimaryMarkedPointIndex < SecondaryMarkedPointIndex ? (PrimaryMarkedPointIndex, SecondaryMarkedPointIndex): (SecondaryMarkedPointIndex, PrimaryMarkedPointIndex); | ||||
|  | ||||
|             double step = (Graph.DataY[highIndex] - Graph.DataY[lowIndex]) / steps; | ||||
|             double step = (SelectedGraphEntry.DataGraph.DataY[highIndex] - SelectedGraphEntry.DataGraph.DataY[lowIndex]) / steps; | ||||
|  | ||||
|             for (int i = lowIndex; i < highIndex - 1; i++) { | ||||
|                 Graph.DataY[i + 1] = Math.Round(Graph.DataY[i] + step, 4); // TODO richtig runden | ||||
|                 SelectedGraphEntry.DataGraph.DataY[i + 1] = Math.Round(SelectedGraphEntry.DataGraph.DataY[i] + step, 4); // TODO richtig runden | ||||
|             } | ||||
|             SaveButton.IsEnabled = true; | ||||
|             ResetButton.IsEnabled = true; | ||||
|         } | ||||
|  | ||||
|         private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) {  | ||||
| @@ -524,23 +361,21 @@ namespace Elwig.Windows { | ||||
|             if (priceIncrease == null) { | ||||
|                 return; | ||||
|             } | ||||
|             LinearIncreaseGraph(PrimaryMarkedPointIndex, Graph.DataY.Length - 1, priceIncrease.Value); | ||||
|             SaveButton.IsEnabled = true; | ||||
|             ResetButton.IsEnabled = true; | ||||
|             LinearIncreaseGraph(PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY.Length - 1, priceIncrease.Value); | ||||
|         } | ||||
|  | ||||
|         private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) { | ||||
|             if (!IsCreating && GraphList.SelectedItem == null) { | ||||
|             if (GraphList.SelectedItem == null) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (HoverActive) { | ||||
|                 if ((IsEditing || IsCreating) && Keyboard.IsKeyDown(Key.LeftCtrl)) { | ||||
|                 if (PaymentVar.TestVariant && Keyboard.IsKeyDown(Key.LeftCtrl)) { | ||||
|                     if (PrimaryMarkedPointIndex == -1) { | ||||
|                         return; | ||||
|                     } | ||||
|                     SecondaryMarkedPointIndex = HighlightedIndex; | ||||
|                     ChangeMarker(SecondaryMarkedPoint, true, Graph.DataX[SecondaryMarkedPointIndex], Graph.DataY[SecondaryMarkedPointIndex]); | ||||
|                     ChangeMarker(SecondaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[SecondaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[SecondaryMarkedPointIndex]); | ||||
|  | ||||
|                     InterpolateButton.IsEnabled = true; | ||||
|  | ||||
| @@ -548,12 +383,12 @@ namespace Elwig.Windows { | ||||
|                 } | ||||
|  | ||||
|                 PrimaryMarkedPointIndex = HighlightedIndex; | ||||
|                 ChangeMarker(PrimaryMarkedPoint, true, Graph.DataX[PrimaryMarkedPointIndex], Graph.DataY[PrimaryMarkedPointIndex]); | ||||
|                 ChangeMarker(PrimaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[PrimaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]); | ||||
|  | ||||
|                 OechsleInput.Text = Graph.DataX[HighlightedIndex].ToString(); | ||||
|                 PriceInput.Text = Graph.DataY[HighlightedIndex].ToString(); | ||||
|                 OechsleInput.Text = SelectedGraphEntry.DataGraph.DataX[HighlightedIndex].ToString(); | ||||
|                 PriceInput.Text = SelectedGraphEntry.DataGraph.DataY[HighlightedIndex].ToString(); | ||||
|  | ||||
|                 if (IsEditing || IsCreating) { | ||||
|                 if (PaymentVar.TestVariant) { | ||||
|                     EnableActionButtons(); | ||||
|                 } | ||||
|             } else { | ||||
| @@ -570,7 +405,7 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private void OechslePricePlot_MouseMove(object sender, MouseEventArgs e) { | ||||
|             if (!IsCreating && GraphList.SelectedItem == null) { | ||||
|             if (GraphList.SelectedItem == null) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
| @@ -607,144 +442,45 @@ namespace Elwig.Windows { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         override protected void UpdateButtons() { | ||||
|             if (!IsEditing && !IsCreating) return; | ||||
|             bool ch = HasChanged, v = IsValid; | ||||
|         private int getMaxGraphId() { | ||||
|             return GraphEntries.Count == 0 ? 0 : GraphEntries.Select(g => g.Id).Max(); | ||||
|         } | ||||
|  | ||||
|         private void DisableNewEditDeleteButtons() { | ||||
|             NewButton.IsEnabled = false; | ||||
|             EditButton.IsEnabled = false; | ||||
|             DeleteButton.IsEnabled = false; | ||||
|         private void AddButton_Click(object sender, RoutedEventArgs e) { | ||||
|             GraphEntry newGraphEntry = new(getMaxGraphId() + 1, BillingData.CurveMode.Oe, MinOechsle, MaxOechsle); | ||||
|             GraphEntries.Add(newGraphEntry); | ||||
|             GraphList.Items.Refresh(); | ||||
|             GraphList.SelectedItem = newGraphEntry; | ||||
|         } | ||||
|  | ||||
|         private void EnableNewEditDeleteButtons() { | ||||
|             NewButton.IsEnabled = true; | ||||
|             EditButton.IsEnabled = GraphList.SelectedItem != null; | ||||
|             DeleteButton.IsEnabled = GraphList.SelectedItem != null; | ||||
|         private void CopyButton_Click(object sender, RoutedEventArgs e) { | ||||
|             if (SelectedGraphEntry == null) return; | ||||
|  | ||||
|             GraphEntry newGraphEntry = SelectedGraphEntry.Copy(getMaxGraphId() + 1); | ||||
|             GraphEntries.Add(newGraphEntry); | ||||
|             GraphList.Items.Refresh(); | ||||
|             GraphList.SelectedItem = newGraphEntry; | ||||
|         } | ||||
|  | ||||
|         private void ShowSaveResetCancelButtons() { | ||||
|             SaveButton.IsEnabled = false; | ||||
|             ResetButton.IsEnabled = false; | ||||
|             CancelButton.IsEnabled = true; | ||||
|             SaveButton.Visibility = Visibility.Visible; | ||||
|             ResetButton.Visibility = Visibility.Visible; | ||||
|             CancelButton.Visibility = Visibility.Visible; | ||||
|         } | ||||
|  | ||||
|         private void HideSaveResetCancelButtons() { | ||||
|             SaveButton.IsEnabled = false; | ||||
|             ResetButton.IsEnabled = false; | ||||
|             CancelButton.IsEnabled = false; | ||||
|             SaveButton.Visibility = Visibility.Hidden; | ||||
|             ResetButton.Visibility = Visibility.Hidden; | ||||
|             CancelButton.Visibility = Visibility.Hidden; | ||||
|         } | ||||
|         private void ShowNewEditDeleteButtons() { | ||||
|             EnableNewEditDeleteButtons(); | ||||
|             NewButton.Visibility = Visibility.Visible; | ||||
|             EditButton.Visibility = Visibility.Visible; | ||||
|             DeleteButton.Visibility = Visibility.Visible; | ||||
|         } | ||||
|  | ||||
|         private void HideNewEditDeleteButtons() { | ||||
|             DisableNewEditDeleteButtons(); | ||||
|             NewButton.Visibility = Visibility.Hidden; | ||||
|             EditButton.Visibility = Visibility.Hidden; | ||||
|             DeleteButton.Visibility = Visibility.Hidden; | ||||
|         } | ||||
|  | ||||
|         private void NewButton_Click(object sender, RoutedEventArgs e) { | ||||
|             IsCreating = true; | ||||
|             GraphList.IsEnabled = false; | ||||
|             GraphList.SelectedItem = null; | ||||
|             HideNewEditDeleteButtons(); | ||||
|             ShowSaveResetCancelButtons(); | ||||
|             UnlockInputs(); | ||||
|             PriceInput.IsReadOnly = false; | ||||
|             OechsleInput.IsReadOnly = false; | ||||
|             InitInputs(); | ||||
|             FillInputs(new Graph(GraphList.Items.Count + 1, BillingData.CurveMode.Oe, MinOechsle, MaxOechsle)); //TODO not hardcode oe | ||||
|             EnableOptionButtons(); | ||||
|         } | ||||
|  | ||||
|         private void EditButton_Click(object sender, RoutedEventArgs e) { | ||||
|             if (GraphList.SelectedItem == null) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             IsEditing = true; | ||||
|             GraphList.IsEnabled = false; | ||||
|  | ||||
|             HideNewEditDeleteButtons(); | ||||
|             ShowSaveResetCancelButtons(); | ||||
|             UnlockInputs(); | ||||
|             PriceInput.IsReadOnly = false; | ||||
|             OechsleInput.IsReadOnly = false; | ||||
|             if (PrimaryMarkedPointIndex != -1) EnableActionButtons(); | ||||
|         } | ||||
|  | ||||
|         private async void DeleteButton_Click(object sender, RoutedEventArgs e) { | ||||
|             Graph g = (Graph)GraphList.SelectedItem; | ||||
|             if (g == null) return; | ||||
|         private void DeleteButton_Click(object sender, RoutedEventArgs e) { | ||||
|             if (SelectedGraphEntry == null) return; | ||||
|  | ||||
|             var r = MessageBox.Show( | ||||
|                 $"Soll der Graph {g.Id} (verwendet in folgenden Verträgen: {g.Contracts}) wirklich unwiderruflich gelöscht werden?", | ||||
|                 $"Soll der Graph {SelectedGraphEntry.Id} (verwendet in folgenden Verträgen: {SelectedGraphEntry.Contracts}) wirklich gelöscht werden?", | ||||
|                 "Graph löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No); | ||||
|  | ||||
|             if (r == MessageBoxResult.Yes) { | ||||
|                 bool success = await RemoveGraph(g.Id); | ||||
|                 if (!success) { | ||||
|                     MessageBox.Show("Der Graph konnte nicht gelöscht werden", "Graph löschen", MessageBoxButton.OK, MessageBoxImage.Error); | ||||
|                 } | ||||
|                 await RefreshGraphList(); | ||||
|                 GraphEntries.Remove(SelectedGraphEntry); | ||||
|                 GraphList.Items.Refresh(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         private async void SaveButton_Click(object sender, RoutedEventArgs e) { | ||||
|             int? index = await UpdateGraph(Graph); | ||||
|             if (index == null) { | ||||
|                 MessageBox.Show("Der Graph konnte nicht gespeichert werden", "Graph speichern", MessageBoxButton.OK, MessageBoxImage.Error); | ||||
|             } | ||||
|             IsEditing = false; | ||||
|             IsCreating = false; | ||||
|             GraphList.IsEnabled = true; | ||||
|             HideSaveResetCancelButtons(); | ||||
|             ShowNewEditDeleteButtons(); | ||||
|             LockInputs(); | ||||
|             PriceInput.IsReadOnly = true; | ||||
|             OechsleInput.IsReadOnly = true; | ||||
|             await RefreshGraphList(); | ||||
|             GraphList.SelectedIndex = index.Value; | ||||
|         private void SaveButton_Click(object sender, RoutedEventArgs e) { | ||||
|             //TODO SAVE | ||||
|         } | ||||
|  | ||||
|         private void ResetButton_Click(object sender, RoutedEventArgs e) { | ||||
|             if (IsEditing) { | ||||
|                 RefreshInputs(); | ||||
|             } else if (IsCreating) { | ||||
|                 InitInputs(); | ||||
|             } | ||||
|             UpdateButtons(); | ||||
|         } | ||||
|  | ||||
|         private void CancelButton_Click(object sender, RoutedEventArgs e) { | ||||
|             IsEditing = false; | ||||
|             IsCreating = false; | ||||
|             GraphList.IsEnabled = true; | ||||
|             HideSaveResetCancelButtons(); | ||||
|             ShowNewEditDeleteButtons(); | ||||
|             DisableActionButtons(); | ||||
|             RefreshInputs(); | ||||
|             PriceInput.Text = ""; | ||||
|             OechsleInput.Text = ""; | ||||
|             ClearInputStates(); | ||||
|             LockInputs(); | ||||
|             PriceInput.IsReadOnly = true; | ||||
|             OechsleInput.IsReadOnly = true; | ||||
|         } | ||||
|  | ||||
|         private void GraphList_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) { | ||||
|         private void GraphList_SelectionChanged(object sender, SelectionChangedEventArgs e) { | ||||
|             SelectedGraphEntry = (GraphEntry)GraphList.SelectedItem; | ||||
|             RefreshInputs(); | ||||
|  | ||||
|             //var x = OechslePricePlot.Plot.GetPlottables().OfType<ScatterPlot>(); | ||||
| @@ -759,11 +495,7 @@ namespace Elwig.Windows { | ||||
|  | ||||
|         } | ||||
|  | ||||
|         private void GraphNumberInput_TextChanged(object sender, TextChangedEventArgs e) { | ||||
|  | ||||
|         } | ||||
|  | ||||
|         private void GraphNumberInput_LostFocus(object sender, RoutedEventArgs e) { | ||||
|         private void GebundenBonus_TextChanged(object sender, TextChangedEventArgs evt) { | ||||
|  | ||||
|         } | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user