350 lines
13 KiB
C#
350 lines
13 KiB
C#
using FieldVisualizer.Entities.ColorMaps;
|
|
using FieldVisualizer.Entities.ColorMaps.Factories;
|
|
using FieldVisualizer.Entities.Values;
|
|
using FieldVisualizer.Entities.Values.Primitives;
|
|
using FieldVisualizer.Infrastructure.Commands;
|
|
using FieldVisualizer.Services.ColorServices;
|
|
using FieldVisualizer.Services.PrimitiveServices;
|
|
using FieldVisualizer.Services.ValueRanges;
|
|
using FieldVisualizer.Windows.UserControls;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using System.Windows.Shapes;
|
|
|
|
namespace FieldVisualizer.ViewModels.FieldViewerViewModels
|
|
{
|
|
public class FieldViewerViewModel : ViewModelBase, IDataErrorInfo
|
|
{
|
|
private ICommand setCrossLineCommand;
|
|
private IPrimitiveSet primitiveSet;
|
|
private double dX, dY;
|
|
private ColorMapsTypes _ColorMapType = ColorMapsTypes.LiraSpectrum;
|
|
private IColorMap _ColorMap;
|
|
private IValueRange valueRange;
|
|
private IEnumerable<IValueRange> valueRanges;
|
|
private IEnumerable<IValueColorRange> valueColorRanges;
|
|
private bool setMinValue;
|
|
private bool setMaxValue;
|
|
private double crossLineX;
|
|
private double crossLineY;
|
|
private double sumAboveLine;
|
|
private double sumUnderLine;
|
|
private Line previosLine;
|
|
const int RangeNumber = 16;
|
|
private const int zoomFactor = 1000;
|
|
private RelayCommand rebuildCommand;
|
|
|
|
public ICommand RebuildCommand => rebuildCommand ??= new RelayCommand(o => ProcessPrimitives(), o => PrimitiveValidation());
|
|
public ICommand ZoomInCommand { get; }
|
|
public ICommand ZoomOutCommand { get; }
|
|
public ICommand ChangeColorMapCommand { get; }
|
|
public ICommand SetUserColorsCommand { get; }
|
|
public ICommand SetCrossLineCommand
|
|
{
|
|
get
|
|
{
|
|
if (setCrossLineCommand == null)
|
|
{
|
|
setCrossLineCommand = new RelayCommand(SetCrossLine);
|
|
}
|
|
|
|
return setCrossLineCommand;
|
|
}
|
|
}
|
|
|
|
public IPrimitiveSet PrimitiveSet
|
|
{ get
|
|
{
|
|
return primitiveSet;
|
|
}
|
|
set
|
|
{
|
|
primitiveSet = value;
|
|
AreaTotal = primitiveSet is null ? 0 : primitiveSet.ValuePrimitives.Sum(x => x.Area);
|
|
AreaNeg = primitiveSet is null ? 0 : primitiveSet.ValuePrimitives.Where(x => x.Value < 0d).Sum(x => x.Area);
|
|
AreaZero = primitiveSet is null ? 0 : primitiveSet.ValuePrimitives.Where(x => x.Value == 0d).Sum(x => x.Area);
|
|
AreaPos = primitiveSet is null ? 0 : primitiveSet.ValuePrimitives.Where(x => x.Value > 0d).Sum(x => x.Area);
|
|
SumTotal = primitiveSet is null ? 0 : primitiveSet.ValuePrimitives.Sum(x => x.Value);
|
|
SumNeg = primitiveSet is null ? 0 : primitiveSet.ValuePrimitives.Where(x => x.Value < 0d).Sum(x => x.Value);
|
|
SumPos = primitiveSet is null ? 0 : primitiveSet.ValuePrimitives.Where(x => x.Value > 0d).Sum(x => x.Value);
|
|
OnPropertyChanged(nameof(PrimitiveSet));
|
|
OnPropertyChanged(nameof(AreaTotal));
|
|
OnPropertyChanged(nameof(AreaNeg));
|
|
OnPropertyChanged(nameof(AreaZero));
|
|
OnPropertyChanged(nameof(AreaPos));
|
|
OnPropertyChanged(nameof(SumTotal));
|
|
OnPropertyChanged(nameof(SumNeg));
|
|
OnPropertyChanged(nameof(SumPos));
|
|
|
|
}
|
|
}
|
|
public IValueRange UserValueRange { get; set; }
|
|
public bool SetMinValue
|
|
{
|
|
get
|
|
{
|
|
return setMinValue;
|
|
}
|
|
set
|
|
{
|
|
setMinValue = value;
|
|
OnPropertyChanged(nameof(SetMinValue));
|
|
//OnPropertyChanged(nameof(UserMinValue));
|
|
}
|
|
}
|
|
public bool SetMaxValue
|
|
{
|
|
get
|
|
{
|
|
return setMaxValue;
|
|
}
|
|
set
|
|
{
|
|
setMaxValue = value;
|
|
OnPropertyChanged(nameof(SetMaxValue));
|
|
//OnPropertyChanged(nameof(UserMaxValue));
|
|
}
|
|
}
|
|
public double UserMinValue
|
|
{
|
|
get
|
|
{
|
|
return UserValueRange.BottomValue;
|
|
}
|
|
set
|
|
{
|
|
UserValueRange.BottomValue = value;
|
|
OnPropertyChanged(nameof(UserMinValue));
|
|
}
|
|
}
|
|
public double UserMaxValue
|
|
{
|
|
get
|
|
{
|
|
return UserValueRange.TopValue;
|
|
}
|
|
set
|
|
{
|
|
double tmpVal = UserValueRange.TopValue;
|
|
try
|
|
{
|
|
UserValueRange.TopValue = value;
|
|
OnPropertyChanged(nameof(UserMaxValue));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
UserValueRange.TopValue = tmpVal;
|
|
}
|
|
}
|
|
}
|
|
public double AreaTotal { get; private set; }
|
|
public double AreaNeg { get; private set; }
|
|
public double AreaZero { get; private set; }
|
|
public double AreaPos { get; private set; }
|
|
public double SumTotal { get; private set;}
|
|
public double SumNeg { get; private set; }
|
|
public double SumPos { get; private set; }
|
|
public Viewbox WorkPlaneBox { get; set; }
|
|
public VerticalLegend Legend { get; set; }
|
|
public Canvas WorkPlaneCanvas { get; set; }
|
|
public double ScrolWidth { get; set; }
|
|
public double ScrolHeight { get; set; }
|
|
public double CrossLineX { get => crossLineX; set => SetProperty(ref crossLineX, value); }
|
|
public double CrossLineY { get => crossLineY; set => SetProperty(ref crossLineY, value); }
|
|
|
|
public double SumAboveLine { get => sumAboveLine; set => SetProperty(ref sumAboveLine, value); }
|
|
public double SumUnderLine { get => sumUnderLine; set => SetProperty(ref sumUnderLine, value); }
|
|
|
|
public string Error { get; }
|
|
public string Title { get; set; }
|
|
public string SubTitle { get; set; }
|
|
|
|
public string this[string columnName]
|
|
{
|
|
get
|
|
{
|
|
string error = String.Empty;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public FieldViewerViewModel()
|
|
{
|
|
ZoomInCommand = new RelayCommand(o => Zoom(1.2), o => PrimitiveValidation());
|
|
ZoomOutCommand = new RelayCommand(o => Zoom(0.8), o => PrimitiveValidation());
|
|
ChangeColorMapCommand = new RelayCommand(o => ChangeColorMap(), o => PrimitiveValidation());
|
|
SetUserColorsCommand = new RelayCommand(o => ColorRefresh(), o => (SetMinValue || SetMaxValue));
|
|
UserValueRange = new ValueRange() { BottomValue = 0, TopValue = 0 };
|
|
SetMinValue = false;
|
|
SetMaxValue = false;
|
|
}
|
|
public void ColorRefresh()
|
|
{
|
|
if (PrimitiveValidation() == false) { return; }
|
|
_ColorMap = ColorMapFactory.GetColorMap(_ColorMapType);
|
|
SetColor();
|
|
if ((PrimitiveSet is null) == false)
|
|
{
|
|
ProcessPrimitives();
|
|
Legend.ValueColorRanges = valueColorRanges;
|
|
Legend.Refresh();
|
|
}
|
|
}
|
|
public void Refresh()
|
|
{
|
|
SetMinValue = false;
|
|
SetMaxValue = false;
|
|
ColorRefresh();
|
|
}
|
|
private void ProcessPrimitives()
|
|
{
|
|
WorkPlaneCanvas.Children.Clear();
|
|
Title = PrimitiveSet.Name;
|
|
OnPropertyChanged(nameof(Title));
|
|
SubTitle = PrimitiveSet.SubTitle;
|
|
OnPropertyChanged(nameof(SubTitle));
|
|
double sizeX = PrimitiveOperations.GetSizeX(PrimitiveSet.ValuePrimitives) * zoomFactor;
|
|
double sizeY = PrimitiveOperations.GetSizeY(PrimitiveSet.ValuePrimitives) * zoomFactor;
|
|
dX = PrimitiveOperations.GetMinMaxX(PrimitiveSet.ValuePrimitives)[0];
|
|
dY = PrimitiveOperations.GetMinMaxY(PrimitiveSet.ValuePrimitives)[1];
|
|
WorkPlaneCanvas.Width = Math.Abs(sizeX);
|
|
WorkPlaneCanvas.Height = Math.Abs(sizeY);
|
|
WorkPlaneBox.Width = (ScrolWidth - 50);
|
|
WorkPlaneBox.Height = (ScrolHeight - 50);
|
|
var logic = new AddPrimitivesToCanvasLogic()
|
|
{
|
|
WorkPlaneCanvas = WorkPlaneCanvas,
|
|
DX = dX,
|
|
DY = dY,
|
|
ValueRange = valueRange,
|
|
ColorMap = _ColorMap,
|
|
ValueColorRanges = valueColorRanges,
|
|
};
|
|
logic.ProcessPrimitives(PrimitiveSet.ValuePrimitives);
|
|
|
|
}
|
|
private void Zoom(double coefficient)
|
|
{
|
|
WorkPlaneBox.Width *= coefficient;
|
|
WorkPlaneBox.Height *= coefficient;
|
|
}
|
|
private void ChangeColorMap()
|
|
{
|
|
//Iterate all available color maps one by one
|
|
try
|
|
{
|
|
_ColorMapType++;
|
|
IColorMap colorMap = ColorMapFactory.GetColorMap(_ColorMapType);
|
|
}
|
|
catch (Exception ex) { _ColorMapType = 0; }
|
|
ColorRefresh();
|
|
}
|
|
private bool PrimitiveValidation()
|
|
{
|
|
if (PrimitiveSet == null || PrimitiveSet.ValuePrimitives.Count() == 0)
|
|
{
|
|
return false;
|
|
}
|
|
else return true;
|
|
}
|
|
private void SetColor()
|
|
{
|
|
valueRange = PrimitiveOperations.GetValueRange(PrimitiveSet.ValuePrimitives);
|
|
//if bottom value is greater than top value
|
|
if (SetMinValue
|
|
& SetMaxValue
|
|
& (UserValueRange.BottomValue > UserValueRange.TopValue))
|
|
{
|
|
UserValueRange.TopValue = UserValueRange.BottomValue;
|
|
}
|
|
if (SetMinValue == true)
|
|
{
|
|
valueRange.BottomValue = UserValueRange.BottomValue;
|
|
}
|
|
else
|
|
{
|
|
UserValueRange.BottomValue = valueRange.BottomValue;
|
|
}
|
|
if (SetMaxValue == true)
|
|
{
|
|
valueRange.TopValue = UserValueRange.TopValue;
|
|
}
|
|
else
|
|
{
|
|
UserValueRange.TopValue = valueRange.TopValue;
|
|
}
|
|
valueRanges = ValueRangeOperations.DivideValueRange(valueRange, RangeNumber);
|
|
valueColorRanges = ColorOperations.GetValueColorRanges(valueRange, valueRanges, _ColorMap);
|
|
}
|
|
private void SetCrossLine(object commandParameter)
|
|
{
|
|
AddCrossLine();
|
|
AddSummaryInfoCrossLine();
|
|
}
|
|
private void AddCrossLine()
|
|
{
|
|
double width = WorkPlaneCanvas.ActualWidth;
|
|
double heigth = WorkPlaneCanvas.ActualHeight;
|
|
Line line = new Line();
|
|
if (crossLineX == 0d)
|
|
{
|
|
line.X1 = - width / 2d - dX;
|
|
line.Y1 = - crossLineY + dY;
|
|
line.X2 = width / 2d - dX;
|
|
line.Y2 = - crossLineY + dY;
|
|
}
|
|
else if (crossLineY == 0d)
|
|
{
|
|
line.X1 = crossLineX - dX;
|
|
line.Y1 = heigth / 2 + dY;
|
|
line.X2 = crossLineX - dX;
|
|
line.Y2 = -heigth / 2 + dY;
|
|
}
|
|
else
|
|
{
|
|
line.X1 = - width / 2d - dX;
|
|
line.Y1 = -(crossLineY / crossLineX * width / 2 + crossLineY) - dY;
|
|
line.X2 = width / 2d - dX;
|
|
line.Y2 = -(-crossLineY / crossLineX * width / 2 + crossLineY) - dY ;
|
|
}
|
|
SolidColorBrush brush = new SolidColorBrush();
|
|
brush.Color = Colors.Red;
|
|
line.Fill = brush;
|
|
line.Stroke = brush;
|
|
line.StrokeThickness = (width + heigth) / 100;
|
|
if (previosLine != null)
|
|
{
|
|
try { WorkPlaneCanvas.Children.Remove(previosLine);}
|
|
catch (Exception) {}
|
|
}
|
|
previosLine = line;
|
|
WorkPlaneCanvas.Children.Add(line);
|
|
}
|
|
private double GetPointOfCrossLine(double x)
|
|
{
|
|
double y;
|
|
if (crossLineX == 0d)
|
|
{
|
|
y = crossLineY;
|
|
}
|
|
else
|
|
{
|
|
y = -crossLineY / crossLineX - crossLineY;
|
|
}
|
|
return y;
|
|
}
|
|
private void AddSummaryInfoCrossLine()
|
|
{
|
|
SumAboveLine = primitiveSet is null ? 0 : primitiveSet.ValuePrimitives.Where(x=>x.CenterY >= GetPointOfCrossLine(x.CenterX)).Sum(x => x.Value);
|
|
SumUnderLine = primitiveSet is null ? 0 : primitiveSet.ValuePrimitives.Where(x => x.CenterY <= GetPointOfCrossLine(x.CenterX)).Sum(x => x.Value);
|
|
}
|
|
}
|
|
}
|