ChartWindow: Added second graph for gebunden
This commit is contained in:
		
							
								
								
									
										47
									
								
								Elwig/Helpers/Billing/ContractSelection.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Elwig/Helpers/Billing/ContractSelection.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
using Elwig.Models.Entities;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Helpers.Billing {
 | 
			
		||||
    public class ContractSelection : IComparable<ContractSelection> {
 | 
			
		||||
 | 
			
		||||
        public WineVar? Variety { get; }
 | 
			
		||||
        public WineAttr? Attribute { get; }
 | 
			
		||||
        public string Listing => Variety != null || Attribute != null ? $"{Variety?.SortId}{Attribute?.AttrId}" : "";
 | 
			
		||||
 | 
			
		||||
        public ContractSelection(WineVar? var, WineAttr? attr) {
 | 
			
		||||
            Variety = var;
 | 
			
		||||
            Attribute = attr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ContractSelection(WineVar var) {
 | 
			
		||||
            Variety = var;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ContractSelection(WineAttr attr) {
 | 
			
		||||
            Attribute = attr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ToString() {
 | 
			
		||||
            return (Variety != null ? $"{Variety.Name}" : "") + (Attribute != null ? $" {Attribute.Name}" : "");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static List<ContractSelection> GetContractsForYear(AppDbContext context, int year) {
 | 
			
		||||
            return context.DeliveryParts
 | 
			
		||||
                .Where(d => d.Year == year)
 | 
			
		||||
                .Select(d => new ContractSelection(d.Variant, d.Attribute))
 | 
			
		||||
                .Distinct()
 | 
			
		||||
                .ToList()
 | 
			
		||||
                .Union(context.WineVarieties.Select(v => new ContractSelection(v)))
 | 
			
		||||
                .ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int CompareTo(ContractSelection? other) {
 | 
			
		||||
            //MessageBox.Show($"{Listing} -- {other.Listing} : {Listing.CompareTo(other.Listing)}");
 | 
			
		||||
            return other != null ?
 | 
			
		||||
                Listing.CompareTo(other.Listing) :
 | 
			
		||||
                throw new ArgumentException();
 | 
			
		||||
        } 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -26,6 +26,22 @@ namespace Elwig.Helpers.Billing {
 | 
			
		||||
            DataY = dataY;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public double GetOechsleAt(int index) {
 | 
			
		||||
            return DataX[index];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetOechsleAt(int index, double oechsle) {
 | 
			
		||||
            DataX[index] = oechsle;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetPriceAt(int index, double price) {
 | 
			
		||||
            DataY[index] = price;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public double GetPriceAt(int index) {
 | 
			
		||||
            return DataY[index];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ParseGraphData(Dictionary<double, decimal> graphPoints, int minX, int maxX) {
 | 
			
		||||
            if (graphPoints.Keys.Count < 1) {
 | 
			
		||||
                return;
 | 
			
		||||
@@ -71,19 +87,48 @@ namespace Elwig.Helpers.Billing {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void FlattenGraph(int begin, int end, double value) {
 | 
			
		||||
        private 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) {
 | 
			
		||||
        public void FlattenGraphLeft(int pointIndex) {
 | 
			
		||||
            FlattenGraph(0, pointIndex, DataY[pointIndex]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void FlattenGraphRight(int pointIndex) {
 | 
			
		||||
            FlattenGraph(pointIndex, DataY.Length - 1, DataY[pointIndex]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void LinearIncreaseGraph(int begin, int end, double inc) {
 | 
			
		||||
            for (int i = begin; i < end; i++) {
 | 
			
		||||
                DataY[i + 1] = DataY[i] + inc;
 | 
			
		||||
                DataY[i + 1] = Math.Round(DataY[i] + inc, 4); //TODO richtig runden
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public JsonObject ToJson(string mode) {
 | 
			
		||||
        public void LinearIncreaseGraphToEnd(int begin, double inc) {
 | 
			
		||||
            LinearIncreaseGraph(begin, DataY.Length - 1, inc);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void InterpolateGraph(int firstPoint, int secondPoint) {
 | 
			
		||||
            int steps = Math.Abs(firstPoint - secondPoint);
 | 
			
		||||
            if (firstPoint == -1 || secondPoint == -1 || steps < 2) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var (lowIndex, highIndex) = firstPoint < secondPoint ? (firstPoint, secondPoint) : (secondPoint, firstPoint);
 | 
			
		||||
            double step = (DataY[highIndex] - DataY[lowIndex]) / steps;
 | 
			
		||||
 | 
			
		||||
            for (int i = lowIndex; i < highIndex - 1; i++) {
 | 
			
		||||
                DataY[i + 1] = Math.Round(DataY[i] + step, 4); // TODO richtig runden
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public JsonNode ToJson(string mode) {
 | 
			
		||||
            if (DataY.Distinct().Count() == 1) {
 | 
			
		||||
                return JsonValue.Create(DataY[0]);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var data = new JsonObject();
 | 
			
		||||
 | 
			
		||||
            if (DataY[0] != DataY[1]) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text.Json.Nodes;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Helpers.Billing {
 | 
			
		||||
@@ -8,8 +9,10 @@ namespace Elwig.Helpers.Billing {
 | 
			
		||||
        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; }
 | 
			
		||||
        public decimal? GebundenFlatBonus { get; set; }
 | 
			
		||||
        public List<ContractSelection> Contracts { get; set; }
 | 
			
		||||
        public string ContractsStringSimple => Contracts.Any() ? string.Join(", ", Contracts.Select(c => c.Listing)) : "-";
 | 
			
		||||
        public string ContractsString => Contracts.Any() ? string.Join("\n", Contracts.Select(c => c.ToString())) : "-";
 | 
			
		||||
        private int MinX { get; set; }
 | 
			
		||||
        private int MaxX { get; set; }
 | 
			
		||||
 | 
			
		||||
@@ -22,9 +25,10 @@ namespace Elwig.Helpers.Billing {
 | 
			
		||||
            Contracts = [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public GraphEntry(int id, BillingData.CurveMode mode, Dictionary<double, decimal> data, int minX, int maxX) :
 | 
			
		||||
            this(id, mode, minX, maxX) {
 | 
			
		||||
        public GraphEntry(int id, BillingData.CurveMode mode, Dictionary<double, decimal> data, Dictionary<double, decimal>? gebunden,
 | 
			
		||||
            int minX, int maxX) : this(id, mode, minX, maxX) {
 | 
			
		||||
            DataGraph = new Graph(data, minX, maxX);
 | 
			
		||||
            if (gebunden != null) GebundenGraph = new Graph(gebunden, minX, maxX);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public GraphEntry(int id, BillingData.Curve curve, int minX, int maxX) :
 | 
			
		||||
@@ -35,17 +39,29 @@ namespace Elwig.Helpers.Billing {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private GraphEntry(int id, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph,
 | 
			
		||||
                           decimal? gebundenFlatPrice, List<string> contracts, int minX, int maxX) {
 | 
			
		||||
            decimal? gebundenFlatPrice, List<ContractSelection> contracts, int minX, int maxX) {
 | 
			
		||||
            Id = id;
 | 
			
		||||
            Mode = mode;
 | 
			
		||||
            MinX = minX;
 | 
			
		||||
            MaxX = maxX;
 | 
			
		||||
            DataGraph = dataGraph;
 | 
			
		||||
            GebundenGraph = gebundenGraph;
 | 
			
		||||
            GebundenFlatPrice = gebundenFlatPrice;
 | 
			
		||||
            GebundenFlatBonus = gebundenFlatPrice;
 | 
			
		||||
            Contracts = contracts;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddGebundenGraph() {
 | 
			
		||||
            GebundenGraph ??= new Graph(MinX, MaxX);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RemoveGebundenGraph() {
 | 
			
		||||
            GebundenGraph = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetGebundenFlatBonus(decimal? value) {
 | 
			
		||||
            GebundenFlatBonus = value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public JsonObject ToJson() {
 | 
			
		||||
            var curve = new JsonObject {
 | 
			
		||||
                ["id"] = Id,
 | 
			
		||||
@@ -54,8 +70,8 @@ namespace Elwig.Helpers.Billing {
 | 
			
		||||
 | 
			
		||||
            curve["data"] = DataGraph.ToJson(Mode.ToString().ToLower());
 | 
			
		||||
 | 
			
		||||
            if (GebundenFlatPrice != null) {
 | 
			
		||||
                curve["geb"] = GebundenFlatPrice.ToString();
 | 
			
		||||
            if (GebundenFlatBonus != null) {
 | 
			
		||||
                curve["geb"] = GebundenFlatBonus;
 | 
			
		||||
            } else if (GebundenGraph != null) {
 | 
			
		||||
                curve["geb"] = GebundenGraph.ToJson(Mode.ToString().ToLower());
 | 
			
		||||
            }
 | 
			
		||||
@@ -64,7 +80,7 @@ namespace Elwig.Helpers.Billing {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public GraphEntry Copy(int id) {
 | 
			
		||||
            return new GraphEntry(id, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), GebundenFlatPrice, Contracts, MinX, MaxX);
 | 
			
		||||
            return new GraphEntry(id, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), GebundenFlatBonus, [], MinX, MaxX);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
        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:ctrl="clr-namespace:Elwig.Controls"
 | 
			
		||||
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
 | 
			
		||||
        xmlns:ScottPlot="clr-namespace:ScottPlot;assembly=ScottPlot.WPF"
 | 
			
		||||
        mc:Ignorable="d"
 | 
			
		||||
@@ -59,12 +60,12 @@
 | 
			
		||||
            </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
            <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"/>
 | 
			
		||||
            <TextBlock x:Name="GraphNum" Margin="55,0,0,0" FontSize="14" Width="50" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
 | 
			
		||||
 | 
			
		||||
            <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 x:Name="ContractInput" Margin="0,10,-42,5" Grid.Column="1" DisplayMemberPath="{Binding Listing}"
 | 
			
		||||
                                        Delimiter=", " AllItemsSelectedContent="Alle" IsEnabled="False" ItemSelectionChanged="ContractInput_Changed"
 | 
			
		||||
                                        Width="500" Height="25" HorizontalAlignment="Right">
 | 
			
		||||
                <!--<xctk:CheckComboBox.ItemTemplate>
 | 
			
		||||
                    <DataTemplate>
 | 
			
		||||
                        <StackPanel Orientation="Horizontal">
 | 
			
		||||
@@ -79,8 +80,8 @@
 | 
			
		||||
            <ListBox.ItemTemplate>
 | 
			
		||||
                <DataTemplate>
 | 
			
		||||
                    <StackPanel Orientation="Horizontal">
 | 
			
		||||
                        <TextBlock Text="{Binding Id}" Width="40"/>
 | 
			
		||||
                        <TextBlock Text="{Binding Contracts}" Width="100"/>
 | 
			
		||||
                        <TextBlock Text="{Binding Id}" Width="30"/>
 | 
			
		||||
                        <TextBlock Text="{Binding ContractsStringSimple}" Width="140" ToolTip="{Binding ContractsString}"/>
 | 
			
		||||
                    </StackPanel>
 | 
			
		||||
                </DataTemplate>
 | 
			
		||||
            </ListBox.ItemTemplate>
 | 
			
		||||
@@ -121,11 +122,13 @@
 | 
			
		||||
                    </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"/>
 | 
			
		||||
                    <ctrl:UnitTextBox x:Name="OechsleInput" Unit="°Oe" TextChanged="OechsleInput_TextChanged" IsEnabled="False" LostFocus="OechsleInput_LostFocus"
 | 
			
		||||
                        Grid.Column="1" Width="90" Margin="0,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
 | 
			
		||||
 | 
			
		||||
                    <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"/>
 | 
			
		||||
 | 
			
		||||
                    <Label Content="Preis:" Margin="10,40,0,0" Grid.Column="0"/>
 | 
			
		||||
                    <ctrl:UnitTextBox x:Name="PriceInput" Unit="€/kg" TextChanged="PriceInput_TextChanged" IsEnabled="False" LostFocus="PriceInput_LostFocus"
 | 
			
		||||
                        Grid.Column="1" Width="90" Margin="0,40,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
 | 
			
		||||
                </Grid>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
 | 
			
		||||
@@ -137,12 +140,13 @@
 | 
			
		||||
                    </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>
 | 
			
		||||
                        <RadioButton x:Name="GebundenTypeFixed" GroupName="GebundenType" Checked="GebundenType_Checked" IsEnabled="False">Fix</RadioButton>
 | 
			
		||||
                        <RadioButton x:Name="GebundenTypeGraph" GroupName="GebundenType" Checked="GebundenType_Checked" IsEnabled="False">Graph</RadioButton>
 | 
			
		||||
                        <RadioButton x:Name="GebundenTypeNone" GroupName="GebundenType" Checked="GebundenType_Checked" IsEnabled="False">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"/>
 | 
			
		||||
                    <ctrl:UnitTextBox x:Name="GebundenFlatBonus" Unit="€/kg" TextChanged="GebundenFlatBonus_TextChanged" IsEnabled="False"
 | 
			
		||||
                                      Width="90" Margin="0,5,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="1"/>
 | 
			
		||||
                </Grid>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,12 @@ using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text.Json;
 | 
			
		||||
using System.Text.Json.Nodes;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
using System.Windows.Input;
 | 
			
		||||
using Elwig.Controls;
 | 
			
		||||
using Elwig.Helpers;
 | 
			
		||||
using Elwig.Helpers.Billing;
 | 
			
		||||
using Elwig.Models.Entities;
 | 
			
		||||
@@ -23,16 +23,18 @@ namespace Elwig.Windows {
 | 
			
		||||
        public readonly int AvNr;
 | 
			
		||||
        private readonly PaymentVar PaymentVar;
 | 
			
		||||
 | 
			
		||||
        private ScatterPlot OechslePricePlotScatter;
 | 
			
		||||
        private MarkerPlot HighlightedPoint;
 | 
			
		||||
        private MarkerPlot PrimaryMarkedPoint;
 | 
			
		||||
        private MarkerPlot SecondaryMarkedPoint;
 | 
			
		||||
        private Tooltip Tooltip;
 | 
			
		||||
        private ScatterPlot DataPlot;
 | 
			
		||||
        private ScatterPlot? GebundenPlot;
 | 
			
		||||
        private MarkerPlot HighlightedPointPlot;
 | 
			
		||||
        private MarkerPlot PrimaryMarkedPointPlot;
 | 
			
		||||
        private MarkerPlot SecondaryMarkedPointPlot;
 | 
			
		||||
        private Tooltip TooltipPlot;
 | 
			
		||||
 | 
			
		||||
        private int LastHighlightedIndex = -1;
 | 
			
		||||
        private int HighlightedIndex = -1;
 | 
			
		||||
        private int PrimaryMarkedPointIndex = -1;
 | 
			
		||||
        private int SecondaryMarkedPointIndex = -1;
 | 
			
		||||
        private (Graph? graph, int index) LastHighlighted = (null, -1);
 | 
			
		||||
        private (Graph? graph, int index) Highlighted = (null, -1);
 | 
			
		||||
        private Graph? ActiveGraph = null;
 | 
			
		||||
        private int PrimaryMarkedPoint = -1;
 | 
			
		||||
        private int SecondaryMarkedPoint = -1;
 | 
			
		||||
        private bool HoverChanged = false;
 | 
			
		||||
        private bool HoverActive = false;
 | 
			
		||||
 | 
			
		||||
@@ -72,7 +74,10 @@ namespace Elwig.Windows {
 | 
			
		||||
            GraphEntries.AddRange(data.GetPaymentGraphEntries());
 | 
			
		||||
            GraphEntries.AddRange(data.GetQualityGraphEntries());
 | 
			
		||||
 | 
			
		||||
            ControlUtils.RenewItemsSource(AppliedInput, attrVariants, g => g);
 | 
			
		||||
            //var contracts = ContractSelection.GetContractsForYear(Context, Year).DistinctBy(c => c.Listing).Order().ToList();
 | 
			
		||||
            //ControlUtils.RenewItemsSource(ContractInput, contracts, g => (g as GraphEntry)?.Id);
 | 
			
		||||
 | 
			
		||||
            ControlUtils.RenewItemsSource(ContractInput, attrVariants, g => g);
 | 
			
		||||
            ControlUtils.RenewItemsSource(GraphList, GraphEntries, g => (g as GraphEntry)?.Id, null, ControlUtils.RenewSourceDefault.IfOnly);
 | 
			
		||||
 | 
			
		||||
            RefreshInputs();
 | 
			
		||||
@@ -88,18 +93,28 @@ namespace Elwig.Windows {
 | 
			
		||||
                AddButton.IsEnabled = false;
 | 
			
		||||
                CopyButton.IsEnabled = false;
 | 
			
		||||
                DeleteButton.IsEnabled = false;
 | 
			
		||||
                OechsleInput.IsReadOnly = true;
 | 
			
		||||
                PriceInput.IsReadOnly = true;
 | 
			
		||||
                DisableUnitTextBox(OechsleInput);
 | 
			
		||||
                DisableUnitTextBox(PriceInput);
 | 
			
		||||
                GebundenTypeFixed.IsEnabled = false;
 | 
			
		||||
                GebundenTypeGraph.IsEnabled = false;
 | 
			
		||||
                GebundenTypeNone.IsEnabled = false;
 | 
			
		||||
                ContractInput.IsEnabled = false;
 | 
			
		||||
                EnableOptionButtons();
 | 
			
		||||
                FillInputs();
 | 
			
		||||
            } else if (SelectedGraphEntry != null) {
 | 
			
		||||
                CopyButton.IsEnabled = true;
 | 
			
		||||
                DeleteButton.IsEnabled = true;
 | 
			
		||||
                OechsleInput.IsReadOnly = false;
 | 
			
		||||
                //EnableUnitTextBox(OechsleInput);
 | 
			
		||||
                GebundenTypeFixed.IsEnabled = true;
 | 
			
		||||
                GebundenTypeGraph.IsEnabled = true;
 | 
			
		||||
                GebundenTypeNone.IsEnabled = true;
 | 
			
		||||
                ContractInput.IsEnabled = true;
 | 
			
		||||
                EnableOptionButtons();
 | 
			
		||||
                FillInputs();
 | 
			
		||||
            } else {
 | 
			
		||||
                CopyButton.IsEnabled = false;
 | 
			
		||||
                DeleteButton.IsEnabled = false;
 | 
			
		||||
                OechsleInput.IsReadOnly = true;
 | 
			
		||||
                DisableUnitTextBox(OechsleInput);
 | 
			
		||||
                DisableOptionButtons();
 | 
			
		||||
            }
 | 
			
		||||
            GC.Collect();
 | 
			
		||||
@@ -108,6 +123,16 @@ namespace Elwig.Windows {
 | 
			
		||||
        private void FillInputs() {
 | 
			
		||||
            GraphNum.Text = SelectedGraphEntry.Id.ToString();
 | 
			
		||||
 | 
			
		||||
            if (SelectedGraphEntry.GebundenFlatBonus != null) {
 | 
			
		||||
                GebundenTypeFixed.IsChecked = true;
 | 
			
		||||
            } else if (SelectedGraphEntry.GebundenGraph != null) {
 | 
			
		||||
                GebundenTypeGraph.IsChecked = true;
 | 
			
		||||
            } else {
 | 
			
		||||
                GebundenTypeNone.IsChecked = true; ;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ControlUtils.SelectCheckComboBoxItems(ContractInput, SelectedGraphEntry.Contracts, i => (i as ContractSelection)?.Listing);
 | 
			
		||||
 | 
			
		||||
            InitPlot();
 | 
			
		||||
            OechslePricePlot.IsEnabled = true;
 | 
			
		||||
        }
 | 
			
		||||
@@ -117,13 +142,24 @@ namespace Elwig.Windows {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void InitPlot() {
 | 
			
		||||
            OechslePricePlotScatter = OechslePricePlot.Plot.AddScatter(SelectedGraphEntry.DataGraph.DataX, SelectedGraphEntry.DataGraph.DataY);
 | 
			
		||||
            if (SelectedGraphEntry?.GebundenGraph != null) {
 | 
			
		||||
                GebundenPlot = OechslePricePlot.Plot.AddScatter(SelectedGraphEntry.GebundenGraph.DataX, SelectedGraphEntry.GebundenGraph.DataY);
 | 
			
		||||
                GebundenPlot.LineColor = Color.Green;
 | 
			
		||||
                GebundenPlot.MarkerColor = Color.Green;
 | 
			
		||||
                GebundenPlot.MarkerSize = 9;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            DataPlot = OechslePricePlot.Plot.AddScatter(SelectedGraphEntry.DataGraph.DataX, SelectedGraphEntry.DataGraph.DataY);
 | 
			
		||||
            DataPlot.LineColor = Color.Blue;
 | 
			
		||||
            DataPlot.MarkerColor = Color.Blue;
 | 
			
		||||
            DataPlot.MarkerSize = 9;
 | 
			
		||||
 | 
			
		||||
            if (SelectedGraphEntry.GebundenGraph == null) {
 | 
			
		||||
                ChangeActiveGraph(SelectedGraphEntry.DataGraph);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            OechslePricePlot.RightClicked -= OechslePricePlot.DefaultRightClickEvent;
 | 
			
		||||
            OechslePricePlot.Configuration.DoubleClickBenchmark = false;
 | 
			
		||||
            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);
 | 
			
		||||
@@ -133,23 +169,23 @@ namespace Elwig.Windows {
 | 
			
		||||
            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;
 | 
			
		||||
            HighlightedPointPlot = OechslePricePlot.Plot.AddPoint(0, 0);
 | 
			
		||||
            HighlightedPointPlot.Color = Color.Red;
 | 
			
		||||
            HighlightedPointPlot.MarkerSize = 10;
 | 
			
		||||
            HighlightedPointPlot.MarkerShape = MarkerShape.openCircle;
 | 
			
		||||
            HighlightedPointPlot.IsVisible = false;
 | 
			
		||||
 | 
			
		||||
            PrimaryMarkedPoint = OechslePricePlot.Plot.AddPoint(0, 0);
 | 
			
		||||
            PrimaryMarkedPoint.Color = Color.Red;
 | 
			
		||||
            PrimaryMarkedPoint.MarkerSize = 6;
 | 
			
		||||
            PrimaryMarkedPoint.MarkerShape = MarkerShape.filledCircle;
 | 
			
		||||
            PrimaryMarkedPoint.IsVisible = false;
 | 
			
		||||
            PrimaryMarkedPointPlot = OechslePricePlot.Plot.AddPoint(0, 0);
 | 
			
		||||
            PrimaryMarkedPointPlot.Color = Color.Red;
 | 
			
		||||
            PrimaryMarkedPointPlot.MarkerSize = 6;
 | 
			
		||||
            PrimaryMarkedPointPlot.MarkerShape = MarkerShape.filledCircle;
 | 
			
		||||
            PrimaryMarkedPointPlot.IsVisible = false;
 | 
			
		||||
 | 
			
		||||
            SecondaryMarkedPoint = OechslePricePlot.Plot.AddPoint(0, 0);
 | 
			
		||||
            SecondaryMarkedPoint.Color = Color.Red;
 | 
			
		||||
            SecondaryMarkedPoint.MarkerSize = 6;
 | 
			
		||||
            SecondaryMarkedPoint.MarkerShape = MarkerShape.filledCircle;
 | 
			
		||||
            SecondaryMarkedPoint.IsVisible = false;
 | 
			
		||||
            SecondaryMarkedPointPlot = OechslePricePlot.Plot.AddPoint(0, 0);
 | 
			
		||||
            SecondaryMarkedPointPlot.Color = Color.Red;
 | 
			
		||||
            SecondaryMarkedPointPlot.MarkerSize = 6;
 | 
			
		||||
            SecondaryMarkedPointPlot.MarkerShape = MarkerShape.filledCircle;
 | 
			
		||||
            SecondaryMarkedPointPlot.IsVisible = false;
 | 
			
		||||
 | 
			
		||||
            OechslePricePlot.Refresh();
 | 
			
		||||
 | 
			
		||||
@@ -158,8 +194,12 @@ namespace Elwig.Windows {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ResetPlot() {
 | 
			
		||||
            PrimaryMarkedPointIndex = -1;
 | 
			
		||||
            OechslePricePlot.Plot.Remove(OechslePricePlotScatter);
 | 
			
		||||
            PrimaryMarkedPoint = -1;
 | 
			
		||||
            SecondaryMarkedPoint = -1;
 | 
			
		||||
            ChangeActiveGraph(null);
 | 
			
		||||
            HideGradationLines();
 | 
			
		||||
            OechslePricePlot.Plot.Remove(DataPlot);
 | 
			
		||||
            OechslePricePlot.Plot.Remove(GebundenPlot);
 | 
			
		||||
            OechslePricePlot.Plot.Clear();
 | 
			
		||||
            OechslePricePlot.Reset();
 | 
			
		||||
            OechslePricePlot.Refresh();
 | 
			
		||||
@@ -171,21 +211,17 @@ namespace Elwig.Windows {
 | 
			
		||||
            point.IsVisible = visible;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FlattenGraph(int begin, int end, double value) {
 | 
			
		||||
            SelectedGraphEntry.DataGraph.FlattenGraph(begin, end, value);
 | 
			
		||||
            OechslePricePlot.Render();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void LinearIncreaseGraph(int begin, int end, double inc) {
 | 
			
		||||
            SelectedGraphEntry.DataGraph.LinearIncreaseGraph(begin, end, inc);
 | 
			
		||||
            OechslePricePlot.Render();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void EnableActionButtons() {
 | 
			
		||||
            if (PaymentVar.TestVariant) {
 | 
			
		||||
                LeftFlatButton.IsEnabled = true;
 | 
			
		||||
                RightFlatButton.IsEnabled = true;
 | 
			
		||||
                LinearIncreaseButton.IsEnabled = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DisableActionButtons() {
 | 
			
		||||
            LeftFlatButton.IsEnabled = false;
 | 
			
		||||
@@ -239,10 +275,10 @@ namespace Elwig.Windows {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RefreshGradationLines() {
 | 
			
		||||
            if (GradationLinesInput.IsChecked == true) {
 | 
			
		||||
            if (GradationLinesInput.IsChecked == true && SelectedGraphEntry != null && !OechslePricePlot.Plot.GetPlottables().OfType<VLine>().Any()) {
 | 
			
		||||
                ShowGradationLines();
 | 
			
		||||
                ShowLegend();
 | 
			
		||||
            } else {
 | 
			
		||||
            } else if (GradationLinesInput.IsChecked == false) {
 | 
			
		||||
                HideGradationLines();
 | 
			
		||||
                HideLegend();
 | 
			
		||||
            }
 | 
			
		||||
@@ -268,82 +304,85 @@ namespace Elwig.Windows {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void OechsleInput_TextChanged(object sender, TextChangedEventArgs evt) {
 | 
			
		||||
            if (ActiveGraph == null) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            bool success = int.TryParse(OechsleInput.Text, out int oechsle);
 | 
			
		||||
 | 
			
		||||
            SecondaryMarkedPointIndex = -1;
 | 
			
		||||
            ChangeMarker(SecondaryMarkedPoint, false);
 | 
			
		||||
            SecondaryMarkedPoint = -1;
 | 
			
		||||
            ChangeMarker(SecondaryMarkedPointPlot, false);
 | 
			
		||||
 | 
			
		||||
            if (success) {
 | 
			
		||||
                if (oechsle >= MinOechsle && oechsle <= MaxOechsle) {
 | 
			
		||||
                    PrimaryMarkedPointIndex = oechsle - MinOechsle;
 | 
			
		||||
                    ChangeMarker(PrimaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[PrimaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
 | 
			
		||||
                    PrimaryMarkedPoint = oechsle - MinOechsle;
 | 
			
		||||
                    ChangeMarker(PrimaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(PrimaryMarkedPoint), ActiveGraph.GetPriceAt(PrimaryMarkedPoint));
 | 
			
		||||
 | 
			
		||||
                    PriceInput.Text = SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex].ToString();
 | 
			
		||||
                    PriceInput.Text = ActiveGraph.GetPriceAt(PrimaryMarkedPoint).ToString();
 | 
			
		||||
 | 
			
		||||
                    EnableActionButtons();
 | 
			
		||||
                    OechslePricePlot.Render();
 | 
			
		||||
                    PriceInput.IsReadOnly = false;
 | 
			
		||||
                    EnableUnitTextBox(PriceInput);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            PrimaryMarkedPointIndex = -1;
 | 
			
		||||
            ChangeMarker(PrimaryMarkedPoint, false);
 | 
			
		||||
            PrimaryMarkedPoint = -1;
 | 
			
		||||
            //ChangeActiveGraph(null);
 | 
			
		||||
            ChangeMarker(PrimaryMarkedPointPlot, false);
 | 
			
		||||
            DisableActionButtons();
 | 
			
		||||
            PriceInput.Text = "";
 | 
			
		||||
            DisableUnitTextBox(PriceInput);
 | 
			
		||||
            OechslePricePlot.Render();
 | 
			
		||||
            PriceInput.IsReadOnly = true;
 | 
			
		||||
            DisableUnitTextBox(PriceInput);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void PriceInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (PrimaryMarkedPointIndex != -1) {
 | 
			
		||||
        private void PriceInput_TextChanged(object sender, TextChangedEventArgs evt) {
 | 
			
		||||
            if (PrimaryMarkedPoint != -1 && ActiveGraph != null) {
 | 
			
		||||
                bool success = Double.TryParse(PriceInput.Text, out double price);
 | 
			
		||||
 | 
			
		||||
                if (success) {
 | 
			
		||||
                    SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex] = price;
 | 
			
		||||
                    PrimaryMarkedPoint.Y = price;
 | 
			
		||||
                    ActiveGraph.SetPriceAt(PrimaryMarkedPoint, price);
 | 
			
		||||
                    PrimaryMarkedPointPlot.Y = price;
 | 
			
		||||
                    OechslePricePlot.Refresh();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void LeftFlatButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (PrimaryMarkedPointIndex == -1) {
 | 
			
		||||
            if (PrimaryMarkedPoint == -1 || ActiveGraph == null) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            FlattenGraph(0, PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
 | 
			
		||||
            ActiveGraph.FlattenGraphLeft(PrimaryMarkedPoint);
 | 
			
		||||
            OechslePricePlot.Render();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RightFlatButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (PrimaryMarkedPointIndex == -1) {
 | 
			
		||||
            if (PrimaryMarkedPoint == -1 || ActiveGraph == null) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            FlattenGraph(PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY.Length - 1, SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
 | 
			
		||||
            ActiveGraph.FlattenGraphRight(PrimaryMarkedPoint);
 | 
			
		||||
            OechslePricePlot.Render();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void InterpolateButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            int steps = Math.Abs(PrimaryMarkedPointIndex - SecondaryMarkedPointIndex);
 | 
			
		||||
            if (PrimaryMarkedPointIndex == -1 || SecondaryMarkedPointIndex == -1 || steps < 2) {
 | 
			
		||||
            if (PrimaryMarkedPoint == SecondaryMarkedPoint || PrimaryMarkedPoint == -1 || SecondaryMarkedPoint == -1 || ActiveGraph == null) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var (lowIndex, highIndex) = PrimaryMarkedPointIndex < SecondaryMarkedPointIndex ? (PrimaryMarkedPointIndex, SecondaryMarkedPointIndex): (SecondaryMarkedPointIndex, PrimaryMarkedPointIndex);
 | 
			
		||||
 | 
			
		||||
            double step = (SelectedGraphEntry.DataGraph.DataY[highIndex] - SelectedGraphEntry.DataGraph.DataY[lowIndex]) / steps;
 | 
			
		||||
 | 
			
		||||
            for (int i = lowIndex; i < highIndex - 1; i++) {
 | 
			
		||||
                SelectedGraphEntry.DataGraph.DataY[i + 1] = Math.Round(SelectedGraphEntry.DataGraph.DataY[i] + step, 4); // TODO richtig runden
 | 
			
		||||
            }
 | 
			
		||||
            ActiveGraph.InterpolateGraph(PrimaryMarkedPoint, SecondaryMarkedPoint);
 | 
			
		||||
            OechslePricePlot.Render();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) { 
 | 
			
		||||
            if (PrimaryMarkedPointIndex == -1) {
 | 
			
		||||
            if (PrimaryMarkedPoint == -1 || ActiveGraph == null) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            double? priceIncrease = Utils.ShowLinearPriceIncreaseDialog();
 | 
			
		||||
            if (priceIncrease == null) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            LinearIncreaseGraph(PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY.Length - 1, priceIncrease.Value);
 | 
			
		||||
            ActiveGraph.LinearIncreaseGraphToEnd(PrimaryMarkedPoint, priceIncrease.Value);
 | 
			
		||||
            OechslePricePlot.Render();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) {
 | 
			
		||||
@@ -353,83 +392,112 @@ namespace Elwig.Windows {
 | 
			
		||||
 | 
			
		||||
            if (HoverActive) {
 | 
			
		||||
                if (PaymentVar.TestVariant && Keyboard.IsKeyDown(Key.LeftCtrl)) {
 | 
			
		||||
                    if (PrimaryMarkedPointIndex == -1) {
 | 
			
		||||
                    if (PrimaryMarkedPoint == -1 || ActiveGraph == null || ActiveGraph != Highlighted.graph) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    SecondaryMarkedPointIndex = HighlightedIndex;
 | 
			
		||||
                    ChangeMarker(SecondaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[SecondaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[SecondaryMarkedPointIndex]);
 | 
			
		||||
                    SecondaryMarkedPoint = Highlighted.index;
 | 
			
		||||
 | 
			
		||||
                    ChangeMarker(SecondaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(SecondaryMarkedPoint), ActiveGraph.GetPriceAt(SecondaryMarkedPoint));
 | 
			
		||||
 | 
			
		||||
                    InterpolateButton.IsEnabled = true;
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                PrimaryMarkedPointIndex = HighlightedIndex;
 | 
			
		||||
                ChangeMarker(PrimaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[PrimaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
 | 
			
		||||
                PrimaryMarkedPoint = Highlighted.index;
 | 
			
		||||
                ChangeActiveGraph(Highlighted.graph);
 | 
			
		||||
 | 
			
		||||
                OechsleInput.Text = SelectedGraphEntry.DataGraph.DataX[HighlightedIndex].ToString();
 | 
			
		||||
                PriceInput.Text = SelectedGraphEntry.DataGraph.DataY[HighlightedIndex].ToString();
 | 
			
		||||
                ChangeMarker(PrimaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(PrimaryMarkedPoint), ActiveGraph.GetPriceAt(PrimaryMarkedPoint));
 | 
			
		||||
 | 
			
		||||
                OechsleInput.Text = Highlighted.graph.GetOechsleAt(Highlighted.index).ToString();
 | 
			
		||||
                PriceInput.Text = Highlighted.graph.GetPriceAt(Highlighted.index).ToString();
 | 
			
		||||
 | 
			
		||||
                if (PaymentVar.TestVariant) {
 | 
			
		||||
                EnableActionButtons();
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                PrimaryMarkedPointIndex = -1;
 | 
			
		||||
                SecondaryMarkedPointIndex = -1;
 | 
			
		||||
                ChangeMarker(PrimaryMarkedPoint, false);
 | 
			
		||||
                ChangeMarker(SecondaryMarkedPoint, false);
 | 
			
		||||
                PrimaryMarkedPoint = -1;
 | 
			
		||||
                SecondaryMarkedPoint = -1;
 | 
			
		||||
                if (SelectedGraphEntry!.GebundenGraph != null) {
 | 
			
		||||
                    ChangeActiveGraph(null);
 | 
			
		||||
                }
 | 
			
		||||
                ChangeMarker(PrimaryMarkedPointPlot, false);
 | 
			
		||||
                ChangeMarker(SecondaryMarkedPointPlot, false);
 | 
			
		||||
 | 
			
		||||
                OechsleInput.Text = "";
 | 
			
		||||
                PriceInput.Text = "";
 | 
			
		||||
                DisableUnitTextBox(PriceInput);
 | 
			
		||||
 | 
			
		||||
                DisableActionButtons();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private (double, double, int)? MouseOnPlot(ScatterPlot? plot) {
 | 
			
		||||
            if (plot == null) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            (double mouseCoordX, double mouseCoordY) = OechslePricePlot.GetMouseCoordinates();
 | 
			
		||||
            (double mousePixelX, double mousePixelY) = OechslePricePlot.GetMousePixel();
 | 
			
		||||
            double xyRatio = OechslePricePlot.Plot.XAxis.Dims.PxPerUnit / OechslePricePlot.Plot.YAxis.Dims.PxPerUnit;
 | 
			
		||||
 | 
			
		||||
            (double pointX, double pointY, int pointIndex) = plot.GetPointNearest(mouseCoordX, mouseCoordY, xyRatio);
 | 
			
		||||
            (double pointPixelX, double pointPixelY) = OechslePricePlot.Plot.GetPixel(pointX, pointY);
 | 
			
		||||
 | 
			
		||||
            if (Math.Abs(mousePixelX - pointPixelX) < 3 && Math.Abs(mousePixelY - pointPixelY) < 3) {
 | 
			
		||||
                return (pointX, pointY, pointIndex);
 | 
			
		||||
            } else {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void OechslePricePlot_MouseMove(object sender, MouseEventArgs e) {
 | 
			
		||||
            if (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 x, double y, int index)? mouseOnData = MouseOnPlot(DataPlot);
 | 
			
		||||
            (double x, double y , int index)? mouseOnGebunden = MouseOnPlot(GebundenPlot);
 | 
			
		||||
 | 
			
		||||
            (double mousePixelX, double mousePixelY) = OechslePricePlot.GetMousePixel();
 | 
			
		||||
            (double pointPixelX, double pointPixelY) = OechslePricePlot.Plot.GetPixel(pointX, pointY);
 | 
			
		||||
            Highlighted = LastHighlighted;
 | 
			
		||||
 | 
			
		||||
            HighlightedIndex = LastHighlightedIndex;
 | 
			
		||||
 | 
			
		||||
            if (Math.Abs(mousePixelX - pointPixelX) < 3 && Math.Abs(mousePixelY - pointPixelY) < 3) {
 | 
			
		||||
                ChangeMarker(HighlightedPoint, true, pointX, pointY);
 | 
			
		||||
                HighlightedPoint.IsVisible = true;
 | 
			
		||||
            if (mouseOnData != null) {
 | 
			
		||||
                ChangeMarker(HighlightedPointPlot, true, mouseOnData.Value.x, mouseOnData.Value.y);
 | 
			
		||||
                HighlightedPointPlot.IsVisible = true;
 | 
			
		||||
                HoverChanged = true ^ HoverActive;
 | 
			
		||||
                HoverActive = true;
 | 
			
		||||
                HandleTooltip(mouseOnData.Value.x, mouseOnData.Value.y, mouseOnData.Value.index, SelectedGraphEntry!.DataGraph);
 | 
			
		||||
            } else if (mouseOnGebunden != null) {
 | 
			
		||||
                ChangeMarker(HighlightedPointPlot, true, mouseOnGebunden.Value.x, mouseOnGebunden.Value.y);
 | 
			
		||||
                HighlightedPointPlot.IsVisible = true;
 | 
			
		||||
                HoverChanged = true ^ HoverActive;
 | 
			
		||||
                HoverActive = true;
 | 
			
		||||
                HandleTooltip(mouseOnGebunden.Value.x, mouseOnGebunden.Value.y, mouseOnGebunden.Value.index, SelectedGraphEntry!.GebundenGraph);
 | 
			
		||||
            } else {
 | 
			
		||||
                ChangeMarker(HighlightedPoint, false);
 | 
			
		||||
                ChangeMarker(HighlightedPointPlot, false);
 | 
			
		||||
                HoverChanged = false ^ HoverActive;
 | 
			
		||||
                HoverActive = false;
 | 
			
		||||
                OechslePricePlot.Plot.Remove(Tooltip);
 | 
			
		||||
                OechslePricePlot.Plot.Remove(TooltipPlot);
 | 
			
		||||
                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;
 | 
			
		||||
 | 
			
		||||
        private void HandleTooltip(double pointX, double pointY, int pointIndex, Graph g) {
 | 
			
		||||
            if (LastHighlighted != Highlighted || HoverChanged) {
 | 
			
		||||
                OechslePricePlot.Plot.Remove(TooltipPlot);
 | 
			
		||||
                if (TooltipInput.IsChecked == true) {
 | 
			
		||||
                    TooltipPlot = OechslePricePlot.Plot.AddTooltip($"Oechsle: {pointX:N2}, Preis: {Math.Round(pointY, 4)}€/kg)", pointX, pointY);
 | 
			
		||||
                }
 | 
			
		||||
                LastHighlighted = (g, pointIndex);
 | 
			
		||||
                HoverChanged = false;
 | 
			
		||||
                OechslePricePlot.Render();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private int getMaxGraphId() {
 | 
			
		||||
        private int GetMaxGraphId() {
 | 
			
		||||
            return GraphEntries.Count == 0 ? 0 : GraphEntries.Select(g => g.Id).Max();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddButton_Click(object sender, RoutedEventArgs e) {
 | 
			
		||||
            GraphEntry newGraphEntry = new(getMaxGraphId() + 1, BillingData.CurveMode.Oe, MinOechsle, MaxOechsle);
 | 
			
		||||
            GraphEntry newGraphEntry = new(GetMaxGraphId() + 1, BillingData.CurveMode.Oe, MinOechsle, MaxOechsle);
 | 
			
		||||
            GraphEntries.Add(newGraphEntry);
 | 
			
		||||
            GraphList.Items.Refresh();
 | 
			
		||||
            GraphList.SelectedItem = newGraphEntry;
 | 
			
		||||
@@ -438,7 +506,7 @@ namespace Elwig.Windows {
 | 
			
		||||
        private void CopyButton_Click(object sender, RoutedEventArgs e) {
 | 
			
		||||
            if (SelectedGraphEntry == null) return;
 | 
			
		||||
 | 
			
		||||
            GraphEntry newGraphEntry = SelectedGraphEntry.Copy(getMaxGraphId() + 1);
 | 
			
		||||
            GraphEntry newGraphEntry = SelectedGraphEntry.Copy(GetMaxGraphId() + 1);
 | 
			
		||||
            GraphEntries.Add(newGraphEntry);
 | 
			
		||||
            GraphList.Items.Refresh();
 | 
			
		||||
            GraphList.SelectedItem = newGraphEntry;
 | 
			
		||||
@@ -457,8 +525,82 @@ namespace Elwig.Windows {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SaveButton_Click(object sender, RoutedEventArgs e) {
 | 
			
		||||
            //TODO SAVE
 | 
			
		||||
        private async void SaveButton_Click(object sender, RoutedEventArgs e) {
 | 
			
		||||
            await SaveGraphs();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task SaveGraphs() {
 | 
			
		||||
            var payment = new JsonObject();
 | 
			
		||||
            var curves = new JsonArray();
 | 
			
		||||
 | 
			
		||||
            foreach (var entry in GraphEntries) {
 | 
			
		||||
                curves.Add(entry.ToJson());
 | 
			
		||||
                foreach (var contract in entry.Contracts) {
 | 
			
		||||
                    payment[$"{contract.Variety?.SortId}/{contract.Attribute?.AttrId}"] = $"curve:{entry.Id}";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var data = new JsonObject {
 | 
			
		||||
                ["mode"] = "elwig",
 | 
			
		||||
                ["version"] = 1,
 | 
			
		||||
                ["payment"] = payment,
 | 
			
		||||
                ["curves"] = curves
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            MessageBox.Show(data.ToJsonString());
 | 
			
		||||
 | 
			
		||||
            EntityEntry<PaymentVar>? tr = null;
 | 
			
		||||
            try {
 | 
			
		||||
                PaymentVar.Data = data.ToJsonString();
 | 
			
		||||
                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 gespeichert werden!\n\n" + exc.Message;
 | 
			
		||||
                if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
 | 
			
		||||
                MessageBox.Show(str, "Graph speichern", MessageBoxButton.OK, MessageBoxImage.Error);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void EnableUnitTextBox(UnitTextBox u) {
 | 
			
		||||
            if (PaymentVar.TestVariant) {
 | 
			
		||||
                u.IsEnabled = true;
 | 
			
		||||
                u.TextBox.IsReadOnly = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DisableUnitTextBox(UnitTextBox u) {
 | 
			
		||||
            u.IsEnabled = false;
 | 
			
		||||
            u.TextBox.IsReadOnly = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ChangeActiveGraph(Graph? g) {
 | 
			
		||||
            if (g != null && g == SelectedGraphEntry?.DataGraph) {
 | 
			
		||||
                EnableUnitTextBox(OechsleInput);
 | 
			
		||||
                ChangeLineWidth(DataPlot, 4);
 | 
			
		||||
                ChangeLineWidth(GebundenPlot, 1);
 | 
			
		||||
            } else if (g != null && g == SelectedGraphEntry?.GebundenGraph) {
 | 
			
		||||
                EnableUnitTextBox(OechsleInput);
 | 
			
		||||
                ChangeLineWidth(GebundenPlot, 4);
 | 
			
		||||
                ChangeLineWidth(DataPlot, 1);
 | 
			
		||||
            } else {
 | 
			
		||||
                DisableUnitTextBox(OechsleInput);
 | 
			
		||||
                DisableUnitTextBox(PriceInput);
 | 
			
		||||
                OechsleInput.Text = "";
 | 
			
		||||
                PriceInput.Text = "";
 | 
			
		||||
                ChangeLineWidth(DataPlot, 1);
 | 
			
		||||
                ChangeLineWidth(GebundenPlot, 1);
 | 
			
		||||
            }
 | 
			
		||||
            ActiveGraph = g;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ChangeLineWidth(ScatterPlot? p, double lineWidth) {
 | 
			
		||||
            if (p != null) {
 | 
			
		||||
                p.LineWidth = lineWidth;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GraphList_SelectionChanged(object sender, SelectionChangedEventArgs e) {
 | 
			
		||||
@@ -477,8 +619,40 @@ namespace Elwig.Windows {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GebundenBonus_TextChanged(object sender, TextChangedEventArgs evt) {
 | 
			
		||||
        private void GebundenFlatBonus_TextChanged(object sender, TextChangedEventArgs e) {
 | 
			
		||||
            var r = Validator.CheckDecimal(GebundenFlatBonus.TextBox, true, 2, 8);
 | 
			
		||||
            if (r.IsValid) {
 | 
			
		||||
                SelectedGraphEntry?.SetGebundenFlatBonus(decimal.Parse(GebundenFlatBonus.Text));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ContractInput_Changed(object sender, RoutedEventArgs e) {
 | 
			
		||||
            var r = ContractInput.SelectedItems.Cast<ContractSelection>();
 | 
			
		||||
            SelectedGraphEntry!.Contracts = r.ToList();
 | 
			
		||||
            GraphList.Items.Refresh();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GebundenType_Checked(object sender, RoutedEventArgs e) {
 | 
			
		||||
            if (SelectedGraphEntry == null) {
 | 
			
		||||
                DisableUnitTextBox(GebundenFlatBonus);
 | 
			
		||||
                return;
 | 
			
		||||
            } else if (GebundenTypeNone.IsChecked == true) {
 | 
			
		||||
                SelectedGraphEntry.SetGebundenFlatBonus(null);
 | 
			
		||||
                SelectedGraphEntry.RemoveGebundenGraph();
 | 
			
		||||
                DisableUnitTextBox(GebundenFlatBonus);
 | 
			
		||||
                RefreshInputs();
 | 
			
		||||
            } else if (GebundenTypeFixed.IsChecked == true) {
 | 
			
		||||
                SelectedGraphEntry.SetGebundenFlatBonus(0);
 | 
			
		||||
                SelectedGraphEntry.RemoveGebundenGraph();
 | 
			
		||||
                EnableUnitTextBox(GebundenFlatBonus);
 | 
			
		||||
                RefreshInputs();
 | 
			
		||||
            } else if (GebundenTypeGraph.IsChecked == true) {
 | 
			
		||||
                GebundenFlatBonus.Text = "";
 | 
			
		||||
                SelectedGraphEntry.SetGebundenFlatBonus(null);
 | 
			
		||||
                SelectedGraphEntry.AddGebundenGraph();
 | 
			
		||||
                DisableUnitTextBox(GebundenFlatBonus);
 | 
			
		||||
                RefreshInputs();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user