ChartWindow: Make gebunden type fixed more user friendly
This commit is contained in:
@ -210,21 +210,21 @@ namespace Elwig.Helpers.Billing {
|
||||
var x = graph.DataX;
|
||||
var y = graph.DataY;
|
||||
if (y.Distinct().Count() == 1) {
|
||||
return JsonValue.Create(graph.DataY[0]);
|
||||
return JsonValue.Create((decimal)graph.DataY[0]);
|
||||
}
|
||||
|
||||
var data = new JsonObject();
|
||||
|
||||
if (y[0] != y[1]) {
|
||||
data.Add(new KeyValuePair<string, JsonNode?>(x[0] + mode, Math.Round(y[0], graph.Precision)));
|
||||
data[$"{x[0]}{mode}"] = Math.Round(y[0], graph.Precision);
|
||||
}
|
||||
for (int i = 1; i < x.Length - 1; i++) {
|
||||
if (Math.Round(y[i] - y[i - 1], 10) != Math.Round(y[i + 1] - y[i], 10)) {
|
||||
data.Add(new KeyValuePair<string, JsonNode?>(x[i] + mode, Math.Round(y[i], graph.Precision)));
|
||||
data[$"{x[i]}{mode}"] = Math.Round(y[i], graph.Precision);
|
||||
}
|
||||
}
|
||||
if (y[^1] != y[^2]) {
|
||||
data.Add(new KeyValuePair<string, JsonNode?>(x[^1] + mode, Math.Round(y[^1], graph.Precision)));
|
||||
data[$"{x[^1]}{mode}"] = Math.Round(y[^1], graph.Precision);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@ -247,16 +247,6 @@ namespace Elwig.Helpers.Billing {
|
||||
}
|
||||
|
||||
public JsonObject FromGraphEntries(IEnumerable<GraphEntry> graphEntries) {
|
||||
var payment = new JsonObject();
|
||||
var curves = new JsonArray();
|
||||
|
||||
foreach (var entry in graphEntries) {
|
||||
curves.Add(GraphEntryToJson(entry));
|
||||
foreach (var contract in entry.Contracts) {
|
||||
payment[$"{contract.Variety?.SortId}/{contract.Attribute?.AttrId}"] = $"curve:{entry.Id}";
|
||||
}
|
||||
}
|
||||
|
||||
var data = new JsonObject {
|
||||
["mode"] = "elwig",
|
||||
["version"] = 1,
|
||||
@ -270,6 +260,16 @@ namespace Elwig.Helpers.Billing {
|
||||
if (ConsiderAutoBusinessShares)
|
||||
data["consider_auto_business_shares"] = true;
|
||||
|
||||
var payment = new JsonObject();
|
||||
var curves = new JsonArray();
|
||||
|
||||
foreach (var entry in graphEntries) {
|
||||
curves.Add(GraphEntryToJson(entry));
|
||||
foreach (var contract in entry.Contracts) {
|
||||
payment[$"{contract.Variety?.SortId}/{contract.Attribute?.AttrId}"] = $"curve:{entry.Id}";
|
||||
}
|
||||
}
|
||||
|
||||
data["payment"] = payment;
|
||||
data["curves"] = curves;
|
||||
|
||||
|
@ -69,7 +69,7 @@ namespace Elwig.Helpers.Billing {
|
||||
return dict3
|
||||
.Select(e => new GraphEntry(e.Key, season.Precision, curves[e.Key], e.Value
|
||||
.Select(s => new ContractSelection(vars[s[..2]], s.Length > 2 ? attrs[s[2..]] : null))
|
||||
.ToList(), 50, 73, 140))
|
||||
.ToList()))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,14 @@ namespace Elwig.Helpers.Billing {
|
||||
DataY = DataX.Select(i => (double)BillingData.GetCurveValueAt(data, i)).ToArray();
|
||||
}
|
||||
|
||||
public Graph(double[] values, int precision, int minX, int maxX) {
|
||||
Precision = precision;
|
||||
MinX = minX;
|
||||
MaxX = maxX;
|
||||
DataX = Enumerable.Range(MinX, MaxX - MinX + 1).Select(i => (double)i).ToArray();
|
||||
DataY = values;
|
||||
}
|
||||
|
||||
private Graph(double[] dataX, double[] dataY, int precision, int minX, int maxX) {
|
||||
Precision = precision;
|
||||
MinX = minX;
|
||||
@ -52,6 +60,10 @@ namespace Elwig.Helpers.Billing {
|
||||
return DataY[index];
|
||||
}
|
||||
|
||||
public double GetPriceAtOe(double oe) {
|
||||
return DataY[Array.IndexOf(DataX, oe)];
|
||||
}
|
||||
|
||||
private void FlattenGraph(int begin, int end, double value) {
|
||||
for (int i = begin; i <= end; i++) {
|
||||
DataY[i] = value;
|
||||
|
@ -1,77 +1,87 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Elwig.Helpers.Billing {
|
||||
public class GraphEntry {
|
||||
|
||||
public const int MinX = 50;
|
||||
public const int MinXGeb = 73;
|
||||
public const int MaxX = 140;
|
||||
|
||||
public int Id { get; set; }
|
||||
private readonly int Precision;
|
||||
public BillingData.CurveMode Mode { get; set; }
|
||||
public bool Abgewertet { get; set; }
|
||||
|
||||
public Graph DataGraph { get; set; }
|
||||
public Graph? GebundenGraph { 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.FullName)) : "-";
|
||||
private int MinX { get; set; }
|
||||
private int MinXGebunden { get; set; }
|
||||
private int MaxX { get; set; }
|
||||
public double? GebundenFlatBonus {
|
||||
get {
|
||||
try {
|
||||
return GebundenGraph?.DataX.Zip(GebundenGraph.DataY)
|
||||
.Select(e => Math.Round(e.Second - DataGraph.GetPriceAtOe(e.First), Precision))
|
||||
.Distinct()
|
||||
.Single();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
set {
|
||||
if (value is not double v) return;
|
||||
var values = Enumerable.Range(MinXGeb, MaxX - MinXGeb + 1)
|
||||
.Select(i => Math.Round(DataGraph.GetPriceAtOe(i) + v, Precision))
|
||||
.ToArray();
|
||||
GebundenGraph = new Graph(values, Precision, MinXGeb, MaxX);
|
||||
}
|
||||
}
|
||||
|
||||
public GraphEntry(int id, int precision, BillingData.CurveMode mode, int minX, int minXGebunden, int maxX) {
|
||||
public List<ContractSelection> Contracts { get; set; }
|
||||
public string ContractsStringSimple => Contracts.Count != 0 ? string.Join(", ", Contracts.Select(c => c.Listing)) : "-";
|
||||
public string ContractsString => Contracts.Count != 0 ? string.Join("\n", Contracts.Select(c => c.FullName)) : "-";
|
||||
|
||||
private readonly int Precision;
|
||||
|
||||
public GraphEntry(int id, int precision, BillingData.CurveMode mode) {
|
||||
Id = id;
|
||||
Precision = precision;
|
||||
Mode = mode;
|
||||
Abgewertet = false;
|
||||
MinX = minX;
|
||||
MinXGebunden = minXGebunden;
|
||||
MaxX = maxX;
|
||||
DataGraph = new Graph(precision, minX, maxX);
|
||||
DataGraph = new Graph(precision, MinX, MaxX); ;
|
||||
Contracts = [];
|
||||
}
|
||||
|
||||
public GraphEntry(int id, int precision, BillingData.CurveMode mode, Dictionary<double, decimal> data, Dictionary<double, decimal>? gebunden,
|
||||
int minX, int minXGebunden, int maxX) : this(id, precision, mode, minX, minXGebunden, maxX) {
|
||||
DataGraph = new Graph(data, precision, minX, maxX);
|
||||
if (gebunden != null) GebundenGraph = new Graph(gebunden, precision, minXGebunden, maxX);
|
||||
public GraphEntry(int id, int precision, BillingData.CurveMode mode, Dictionary<double, decimal> data, Dictionary<double, decimal>? gebunden) :
|
||||
this(id, precision, mode) {
|
||||
DataGraph = new Graph(data, precision, MinX, MaxX);
|
||||
if (gebunden != null) GebundenGraph = new Graph(gebunden, precision, MinXGeb, MaxX);
|
||||
}
|
||||
|
||||
public GraphEntry(int id, int precision, BillingData.Curve curve, List<ContractSelection> contracts, int minX, int minXGebunden, int maxX) :
|
||||
this(id, precision, curve.Mode, minX, minXGebunden, maxX) {
|
||||
DataGraph = new Graph(curve.Normal, precision, minX, maxX);
|
||||
public GraphEntry(int id, int precision, BillingData.Curve curve, List<ContractSelection> contracts) :
|
||||
this(id, precision, curve.Mode) {
|
||||
DataGraph = new Graph(curve.Normal, precision, MinX, MaxX);
|
||||
if (curve.Gebunden != null)
|
||||
GebundenGraph = new Graph(curve.Gebunden, precision, minXGebunden, maxX);
|
||||
GebundenGraph = new Graph(curve.Gebunden, precision, MinXGeb, MaxX);
|
||||
Contracts = contracts;
|
||||
}
|
||||
|
||||
private GraphEntry(int id, int precision, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph,
|
||||
decimal? gebundenFlatPrice, List<ContractSelection> contracts, int minX, int minXGebunden, int maxX) {
|
||||
private GraphEntry(int id, int precision, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph, List<ContractSelection> contracts) {
|
||||
Id = id;
|
||||
Precision = precision;
|
||||
Mode = mode;
|
||||
MinX = minX;
|
||||
MinXGebunden = minXGebunden;
|
||||
MaxX = maxX;
|
||||
DataGraph = dataGraph;
|
||||
GebundenGraph = gebundenGraph;
|
||||
GebundenFlatBonus = gebundenFlatPrice;
|
||||
Contracts = contracts;
|
||||
}
|
||||
|
||||
public void AddGebundenGraph() {
|
||||
GebundenGraph ??= new Graph(Precision, MinXGebunden, MaxX);
|
||||
GebundenGraph ??= new Graph(Precision, MinXGeb, MaxX);
|
||||
}
|
||||
|
||||
public void RemoveGebundenGraph() {
|
||||
GebundenGraph = null;
|
||||
}
|
||||
|
||||
public void SetGebundenFlatBonus(decimal? value) {
|
||||
GebundenFlatBonus = value;
|
||||
}
|
||||
|
||||
public GraphEntry Copy(int id) {
|
||||
return new GraphEntry(id, Precision, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), GebundenFlatBonus, [], MinX, MinXGebunden, MaxX);
|
||||
return new GraphEntry(id, Precision, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), []);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,10 +43,6 @@ namespace Elwig.Windows {
|
||||
private bool HoverActive = false;
|
||||
private bool FillingInputs = false;
|
||||
|
||||
private const int MinOechsle = 50;
|
||||
private const int MinOechsleGebunden = 73;
|
||||
private const int MaxOechsle = 140;
|
||||
|
||||
private List<GraphEntry> GraphEntries = [];
|
||||
private GraphEntry? SelectedGraphEntry;
|
||||
|
||||
@ -125,12 +121,15 @@ namespace Elwig.Windows {
|
||||
private void FillInputs() {
|
||||
FillingInputs = true;
|
||||
|
||||
if (SelectedGraphEntry?.GebundenFlatBonus != null) {
|
||||
if (SelectedGraphEntry?.GebundenFlatBonus is double bonus) {
|
||||
GebundenTypeFixed.IsChecked = true;
|
||||
GebundenFlatBonus.Text = $"{bonus}";
|
||||
} else if (SelectedGraphEntry?.GebundenGraph != null) {
|
||||
GebundenTypeGraph.IsChecked = true;
|
||||
GebundenFlatBonus.Text = "";
|
||||
} else {
|
||||
GebundenTypeNone.IsChecked = true;
|
||||
GebundenFlatBonus.Text = "";
|
||||
}
|
||||
|
||||
ControlUtils.SelectCheckComboBoxItems(ContractInput, SelectedGraphEntry?.Contracts ?? [], i => (i as ContractSelection)?.Listing);
|
||||
@ -165,7 +164,7 @@ namespace Elwig.Windows {
|
||||
OechslePricePlot.Configuration.DoubleClickBenchmark = false;
|
||||
//OechslePricePlot.Plot.XAxis.ManualTickSpacing(1);
|
||||
OechslePricePlot.Plot.YAxis.ManualTickSpacing(0.1);
|
||||
OechslePricePlot.Plot.SetAxisLimits(Math.Min(MinOechsle, MinOechsleGebunden) - 1, MaxOechsle + 1, -0.1, 2);
|
||||
OechslePricePlot.Plot.SetAxisLimits(Math.Min(GraphEntry.MinX, GraphEntry.MinXGeb) - 1, GraphEntry.MaxX + 1, -0.1, 2);
|
||||
|
||||
OechslePricePlot.Plot.Layout(padding: 0);
|
||||
OechslePricePlot.Plot.XAxis2.Layout(padding: 0);
|
||||
@ -247,17 +246,17 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private void LockZoom() {
|
||||
OechslePricePlot.Plot.XAxis.SetBoundary(MinOechsle - 1, MaxOechsle + 1);
|
||||
OechslePricePlot.Plot.XAxis.SetBoundary(GraphEntry.MinX - 1, GraphEntry.MaxX + 1);
|
||||
OechslePricePlot.Plot.YAxis.SetBoundary(-0.1, 2);
|
||||
OechslePricePlot.Plot.XAxis.SetZoomOutLimit(MaxOechsle - MinOechsle + 2);
|
||||
OechslePricePlot.Plot.XAxis.SetZoomOutLimit(GraphEntry.MaxX - GraphEntry.MinX + 2);
|
||||
OechslePricePlot.Plot.YAxis.SetZoomOutLimit(2.1);
|
||||
OechslePricePlot.Plot.SetAxisLimits(MinOechsle - 1, MaxOechsle + 1, -0.1, 2);
|
||||
OechslePricePlot.Plot.SetAxisLimits(GraphEntry.MinX - 1, GraphEntry.MaxX + 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.XAxis.SetZoomOutLimit((GraphEntry.MaxX - GraphEntry.MinX) * 1.5);
|
||||
OechslePricePlot.Plot.YAxis.SetZoomOutLimit(3.5);
|
||||
}
|
||||
|
||||
@ -342,12 +341,11 @@ namespace Elwig.Windows {
|
||||
|
||||
private void PriceInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
if (PrimaryMarkedPoint != -1 && ActiveGraph != null) {
|
||||
bool success = double.TryParse(PriceInput.Text, out double price);
|
||||
|
||||
if (success) {
|
||||
if (double.TryParse(PriceInput.Text, out double price)) {
|
||||
ActiveGraph.SetPriceAt(PrimaryMarkedPoint, price);
|
||||
PrimaryMarkedPointPlot.Y = price;
|
||||
OechslePricePlot.Refresh();
|
||||
CheckGebundenTypeFixed();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -358,6 +356,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
ActiveGraph.FlattenGraphLeft(PrimaryMarkedPoint);
|
||||
OechslePricePlot.Render();
|
||||
CheckGebundenTypeFixed();
|
||||
}
|
||||
|
||||
private void RightFlatButton_Click(object sender, RoutedEventArgs evt) {
|
||||
@ -366,6 +365,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
ActiveGraph.FlattenGraphRight(PrimaryMarkedPoint);
|
||||
OechslePricePlot.Render();
|
||||
CheckGebundenTypeFixed();
|
||||
}
|
||||
|
||||
private void InterpolateButton_Click(object sender, RoutedEventArgs evt) {
|
||||
@ -374,6 +374,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
ActiveGraph.InterpolateGraph(PrimaryMarkedPoint, SecondaryMarkedPoint);
|
||||
OechslePricePlot.Render();
|
||||
CheckGebundenTypeFixed();
|
||||
}
|
||||
|
||||
private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) {
|
||||
@ -386,6 +387,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
ActiveGraph.LinearIncreaseGraphToEnd(PrimaryMarkedPoint, priceIncrease.Value);
|
||||
OechslePricePlot.Render();
|
||||
CheckGebundenTypeFixed();
|
||||
}
|
||||
|
||||
private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) {
|
||||
@ -500,7 +502,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private void AddButton_Click(object sender, RoutedEventArgs e) {
|
||||
GraphEntry newGraphEntry = new(GetMaxGraphId() + 1, Season.Precision, BillingData.CurveMode.Oe, MinOechsle, MinOechsleGebunden, MaxOechsle);
|
||||
GraphEntry newGraphEntry = new(GetMaxGraphId() + 1, Season.Precision, BillingData.CurveMode.Oe);
|
||||
GraphEntries.Add(newGraphEntry);
|
||||
GraphList.Items.Refresh();
|
||||
GraphList.SelectedItem = newGraphEntry;
|
||||
@ -600,9 +602,12 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
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));
|
||||
if (FillingInputs) return;
|
||||
var r = Validator.CheckDecimal(GebundenFlatBonus.TextBox, true, 2, Season.Precision);
|
||||
if (r.IsValid && SelectedGraphEntry != null) {
|
||||
SelectedGraphEntry.GebundenFlatBonus = double.Parse(GebundenFlatBonus.Text);
|
||||
ResetPlot();
|
||||
InitPlot();
|
||||
}
|
||||
}
|
||||
|
||||
@ -635,23 +640,32 @@ namespace Elwig.Windows {
|
||||
if (SelectedGraphEntry == null) {
|
||||
DisableUnitTextBox(GebundenFlatBonus);
|
||||
return;
|
||||
} else if (GebundenTypeNone.IsChecked == true) {
|
||||
SelectedGraphEntry.SetGebundenFlatBonus(null);
|
||||
}
|
||||
if (GebundenTypeNone.IsChecked == true) {
|
||||
SelectedGraphEntry.RemoveGebundenGraph();
|
||||
DisableUnitTextBox(GebundenFlatBonus);
|
||||
RefreshInputs();
|
||||
} else if (GebundenTypeFixed.IsChecked == true) {
|
||||
SelectedGraphEntry.SetGebundenFlatBonus(0);
|
||||
SelectedGraphEntry.RemoveGebundenGraph();
|
||||
SelectedGraphEntry.GebundenFlatBonus = double.TryParse(GebundenFlatBonus.Text, out var val) ? val : 0.1;
|
||||
SelectedGraphEntry.AddGebundenGraph();
|
||||
EnableUnitTextBox(GebundenFlatBonus);
|
||||
RefreshInputs();
|
||||
} else if (GebundenTypeGraph.IsChecked == true) {
|
||||
GebundenFlatBonus.Text = "";
|
||||
SelectedGraphEntry.SetGebundenFlatBonus(null);
|
||||
SelectedGraphEntry.AddGebundenGraph();
|
||||
DisableUnitTextBox(GebundenFlatBonus);
|
||||
RefreshInputs();
|
||||
}
|
||||
RefreshInputs();
|
||||
}
|
||||
|
||||
private void CheckGebundenTypeFixed() {
|
||||
FillingInputs = true;
|
||||
if (SelectedGraphEntry?.GebundenFlatBonus is double bonus) {
|
||||
GebundenTypeFixed.IsChecked = true;
|
||||
GebundenFlatBonus.Text = $"{bonus}";
|
||||
EnableUnitTextBox(GebundenFlatBonus);
|
||||
} else {
|
||||
GebundenTypeGraph.IsChecked = true;
|
||||
DisableUnitTextBox(GebundenFlatBonus);
|
||||
}
|
||||
FillingInputs = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user