diff --git a/Elwig/Dialogs/LinearPriceIncreaseDialog.xaml b/Elwig/Dialogs/LinearPriceIncreaseDialog.xaml new file mode 100644 index 0000000..b6dd04a --- /dev/null +++ b/Elwig/Dialogs/LinearPriceIncreaseDialog.xaml @@ -0,0 +1,53 @@ +<Window x:Class="Elwig.Dialogs.LinearPriceIncreaseDialog" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:local="clr-namespace:Elwig.Dialogs" + mc:Ignorable="d" + ResizeMode="NoResize" + ShowInTaskbar="False" + Topmost="True" + WindowStartupLocation="CenterOwner" + FocusManager.FocusedElement="{Binding ElementName=PriceInput}" + Title="Linear wachsen" Height="140" Width="270"> + <Window.Resources> + <Style TargetType="Label"> + <Setter Property="HorizontalAlignment" Value="Left"/> + <Setter Property="VerticalAlignment" Value="Top"/> + <Setter Property="Padding" Value="2,4,2,4"/> + <Setter Property="Height" Value="25"/> + </Style> + <Style TargetType="TextBox"> + <Setter Property="HorizontalAlignment" Value="Stretch"/> + <Setter Property="VerticalAlignment" Value="Top"/> + <Setter Property="FontSize" Value="14"/> + <Setter Property="Padding" Value="2"/> + <Setter Property="Height" Value="25"/> + <Setter Property="TextWrapping" Value="NoWrap"/> + </Style> + <Style TargetType="Button"> + <Setter Property="HorizontalAlignment" Value="Right"/> + <Setter Property="VerticalAlignment" Value="Bottom"/> + <Setter Property="Width" Value="100"/> + <Setter Property="Height" Value="25"/> + </Style> + </Window.Resources> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="55"/> + <ColumnDefinition/> + </Grid.ColumnDefinitions> + + <Label Content="Preis:" Margin="10,20,10,10"/> + <Grid Grid.Column="1" Width="145" Height="25" Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"> + <TextBox x:Name="PriceInput" TextAlignment="Right" Padding="2,2,30,2" + TextChanged="PriceInput_TextChanged"/> + <Label Content="€/kg" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10" Padding="2,4,2,4"/> + </Grid> + + <Button x:Name="ConfirmButton" Content="Bestätigen" Margin="17,0,133,10" IsEnabled="False" IsDefault="True" + Click="ConfirmButton_Click" Grid.ColumnSpan="2" HorizontalAlignment="Stretch"/> + <Button x:Name="CancelButton" Content="Abbrechen" Margin="0,0,20,10" Grid.Column="1" IsCancel="True"/> + </Grid> +</Window> diff --git a/Elwig/Dialogs/LinearPriceIncreaseDialog.xaml.cs b/Elwig/Dialogs/LinearPriceIncreaseDialog.xaml.cs new file mode 100644 index 0000000..d782d6a --- /dev/null +++ b/Elwig/Dialogs/LinearPriceIncreaseDialog.xaml.cs @@ -0,0 +1,30 @@ +using Elwig.Helpers; +using System.Text.RegularExpressions; +using System.Windows; +using System.Windows.Controls; + +namespace Elwig.Dialogs { + public partial class LinearPriceIncreaseDialog : Window { + + public double Price = 0.0; + + public LinearPriceIncreaseDialog() { + InitializeComponent(); + } + + private void ConfirmButton_Click(object sender, RoutedEventArgs evt) { + DialogResult = true; + Price = double.Parse(PriceInput.Text.Replace("\u202f", "")); + Close(); + } + + private void UpdateButtons(ValidationResult res) { + ConfirmButton.IsEnabled = res.IsValid; + } + + private void PriceInput_TextChanged(object sender, TextChangedEventArgs evt) { + var res = Validator.CheckDecimal(PriceInput, true, 2, 8); + UpdateButtons(res); + } + } +} diff --git a/Elwig/Elwig.csproj b/Elwig/Elwig.csproj index d40916e..9c80baf 100644 --- a/Elwig/Elwig.csproj +++ b/Elwig/Elwig.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> @@ -7,7 +7,7 @@ <UseWPF>true</UseWPF> <PreserveCompilationContext>true</PreserveCompilationContext> <ApplicationIcon>elwig.ico</ApplicationIcon> - <Version>0.0.1</Version> + <Version>0.0.2</Version> <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages> </PropertyGroup> @@ -25,6 +25,7 @@ <PackageReference Include="PdfSharp" Version="1.50.5147" /> <PackageReference Include="PuppeteerSharp" Version="11.0.2" /> <PackageReference Include="RazorLight" Version="2.3.1" /> + <PackageReference Include="ScottPlot.WPF" Version="4.1.67" /> <PackageReference Include="System.IO.Ports" Version="7.0.0" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" /> </ItemGroup> diff --git a/Elwig/Helpers/AppDbContext.cs b/Elwig/Helpers/AppDbContext.cs index c0ea1b1..2225e94 100644 --- a/Elwig/Helpers/AppDbContext.cs +++ b/Elwig/Helpers/AppDbContext.cs @@ -42,6 +42,7 @@ namespace Elwig.Helpers { public DbSet<DeliveryPart> DeliveryParts { get; private set; } public DbSet<DeliveryPartAttr> DeliveryPartAttributes { get; private set; } public DbSet<DeliveryPartModifier> DeliveryPartModifiers { get; private set; } + public DbSet<PaymentVar> PaymentVariants { get; private set; } private readonly StreamWriter? LogFile = null; public static DateTime LastWriteTime => File.GetLastWriteTime(App.Config.DatabaseFile); diff --git a/Elwig/Helpers/Utils.cs b/Elwig/Helpers/Utils.cs index e374648..5423d99 100644 --- a/Elwig/Helpers/Utils.cs +++ b/Elwig/Helpers/Utils.cs @@ -223,6 +223,11 @@ namespace Elwig.Helpers { return d.ShowDialog() == true ? d.Weight : null; } + public static double? ShowLinearPriceIncreaseDialog() { + var d = new LinearPriceIncreaseDialog(); + return d.ShowDialog() == true ? d.Price : null; + } + public static string? ShowDeliveryExtractionDialog(string lsnr, string name, bool single, IEnumerable<string> lsnrs) { var d = new DeliveryExtractionDialog(lsnr, name, single, lsnrs); return d.ShowDialog() == true ? d.AddTo : null; diff --git a/Elwig/Models/Graph.cs b/Elwig/Models/Graph.cs new file mode 100644 index 0000000..d87ea6d --- /dev/null +++ b/Elwig/Models/Graph.cs @@ -0,0 +1,123 @@ +using Newtonsoft.Json.Linq; +using ScottPlot; +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Markup; + +namespace Elwig.Models { + public class Graph : ICloneable { + + public string Type { get; set; } + public int Num { get; set; } + private int MinX { get; set; } + private int MaxX { get; set; } + public string Contracts { get; set; } + public double[] DataX { get; set; } + public double[] DataY { get; set; } + + public Graph(int num, int minX, int maxX) { + Type = "oe"; + Num = num; + Contracts = ""; + MinX = minX; + MaxX = maxX; + + DataX = DataGen.Range(MinX, MaxX + 1); + DataY = DataGen.Zeros(MaxX - MinX + 1); + } + + public Graph(string type, int num, JToken graphData, string contracts, int minX, int maxX) { + Type = type; + Num = num; + Contracts = contracts; + MinX = minX; + MaxX = maxX; + + DataX = DataGen.Range(MinX, MaxX + 1); + DataY = DataGen.Zeros(MaxX - MinX + 1); + ParseGraphData(graphData); + } + + public Graph(string type, int num, int minX, int maxX, string contracts, double[] dataX, double[] dataY) { + Type = type; + Num = num; + MinX = minX; + MaxX = maxX; + Contracts = contracts; + DataX = dataX; + DataY = dataY; + } + + private void ParseGraphData(JToken graphData) { + var GraphPoints = graphData.Children().OfType<JProperty>().ToDictionary(p => int.Parse(p.Name[..^2]), p => (double)p.Value); + + if (GraphPoints.Keys.Count < 1) { + return; + } + + 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(MaxX)) { + GraphPoints.Add(MaxX, GraphPoints.GetValueOrDefault(maxKey)); + } + + var keys = GraphPoints.Keys.Order().ToArray(); + + for (int i = 0; i < keys.Length; i++) { + double point1Value = GraphPoints[keys[i]]; + if (i + 1 < keys.Length) { + double point2Value = GraphPoints[keys[i + 1]]; + if (point1Value == point2Value) { + for (int j = keys[i] - MinX; j < keys[i + 1] - MinX; j++) { + DataY[j] = point1Value; + } + } else { + int steps = Math.Abs(keys[i + 1] - keys[i]); + double step = (point2Value - point1Value) / steps; + + DataY[keys[i] - MinX] = point1Value; + DataY[keys[i + 1] - MinX] = point2Value; + + for (int j = keys[i] - MinX; j < keys[i + 1] - MinX - 1; j++) { + DataY[j + 1] = Math.Round(DataY[j] + step, 4); // TODO richtig runden + } + } + } + else { + for (int j = keys[i] - MinX; j < DataX.Length; j++) { + DataY[j] = point1Value; + } + } + } + } + + public JObject ToJson() { + JObject graph = new(); + + if (DataY[0] != DataY[1]) { + graph.Add(new JProperty(DataX[0] + Type.ToLower(), Math.Round(DataY[0], 4))); + } + for (int i = 1; i < DataX.Length - 1; i++) { + if (Math.Round(DataY[i] - DataY[i - 1], 4) != Math.Round(DataY[i + 1] - DataY[i], 4)) { + graph.Add(new JProperty(DataX[i] + Type.ToLower(), Math.Round(DataY[i], 4))); + } + } + if (DataY[^1] != DataY[^2]) { + graph.Add(new JProperty(DataX[^1] + Type.ToLower(), Math.Round(DataY[^1], 4))); + } + return graph; + } + + public object Clone() { + return new Graph(Type, Num, MinX, MaxX, Contracts, (double[])DataX.Clone(), (double[])DataY.Clone()); + } + } +} diff --git a/Elwig/Models/PaymentVar.cs b/Elwig/Models/PaymentVar.cs new file mode 100644 index 0000000..689b6ca --- /dev/null +++ b/Elwig/Models/PaymentVar.cs @@ -0,0 +1,69 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Elwig.Models { + [Table("payment_variant"), PrimaryKey("Year", "AvNr")] + public class PaymentVar { + [Column("year")] + public int Year { get; set; } + + [Column("avnr")] + public int AvNr { get; set; } + + [Column("name")] + public string Name { get; set; } + + [Column("date")] + public string DateString { get; set; } + + [NotMapped] + public DateOnly Date { + get { + return DateOnly.ParseExact(DateString, "yyyy-MM-dd"); + } + set { + DateString = value.ToString("yyyy-MM-dd"); + } + } + + [Column("test_variant")] + public bool TestVariant { get; set; } + + [Column("calc_time")] + public int? CalcTime { get; set; } + + [Column("bucket_1_name")] + public string? Bucket1Name { get; set; } + + [Column("bucket_2_name")] + public string? Bucket2Name { get; set; } + + [Column("bucket_3_name")] + public string? Bucket3Name { get; set; } + + [Column("bucket_4_name")] + public string? Bucket4Name { get; set; } + + [Column("bucket_5_name")] + public string? Bucket5Name { get; set; } + + [Column("bucket_6_name")] + public string? Bucket6Name { get; set; } + + [Column("bucket_7_name")] + public string? Bucket7Name { get; set; } + + [Column("bucket_8_name")] + public string? Bucket8Name { get; set; } + + [Column("bucket_9_name")] + public string? Bucket9Name { get; set; } + + [Column("comment")] + public string? Comment { get; set; } + + [Column("data")] + public string Data { get; set; } + } +} diff --git a/Elwig/Windows/ChartWindow.xaml b/Elwig/Windows/ChartWindow.xaml new file mode 100644 index 0000000..c6515b1 --- /dev/null +++ b/Elwig/Windows/ChartWindow.xaml @@ -0,0 +1,188 @@ +<local:AdministrationWindow x:Class="Elwig.Windows.ChartWindow" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:local="clr-namespace:Elwig.Windows" + 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" + Loaded="Window_Loaded"> + + <Window.Resources> + <Style TargetType="Label"> + <Setter Property="HorizontalAlignment" Value="Left"/> + <Setter Property="VerticalAlignment" Value="Top"/> + <Setter Property="Padding" Value="2,4,2,4"/> + <Setter Property="Height" Value="25"/> + </Style> + <Style TargetType="TextBox"> + <Setter Property="HorizontalAlignment" Value="Stretch"/> + <Setter Property="VerticalAlignment" Value="Top"/> + <Setter Property="FontSize" Value="14"/> + <Setter Property="Padding" Value="2"/> + <Setter Property="IsReadOnly" Value="True"/> + <Setter Property="Height" Value="25"/> + <Setter Property="TextWrapping" Value="NoWrap"/> + </Style> + <Style TargetType="ComboBox"> + <Setter Property="IsEnabled" Value="False"/> + <Setter Property="Height" Value="25"/> + <Setter Property="FontSize" Value="14"/> + <Setter Property="HorizontalAlignment" Value="Stretch"/> + <Setter Property="VerticalAlignment" Value="Top"/> + </Style> + <Style TargetType="Button"> + <Setter Property="FontSize" Value="14"/> + <Setter Property="Padding" Value="9,3"/> + <Setter Property="Height" Value="27"/> + </Style> + </Window.Resources> + + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="19"/> + <RowDefinition Height="*"/> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="330"/> + <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.ColumnDefinitions> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="*"/> + </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 Num}" Width="40"> + <DataGridTextColumn.ElementStyle> + <Style> + <Setter Property="TextBlock.TextWrapping" Value="Wrap" /> + </Style> + </DataGridTextColumn.ElementStyle> + </DataGridTextColumn> + <DataGridTextColumn Header="Typ" Binding="{Binding Type}" 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"/> + + <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"/> + </Grid> + + <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.RowDefinitions> + <RowDefinition Height="120"/> + <RowDefinition Height="120"/> + <RowDefinition Height="210"/> + <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"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="85"/> + <ColumnDefinition Width="*"/> + </Grid.ColumnDefinitions> + + <Label Content="Oechsle:" Margin="10,10,0,0" Grid.Column="0"/> + <TextBox x:Name="OechsleInput" Grid.Column="1" HorizontalAlignment="Left" Margin="0,10,0,0" Text="" Width="90" TextChanged="OechsleInput_TextChanged" LostFocus="OechsleInput_LostFocus"/> + + <Label Content="Preis pro kg:" Margin="10,40,0,0" Grid.Column="0"/> + <TextBox x:Name="PriceInput" Grid.Column="1" HorizontalAlignment="Left" Margin="0,40,0,0" Text="" Width="90" TextChanged="PriceInput_TextChanged" LostFocus="PriceInput_LostFocus"/> + + </Grid> + </GroupBox> + + <GroupBox Header="Aktionen" Grid.Row="2" Margin="0,5,5,5"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*"/> + </Grid.ColumnDefinitions> + + <Button x:Name="LeftFlatButton" Content="Links flach" Click="LeftFlatButton_Click" IsEnabled="False" + HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10,10,10,10"/> + + <Button x:Name="RightFlatButton" Content="Rechts flach" Click="RightFlatButton_Click" IsEnabled="False" + HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10,50,10,10"/> + + <Button x:Name="InterpolateButton" Content="Interpolieren" Click="InterpolateButton_Click" IsEnabled="False" + HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10,90,10,10"/> + + <Button x:Name="LinearIncreaseButton" Content="Linear wachsen" Click="LinearIncreaseButton_Click" IsEnabled="False" + HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10,130,10,10"/> + </Grid> + </GroupBox> + + <GroupBox Header="Optionen" Grid.Row="3" Margin="0,5,5,5"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*"/> + </Grid.ColumnDefinitions> + + <CheckBox x:Name="FreeZoomInput" Content="Freier Zoom" IsEnabled="False" + Checked="FreeZoomInput_Changed" Unchecked="FreeZoomInput_Changed" + HorizontalAlignment="Left" Margin="10,10,10,0" VerticalAlignment="Top"/> + + <CheckBox x:Name="GradationLinesInput" Content="Gradationslinien anzeigen" IsEnabled="False" + Checked="GradationLinesInput_Changed" Unchecked="GradationLinesInput_Changed" + HorizontalAlignment="Left" Margin="10,30,10,0" VerticalAlignment="Top" IsChecked="True"/> + + <CheckBox x:Name="TooltipInput" Content="Tooltips anzeigen" IsEnabled="False" + HorizontalAlignment="Left" Margin="10,50,10,0" VerticalAlignment="Top" IsChecked="True"/> + </Grid> + </GroupBox> + </Grid> + </Grid> +</local:AdministrationWindow> diff --git a/Elwig/Windows/ChartWindow.xaml.cs b/Elwig/Windows/ChartWindow.xaml.cs new file mode 100644 index 0000000..9010918 --- /dev/null +++ b/Elwig/Windows/ChartWindow.xaml.cs @@ -0,0 +1,750 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Diagnostics.Contracts; +using System.Drawing; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using Elwig.Helpers; +using Elwig.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Newtonsoft.Json.Linq; +using ScottPlot; +using ScottPlot.Plottable; + +namespace Elwig.Windows { + public partial class ChartWindow : AdministrationWindow { + + private readonly int Year = 2021; + private readonly int AvNr = 2; + + private ScatterPlot OechslePricePlotScatter; + private MarkerPlot HighlightedPoint; + private MarkerPlot PrimaryMarkedPoint; + private MarkerPlot SecondaryMarkedPoint; + private Tooltip Tooltip; + + private int LastHighlightedIndex = -1; + private int HighlightedIndex = -1; + private int PrimaryMarkedPointIndex = -1; + private int SecondaryMarkedPointIndex = -1; + private bool HoverChanged = false; + private bool HoverActive = false; + + private const int MinOechsle = 50; + private const int MaxOechsle = 140; + + private Graph? Graph; + + public ChartWindow() { + InitializeComponent(); + + ExemptInputs = new Control[] { + GraphList, OechsleInput, PriceInput, FreeZoomInput, GradationLinesInput, TooltipInput + }; + } + + private void Window_Loaded(object sender, RoutedEventArgs evt) { + LockInputs(); + OechslePricePlot.IsEnabled = false; + } + + private async Task RefreshGraphList() { + await Context.PaymentVariants.LoadAsync(); + await RefreshGraphListQuery(); + } + + private async Task RefreshGraphListQuery(bool updateSort = false) { + List<PaymentVar> paymentVars = await Context.PaymentVariants.Where(p => p.Year == Year && p.AvNr == AvNr).ToListAsync(); + + if (paymentVars.Count != 1) { + return; + } + + PaymentVar paymentVar = paymentVars[0]; + var data = JToken.Parse(paymentVar.Data); + + var auszahlungsSorten = data["AuszahlungSorten"]; + if (auszahlungsSorten == null) { + return; + } + + var Graphs = auszahlungsSorten["Kurven"]; + + if (Graphs == null) { + return; + } + + List<Graph> GraphsList = new(); + + int i = 1; + foreach (var graph in Graphs) { + GraphsList.Add(new Graph("Oe", i, graph, ParseContracts(auszahlungsSorten, i - 1), 50, 140)); + i++; + } + + ControlUtils.RenewItemsSource(GraphList, GraphsList, g => (g as Graph)?.Num); + if (GraphsList.Count == 1) { + GraphList.SelectedIndex = 0; + } + + RefreshInputs(); + } + + private String ParseContracts(JToken auszahlungsSorten, int num) { + List<string> contracts = new(); + + foreach (var sorte in auszahlungsSorten.Children().OfType<JToken>()) { + if (((JProperty)sorte).Name == "Kurven") { + continue; + } + foreach (var attribut in sorte.Values().OfType<JToken>()) { + foreach (var bindung in attribut.Values().OfType<JProperty>()) { + if ((int)(bindung).Value == num) { + contracts.Add($"{((JProperty)sorte).Name}/{((JProperty)attribut).Name}/{bindung.Name}"); + } + } + } + } + + return string.Join("\n", contracts.ToArray()); + } + + private async Task<bool> RemoveGraph(int num) { + List<PaymentVar> paymentVars = await Context.PaymentVariants.Where(p => p.Year == Year && p.AvNr == AvNr).ToListAsync(); + + if (paymentVars.Count != 1) { + return false; + } + + PaymentVar paymentVar = paymentVars[0]; + var data = JToken.Parse(paymentVar.Data); + + var auszahlungsSorten = data["AuszahlungSorten"]; + if (auszahlungsSorten == null) { + return false; + } + + var Graphs = auszahlungsSorten["Kurven"]; + + if (Graphs == null) { + return false; + } + + int i = 1; + foreach (var graph in Graphs) { + if (i == num) { + graph.Remove(); + break; + } + i++; + } + + foreach (var sorte in auszahlungsSorten.Children().OfType<JToken>()) { + if (((JProperty)sorte).Name == "Kurven") { + continue; + } + foreach (var attribut in sorte.Values().OfType<JToken>()) { + List<JProperty> itemsToRemove = new(); + foreach (var bindung in attribut.Values().OfType<JProperty>()) { + if ((int)bindung.Value == num - 1) { + itemsToRemove.Add(bindung); + } else if ((int)bindung.Value > num - 1) { + bindung.Value = (int)bindung.Value - 1; + } + } + itemsToRemove.ForEach(i => i.Remove()); + } + } + + EntityEntry<PaymentVar>? tr = null; + try { + paymentVar.Data = data.ToString(); + tr = Context.Update(paymentVar); + + await Context.SaveChangesAsync(); + } 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 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; + DeleteButton.IsEnabled = false; + DisableOptionButtons(); + ClearOriginalValues(); + ClearInputs(validate); + ClearInputStates(); + } + GC.Collect(); + } + + private void FillInputs(Graph g) { + ClearOriginalValues(); + + Graph = (Graph)g.Clone(); + + GraphNumberInput.Text = Graph.Num.ToString(); + if (Graph.Type == "oe") { + OechsleGraphType_Input.IsChecked = true; + } else if (Graph.Type == "kmw") { + KmwGraphType_Input.IsChecked = true; + } + + InitPlot(); + OechslePricePlot.IsEnabled = true; + + FinishInputFilling(); + } + + private void InitInputs() { + GraphNumberInput.Text = (GraphList.Items.Count + 1).ToString(); + OechsleGraphType_Input.IsChecked = true; + FinishInputFilling(); + } + + protected override async Task RenewContext() { + await base.RenewContext(); + await RefreshGraphList(); + } + + private void InitPlot() { + OechslePricePlotScatter = OechslePricePlot.Plot.AddScatter(Graph.DataX, Graph.DataY); + + OechslePricePlotScatter.LineColor = Color.Blue; + OechslePricePlotScatter.MarkerColor = Color.Blue; + OechslePricePlotScatter.MarkerSize = 9; + + //OechslePricePlot.Plot.XAxis.ManualTickSpacing(1); + OechslePricePlot.Plot.YAxis.ManualTickSpacing(0.1); + OechslePricePlot.Plot.SetAxisLimits(MinOechsle - 1, MaxOechsle + 1, -0.1, 2); + + OechslePricePlot.Plot.Layout(padding: 0); + OechslePricePlot.Plot.XAxis2.Layout(padding: 0); + OechslePricePlot.Plot.YAxis.Layout(padding: 0); + OechslePricePlot.Plot.YAxis2.Layout(padding: 0); + + HighlightedPoint = OechslePricePlot.Plot.AddPoint(0, 0); + HighlightedPoint.Color = Color.Red; + HighlightedPoint.MarkerSize = 10; + HighlightedPoint.MarkerShape = MarkerShape.openCircle; + HighlightedPoint.IsVisible = false; + + PrimaryMarkedPoint = OechslePricePlot.Plot.AddPoint(0, 0); + PrimaryMarkedPoint.Color = Color.Red; + PrimaryMarkedPoint.MarkerSize = 6; + PrimaryMarkedPoint.MarkerShape = MarkerShape.filledCircle; + PrimaryMarkedPoint.IsVisible = false; + + SecondaryMarkedPoint = OechslePricePlot.Plot.AddPoint(0, 0); + SecondaryMarkedPoint.Color = Color.Red; + SecondaryMarkedPoint.MarkerSize = 6; + SecondaryMarkedPoint.MarkerShape = MarkerShape.filledCircle; + SecondaryMarkedPoint.IsVisible = false; + + OechslePricePlot.Refresh(); + + RefreshFreeZoom(); + RefreshGradationLines(); + } + + private void ResetPlot() { + Graph = null; + PrimaryMarkedPointIndex = -1; + OechslePricePlot.Plot.Remove(OechslePricePlotScatter); + OechslePricePlot.Plot.Clear(); + OechslePricePlot.Reset(); + OechslePricePlot.Refresh(); + } + + private void ChangeMarker(MarkerPlot point, bool visible, double x = 0, double y = 0) { + point.X = x; + point.Y = y; + point.IsVisible = visible; + } + + private void FlattenGraph(int begin, int end, double value) { + for (int i = begin; i <= end; i++) { + Graph.DataY[i] = 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; + } + OechslePricePlot.Render(); + } + + private void EnableActionButtons() { + LeftFlatButton.IsEnabled = true; + RightFlatButton.IsEnabled = true; + LinearIncreaseButton.IsEnabled = true; + } + + private void DisableActionButtons() { + LeftFlatButton.IsEnabled = false; + RightFlatButton.IsEnabled = false; + InterpolateButton.IsEnabled = false; + LinearIncreaseButton.IsEnabled = false; + } + + private void FreeZoomInput_Changed(object sender, RoutedEventArgs evt) { + RefreshFreeZoom(); + } + + private void RefreshFreeZoom() { + if (FreeZoomInput.IsChecked == true) { + UnlockZoom(); + } else { + LockZoom(); + } + OechslePricePlot.Refresh(); + } + + private void LockZoom() { + OechslePricePlot.Plot.XAxis.SetBoundary(MinOechsle - 1, MaxOechsle + 1); + OechslePricePlot.Plot.YAxis.SetBoundary(-0.1, 2); + OechslePricePlot.Plot.XAxis.SetZoomOutLimit(MaxOechsle - MinOechsle + 2); + OechslePricePlot.Plot.YAxis.SetZoomOutLimit(2.1); + OechslePricePlot.Plot.SetAxisLimits(MinOechsle - 1, MaxOechsle + 1, -0.1, 2); + } + + private void UnlockZoom() { + OechslePricePlot.Plot.XAxis.SetBoundary(); + OechslePricePlot.Plot.YAxis.SetBoundary(); + OechslePricePlot.Plot.XAxis.SetZoomOutLimit((MaxOechsle - MinOechsle) * 1.5); + OechslePricePlot.Plot.YAxis.SetZoomOutLimit(3.5); + } + + private void EnableOptionButtons() { + FreeZoomInput.IsEnabled = true; + GradationLinesInput.IsEnabled = true; + TooltipInput.IsEnabled = true; + } + + private void DisableOptionButtons() { + FreeZoomInput.IsEnabled = false; + GradationLinesInput.IsEnabled = false; + TooltipInput.IsEnabled = false; + } + + private void GradationLinesInput_Changed(object sender, RoutedEventArgs evt) { + RefreshGradationLines(); + } + + private void RefreshGradationLines() { + if (GradationLinesInput.IsChecked == true) { + ShowGradationLines(); + ShowLegend(); + } else { + HideGradationLines(); + HideLegend(); + } + OechslePricePlot.Refresh(); + } + + private void ShowGradationLines() { + OechslePricePlot.Plot.AddVerticalLine(68, Color.Red, 2, label: "68 Oechsle (LDW)"); + OechslePricePlot.Plot.AddVerticalLine(73, Color.Orange, 2, label: "73 Oechsle (QUW)"); + OechslePricePlot.Plot.AddVerticalLine(84, Color.Green, 2, label: "84 Oechsle (KAB)"); + } + + private void HideGradationLines() { + OechslePricePlot.Plot.Clear(typeof(VLine)); + } + + private void ShowLegend() { + OechslePricePlot.Plot.Legend(true, Alignment.UpperRight); + } + + private void HideLegend() { + OechslePricePlot.Plot.Legend(false, Alignment.UpperRight); + } + + private void OechsleInput_TextChanged(object sender, RoutedEventArgs evt) { + IntegerInput_TextChanged(sender, evt); + + bool success = int.TryParse(OechsleInput.Text, out int oechsle); + + SecondaryMarkedPointIndex = -1; + ChangeMarker(SecondaryMarkedPoint, false); + + if (success) { + if (oechsle >= MinOechsle && oechsle <= MaxOechsle) { + PrimaryMarkedPointIndex = oechsle - MinOechsle; + ChangeMarker(PrimaryMarkedPoint, true, Graph.DataX[PrimaryMarkedPointIndex], Graph.DataY[PrimaryMarkedPointIndex]); + + PriceInput.Text = Graph.DataY[PrimaryMarkedPointIndex].ToString(); + + EnableActionButtons(); + OechslePricePlot.Render(); + return; + } + } + + PrimaryMarkedPointIndex = -1; + ChangeMarker(PrimaryMarkedPoint, false); + DisableActionButtons(); + PriceInput.Text = ""; + OechslePricePlot.Render(); + } + + private void PriceInput_TextChanged(object sender, RoutedEventArgs evt) { + if (PrimaryMarkedPointIndex != -1) { + bool success = Double.TryParse(PriceInput.Text, out double price); + + if (success) { + Graph.DataY[PrimaryMarkedPointIndex] = price; + PrimaryMarkedPoint.Y = price; + SaveButton.IsEnabled = true; + ResetButton.IsEnabled = true; + OechslePricePlot.Refresh(); + } + } + } + + private void LeftFlatButton_Click(object sender, RoutedEventArgs evt) { + if (PrimaryMarkedPointIndex == -1) { + return; + } + FlattenGraph(0, PrimaryMarkedPointIndex, Graph.DataY[PrimaryMarkedPointIndex]); + } + + private void RightFlatButton_Click(object sender, RoutedEventArgs evt) { + if (PrimaryMarkedPointIndex == -1) { + return; + } + FlattenGraph(PrimaryMarkedPointIndex, Graph.DataY.Length - 1, Graph.DataY[PrimaryMarkedPointIndex]); + } + + private void InterpolateButton_Click(object sender, RoutedEventArgs evt) { + int steps = Math.Abs(PrimaryMarkedPointIndex - SecondaryMarkedPointIndex); + if (PrimaryMarkedPointIndex == -1 || SecondaryMarkedPointIndex == -1 || steps < 2) { + return; + } + var (lowIndex, highIndex) = PrimaryMarkedPointIndex < SecondaryMarkedPointIndex ? (PrimaryMarkedPointIndex, SecondaryMarkedPointIndex): (SecondaryMarkedPointIndex, PrimaryMarkedPointIndex); + + double step = (Graph.DataY[highIndex] - Graph.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 + } + } + + private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) { + if (PrimaryMarkedPointIndex == -1) { + return; + } + double? priceIncrease = Utils.ShowLinearPriceIncreaseDialog(); + if (priceIncrease == null) { + return; + } + LinearIncreaseGraph(PrimaryMarkedPointIndex, Graph.DataY.Length - 1, priceIncrease.Value); + } + + private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) { + if (!IsCreating && GraphList.SelectedItem == null) { + return; + } + + if (HoverActive) { + if ((IsEditing || IsCreating) && Keyboard.IsKeyDown(Key.LeftCtrl)) { + if (PrimaryMarkedPointIndex == -1) { + return; + } + SecondaryMarkedPointIndex = HighlightedIndex; + ChangeMarker(SecondaryMarkedPoint, true, Graph.DataX[SecondaryMarkedPointIndex], Graph.DataY[SecondaryMarkedPointIndex]); + + InterpolateButton.IsEnabled = true; + + return; + } + + PrimaryMarkedPointIndex = HighlightedIndex; + ChangeMarker(PrimaryMarkedPoint, true, Graph.DataX[PrimaryMarkedPointIndex], Graph.DataY[PrimaryMarkedPointIndex]); + + OechsleInput.Text = Graph.DataX[HighlightedIndex].ToString(); + PriceInput.Text = Graph.DataY[HighlightedIndex].ToString(); + + if (IsEditing || IsCreating) { + EnableActionButtons(); + } + } else { + PrimaryMarkedPointIndex = -1; + SecondaryMarkedPointIndex = -1; + ChangeMarker(PrimaryMarkedPoint, false); + ChangeMarker(SecondaryMarkedPoint, false); + + OechsleInput.Text = ""; + PriceInput.Text = ""; + + DisableActionButtons(); + } + } + + private void OechslePricePlot_MouseMove(object sender, MouseEventArgs e) { + if (!IsCreating && GraphList.SelectedItem == null) { + return; + } + + (double mouseCoordX, double mouseCoordY) = OechslePricePlot.GetMouseCoordinates(); + double xyRatio = OechslePricePlot.Plot.XAxis.Dims.PxPerUnit / OechslePricePlot.Plot.YAxis.Dims.PxPerUnit; + (double pointX, double pointY, int pointIndex) = OechslePricePlotScatter.GetPointNearest(mouseCoordX, mouseCoordY, xyRatio); + + (double mousePixelX, double mousePixelY) = OechslePricePlot.GetMousePixel(); + (double pointPixelX, double pointPixelY) = OechslePricePlot.Plot.GetPixel(pointX, pointY); + + HighlightedIndex = LastHighlightedIndex; + + if (Math.Abs(mousePixelX - pointPixelX) < 3 && Math.Abs(mousePixelY - pointPixelY) < 3) { + ChangeMarker(HighlightedPoint, true, pointX, pointY); + HighlightedPoint.IsVisible = true; + HoverChanged = true ^ HoverActive; + HoverActive = true; + } else { + ChangeMarker(HighlightedPoint, false); + HoverChanged= false ^ HoverActive; + HoverActive= false; + OechslePricePlot.Plot.Remove(Tooltip); + OechslePricePlot.Render(); + } + + if (LastHighlightedIndex != HighlightedIndex || HoverChanged) { + OechslePricePlot.Plot.Remove(Tooltip); + if (TooltipInput.IsChecked == true) { + Tooltip = OechslePricePlot.Plot.AddTooltip($"Oechsle: {pointX:N2}, Preis: {Math.Round(pointY, 4)})", pointX, pointY); + } + LastHighlightedIndex = pointIndex; + HoverChanged = false; + OechslePricePlot.Render(); + } + } + + override protected void UpdateButtons() { + if (!IsEditing && !IsCreating) return; + bool ch = HasChanged, v = IsValid; + } + + private void DisableNewEditDeleteButtons() { + NewButton.IsEnabled = false; + EditButton.IsEnabled = false; + DeleteButton.IsEnabled = false; + } + + private void EnableNewEditDeleteButtons() { + NewButton.IsEnabled = true; + EditButton.IsEnabled = GraphList.SelectedItem != null; + DeleteButton.IsEnabled = GraphList.SelectedItem != null; + } + + 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, MinOechsle, MaxOechsle)); + 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; + + var r = MessageBox.Show( + $"Soll der Graph {g.Num} (verwendet in folgenden Verträgen: {g.Contracts}) wirklich unwiderruflich gelöscht werden?", + "Graph löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No); + if (r == MessageBoxResult.Yes) { + bool success = await RemoveGraph(g.Num); + if (!success) { + MessageBox.Show("Der Graph konnte nicht gelöscht werden", "Graph löschen", MessageBoxButton.OK, MessageBoxImage.Error); + } + await RefreshGraphList(); + } + } + + + 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 async Task<int?> UpdateGraph(Graph g) { + List<PaymentVar> paymentVars = await Context.PaymentVariants.Where(p => p.Year == Year && p.AvNr == AvNr).ToListAsync(); + + if (paymentVars.Count != 1) { + return null; + } + + PaymentVar paymentVar = paymentVars[0]; + var data = JToken.Parse(paymentVar.Data); + + var auszahlungsSorten = data["AuszahlungSorten"]; + if (auszahlungsSorten == null) { + return null; + } + + var Graphs = auszahlungsSorten["Kurven"]; + + if (Graphs == null) { + return null; + } + + if (IsEditing) { + ((JArray)Graphs)[g.Num - 1] = g.ToJson(); + } else if(IsCreating) { + ((JArray)Graphs).Add(g.ToJson()); + } else { + return null; + } + + EntityEntry<PaymentVar>? tr = null; + try { + paymentVar.Data = data.ToString(); + tr = Context.Update(paymentVar); + + await Context.SaveChangesAsync(); + } 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.Num - 1; + } + + 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) { + RefreshInputs(); + + //var x = OechslePricePlot.Plot.GetPlottables().OfType<ScatterPlot>(); + //MessageBox.Show($"SelectionChanged\nLength: {x.ToList().Count}, Ys: {string.Join(", ", ((ScatterPlot)x.First()).Ys)}"); + } + + private void PriceInput_LostFocus(object sender, RoutedEventArgs e) { + + } + + private void OechsleInput_LostFocus(object sender, RoutedEventArgs e) { + + } + + private void GraphNumberInput_TextChanged(object sender, TextChangedEventArgs e) { + + } + + private void GraphNumberInput_LostFocus(object sender, RoutedEventArgs e) { + + } + } +} diff --git a/Elwig/Windows/MainWindow.xaml b/Elwig/Windows/MainWindow.xaml index af15628..0f11a23 100644 --- a/Elwig/Windows/MainWindow.xaml +++ b/Elwig/Windows/MainWindow.xaml @@ -57,5 +57,7 @@ Margin="260,240,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/> <Button x:Name="QueryWindowButton" Content="Datenbankabfragen" Click="QueryWindowButton_Click" Margin="260,280,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/> + <Button x:Name="PaymentWindowButton" Content="Auszahlung" Click="PaymentWindowButton_Click" + Margin="260,320,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/> </Grid> </Window> diff --git a/Elwig/Windows/MainWindow.xaml.cs b/Elwig/Windows/MainWindow.xaml.cs index 5f32865..8ee1189 100644 --- a/Elwig/Windows/MainWindow.xaml.cs +++ b/Elwig/Windows/MainWindow.xaml.cs @@ -61,5 +61,10 @@ namespace Elwig.Windows { var w = new BaseDataWindow(); w.Show(); } + + private void PaymentWindowButton_Click(object sender, RoutedEventArgs e) { + var w = new ChartWindow(); + w.Show(); + } } } diff --git a/Elwig/Windows/TestWindow.xaml b/Elwig/Windows/TestWindow.xaml index 57e9680..72e75f0 100644 --- a/Elwig/Windows/TestWindow.xaml +++ b/Elwig/Windows/TestWindow.xaml @@ -16,5 +16,7 @@ <Button x:Name="WeighingButton1" Click="WeighingButton1_Click" Height="30" Content="Aktuelles Gewicht" Width="110" Margin="515,246,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/> <Button x:Name="WeighingButton2" Click="WeighingButton2_Click" Height="30" Content="Wiegen" Width="110" Margin="515,285,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/> <TextBlock x:Name="Output" Height="20" Width="200" Margin="470,329,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/> + <Button x:Name="ChartButton" Content="Chart" Click="ChartButton_Click" + Margin="50,240,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/> </Grid> </Window> diff --git a/Elwig/Windows/TestWindow.xaml.cs b/Elwig/Windows/TestWindow.xaml.cs index 30164ef..aede0be 100644 --- a/Elwig/Windows/TestWindow.xaml.cs +++ b/Elwig/Windows/TestWindow.xaml.cs @@ -34,5 +34,10 @@ namespace Elwig.Windows { MessageBoxButton.OK, MessageBoxImage.Error); } } + + private void ChartButton_Click(object sender, RoutedEventArgs evt) { + var w = new ChartWindow(); + w.Show(); + } } }