Add series to graph

This commit is contained in:
Evgeny Redikultsev
2023-12-23 22:40:42 +05:00
parent a19333f7df
commit 0a6d29bcfc
38 changed files with 762 additions and 233 deletions

View File

@@ -86,7 +86,6 @@
<Folder Include="Infrastructure\UI\DataContexts\Logics\" />
<Folder Include="Resources\" />
<Folder Include="Windows\UserControls\MultiplyTuples\" />
<Folder Include="Windows\ViewModels\Graphs\" />
</ItemGroup>
<ItemGroup>

View File

@@ -73,7 +73,9 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews
{
SafetyProcessor.RunSafeProcess(() =>
{
var wnd = new GraphView(arrayParameter);
var series = new Series(arrayParameter) { Name = "Forces and curvatures" };
var vm = new GraphViewModel(new List<Series>() { series });
var wnd = new GraphView(vm);
wnd.ShowDialog();
},
"Errors appeared during showing a graph, see detailed information");

View File

@@ -9,6 +9,7 @@ using StructureHelperCommon.Models.Parameters;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Services.Units;
using StructureHelperLogics.NdmCalculations.Analyses.ByForces;
using StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve;
using StructureHelperLogics.NdmCalculations.Primitives;
using StructureHelperLogics.Services.NdmPrimitives;
using System;
@@ -17,6 +18,9 @@ using System.ComponentModel;
using System.Linq;
using System.Windows;
//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalculatorViews
{
internal class InteractionDiagramLogic : ILongProcessLogic
@@ -24,46 +28,36 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
const string ForceUnitString = "kN";
const string MomentUnitString = "kNm";
private ArrayParameter<double> arrayParameter;
//private List<ArrayParameter<double>> arrayParameters;
private IResult result;
private IUnit unitForce = CommonOperation.GetUnit(UnitTypes.Force, ForceUnitString);
private IUnit unitMoment = CommonOperation.GetUnit(UnitTypes.Moment, MomentUnitString);
private int stepCount;
private static GeometryNames GeometryNames => ProgramSetting.GeometryNames;
public int StepCount => SurroundData.PointCount;
public LimitCurveInputData InputData { get; set; }
public int StepCount { get => stepCount; set => stepCount = value; }
public Action<int> SetProgress { get; set; }
public bool Result { get; set; }
public IEnumerable<INdmPrimitive> NdmPrimitives { get; set; }
public LimitStates LimitState { get; set; }
public CalcTerms CalcTerm { get; set; }
//public ForceTuple ForceTuple { get; set; }
public SurroundData SurroundData { get; set; }
public InteractionDiagramLogic(SurroundData surroundData)
public InteractionDiagramLogic(LimitCurveInputData inputData)
{
SurroundData = surroundData;
InputData = inputData;
stepCount = InputData.PointCount;
stepCount *= InputData.LimitStates.Count();
stepCount *= InputData.CalcTerms.Count();
stepCount *= InputData.PredicateEntries.Count();
//arrayParameters = new();
}
private void DoCalculations()
{
var ndmCollection = NdmPrimitivesService.GetNdms(NdmPrimitives, LimitState, CalcTerm);
var convertLogic = SurroundData.ConvertLogicEntity;
convertLogic.ConstDirectionValue = SurroundData.ConstZ;
var predicateFactory = new PredicateFactory()
var convertLogic = InputData.SurroundData.ConvertLogicEntity;
var calculator = new LimitCurvesCalculator()
{
Ndms = ndmCollection,
ConvertLogic = convertLogic.ConvertLogic,
InputData = InputData
};
Predicate<IPoint2D> predicate = predicateFactory.IsSectionFailure;
//Predicate<IPoint2D> predicate = predicateFactory.IsSectionCracked;
//var logic = new StabLimitCurveLogic();
var logic = new LimitCurveLogic(predicate);
var calculator = new LimitCurveCalculator(logic);
calculator.SurroundData = SurroundData;
calculator.ActionToOutputResults = SetProgressByResult;
SafetyProcessor.RunSafeProcess(() =>
{
@@ -71,15 +65,34 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
}, "Errors appeared during showing a graph, see detailed information");
}
private void CalcResult(LimitCurveCalculator calculator)
private void CalcResult(LimitCurvesCalculator calculator)
{
calculator.Run();
result = calculator.Result;
if (result.IsValid == false) { return; }
var interactionResult = result as LimitCurveResult;
var curvesResult = calculator.Result as LimitCurvesResult;
if (curvesResult.IsValid == false) { return; }
result = curvesResult;
foreach (var curveResult in curvesResult.LimitCurveResults)
{
ProcessCurveResult(curveResult);
}
}
private void ProcessCurveResult(LimitCurveResult curveResult)
{
if (curveResult.IsValid == false)
{
SafetyProcessor.ShowMessage("Calculation error", curveResult.Description);
return;
}
//var arrayParameter = GetParametersByCurveResult(curveResult);
//arrayParameters.Add(arrayParameter);
}
private ArrayParameter<double> GetParametersByCurveResult(LimitCurveResult curveResult)
{
string[] labels = GetLabels();
var items = interactionResult.Points;
arrayParameter = new ArrayParameter<double>(items.Count(), labels.Count(), labels);
var items = curveResult.Points;
var arrayParameter = new ArrayParameter<double>(items.Count(), labels.Count(), labels);
var data = arrayParameter.Data;
for (int i = 0; i < items.Count(); i++)
{
@@ -94,23 +107,25 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
data[i, j] = valueList[j];
}
}
return arrayParameter;
}
private void SetProgressByResult(IResult calcResult)
{
if (calcResult is not LimitCurveResult)
if (calcResult is not LimitCurvesResult)
{
throw new StructureHelperException(ErrorStrings.ExpectedWas(typeof(LimitCurveResult), calcResult));
throw new StructureHelperException(ErrorStrings.ExpectedWas(typeof(LimitCurvesResult), calcResult));
}
var parameterResult = calcResult as LimitCurveResult;
var parameterResult = calcResult as LimitCurvesResult;
StepCount = stepCount;// parameterResult.MaxIterationCount;
SetProgress?.Invoke(parameterResult.IterationNumber);
}
private string[] GetLabels()
{
string[] strings = new string[2];
strings[0] = GetLabel(SurroundData.ConvertLogicEntity.XForceType);
strings[1] = GetLabel(SurroundData.ConvertLogicEntity.YForceType);
strings[0] = GetLabel(InputData.SurroundData.ConvertLogicEntity.XForceType);
strings[1] = GetLabel(InputData.SurroundData.ConvertLogicEntity.YForceType);
return strings;
}
@@ -141,7 +156,15 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
{
if (result.IsValid == true)
{
var wnd = new GraphView(arrayParameter);
var curveResult = result as LimitCurvesResult;
var seriesList = new List<Series>();
foreach (var item in curveResult.LimitCurveResults)
{
var series = new Series(GetParametersByCurveResult(item)) { Name = item.Name };
seriesList.Add(series);
}
var vm = new GraphViewModel(seriesList);
var wnd = new GraphView(vm);
wnd.ShowDialog();
}
else

View File

@@ -13,9 +13,23 @@
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="35"/>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<fc:SurroundDataControl x:Name="SurData" SurroundData="{Binding SurroundData}"/>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Point count"/>
<TextBox Grid.Column="1" Text="{Binding PointCount, ValidatesOnDataErrors=True}"/>
<uc:MultiplyDouble Margin="2" Grid.Column="3" ValueChanged="PointCountChanged"/>
</Grid>
<!--<ContentControl ContentTemplate="{StaticResource SurroundData}" Content="{Binding SurroundDataViewModel}"/>-->
<ContentControl Grid.Row="1" ContentTemplate="{StaticResource OkCancelButtons}" Content="{Binding}"/>
<ContentControl Grid.Row="2" ContentTemplate="{StaticResource OkCancelButtons}" Content="{Binding}"/>
</Grid>
</Window>

View File

@@ -31,5 +31,16 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
InitializeComponent();
SurData.SurroundData = vm.SurroundData;
}
private void PointCountChanged(object sender, EventArgs e)
{
viewModel.PointCount = Convert.ToInt32(viewModel.PointCount * ChangeValue(sender));
}
private double ChangeValue(object sender)
{
var obj = (MultiplyDouble)sender;
var factor = obj.DoubleFactor;
return factor;
}
}
}

View File

@@ -6,6 +6,7 @@ using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Services.Units;
using StructureHelperLogics.NdmCalculations.Analyses.ByForces;
using StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -17,16 +18,75 @@ using System.Windows.Data;
namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalculatorViews.ForceResultLogic
{
public class LimitCurveDataViewModel : OkCancelViewModelBase
public class LimitCurveDataViewModel : OkCancelViewModelBase, IDataErrorInfo
{
private int pointCount;
//public SurroundDataViewModel SurroundDataViewModel { get; private set; }
public SurroundData SurroundData { get; set; }
public List<INdmPrimitive> Primitives { get; set; }
public int PointCount
{
get => pointCount; set
{
try
{
pointCount = value;
}
catch (Exception)
{
pointCount = 40;
}
OnPropertyChanged(nameof(PointCount));
}
}
public LimitCurveDataViewModel(SurroundData surroundData)
{
//SurroundDataViewModel = new(surroundData);
SurroundData = surroundData;
pointCount = 80;
}
public LimitCurveDataViewModel() : this (new SurroundData())
{
}
public LimitCurveInputData GetLimitCurveInputData()
{
LimitCurveInputData inputData = new()
{
SurroundData = SurroundData,
PointCount = pointCount
};
inputData.LimitStates.Add(LimitStates.ULS);
inputData.LimitStates.Add(LimitStates.SLS);
inputData.CalcTerms.Add(CalcTerms.ShortTerm);
inputData.CalcTerms.Add(CalcTerms.LongTerm);
inputData.PredicateEntries.Add(new PredicateEntry() { Name = "Strength", PredicateType = PredicateTypes.Strength });
inputData.PredicateEntries.Add(new PredicateEntry() { Name = "Cracking", PredicateType = PredicateTypes.Cracking });
inputData.Primitives = Primitives;
return inputData;
}
public string Error => throw new NotImplementedException();
public string this[string columnName]
{
get
{
string error = String.Empty;
switch (columnName)
{
case nameof(PointCount):
if (PointCount < 24)
{
error = "Point count must be greater than 24";
}
break;
}
return error;
}
}
}
}

View File

@@ -47,7 +47,9 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
{
SafetyProcessor.RunSafeProcess(() =>
{
var wnd = new GraphView(arrayParameter);
var series = new Series(arrayParameter) { Name = "Forces and curvatures" };
var vm = new GraphViewModel(new List<Series>() { series});
var wnd = new GraphView(vm);
wnd.ShowDialog();
},
"Errors appeared during showing a graph, see detailed information");

View File

@@ -46,6 +46,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
public void ShowProgressResult(int progressValue)
{
progressViewModel.MaxValue = processLogic.StepCount;
progressViewModel.ProgressValue = progressValue;
}

View File

@@ -21,6 +21,7 @@ using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Services.Forces;
using StructureHelperLogics.NdmCalculations.Analyses;
using StructureHelperLogics.NdmCalculations.Analyses.ByForces;
using StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve;
using StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics;
using StructureHelperLogics.NdmCalculations.Analyses.Geometry;
using StructureHelperLogics.NdmCalculations.Primitives;
@@ -74,26 +75,21 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
return showInteractionDiagramCommand ??
(showInteractionDiagramCommand = new RelayCommand(o =>
{
var tuple = SelectedResult.DesignForceTuple.ForceTuple.Clone() as ForceTuple;
var data = new SurroundData();
//data.ConstZ = tuple.My;
var wnd = new LimitCurveDataView(data);
var surroundDdata = new SurroundData();
var vm = new LimitCurveDataViewModel(surroundDdata);
vm.Primitives = ndmPrimitives.ToList();
var wnd = new LimitCurveDataView(vm);
wnd.ShowDialog();
if (wnd.DialogResult != true) return;
interactionDiagramLogic = new(data)
{
//ForceTuple = tuple,
LimitState = SelectedResult.DesignForceTuple.LimitState,
CalcTerm = SelectedResult.DesignForceTuple.CalcTerm,
NdmPrimitives = ndmPrimitives
};
var inputData = vm.GetLimitCurveInputData();
interactionDiagramLogic = new(inputData);
showProgressLogic = new(interactionDiagramLogic)
{
WindowTitle = "Diagram creating...",
ShowResult = interactionDiagramLogic.ShowWindow
};
showProgressLogic.Show();
}, o => SelectedResult != null && SelectedResult.IsValid));
}));
}
}
public ICommand ShowIsoFieldCommand
@@ -160,7 +156,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
};
showProgressLogic.Show();
}
}
}, o => SelectedResult != null && SelectedResult.IsValid
);
}
public ICommand ShowCrackGraphsCommand
@@ -191,7 +187,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
};
showProgressLogic.Show();
}
}
}, o => SelectedResult != null && SelectedResult.IsValid
);
}
public ICommand ShowCrackResultCommand

View File

@@ -87,17 +87,6 @@
</Grid>
</GroupBox>
<Grid Margin="35,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Point count"/>
<TextBox Grid.Column="1" Text="{Binding PointCount, ValidatesOnDataErrors=True}"/>
<uc:MultiplyDouble Margin="2" Grid.Column="3" ValueChanged="PointCountChanged"/>
</Grid>
</StackPanel>
</Grid>

View File

@@ -59,7 +59,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
{
if (SurroundData is null)
{
ViewModel = new SurroundDataViewModel(new() { PointCount = 40 });
ViewModel = new SurroundDataViewModel(new());
}
else
{
@@ -90,10 +90,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
{
ViewModel.ConstZ *= ChangeValue(sender);
}
private void PointCountChanged(object sender, EventArgs e)
{
ViewModel.PointCount = Convert.ToInt32(ViewModel.PointCount * ChangeValue(sender));
}
private double ChangeValue(object sender)
{

View File

@@ -39,7 +39,6 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
OnPropertyChanged(nameof(YMax));
OnPropertyChanged(nameof(YMin));
OnPropertyChanged(nameof(ConstZ));
OnPropertyChanged(nameof(PointCount));
OnPropertyChanged(nameof(XLabel));
OnPropertyChanged(nameof(YLabel));
OnPropertyChanged(nameof(ZLabel));
@@ -162,22 +161,6 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
}
}
public int PointCount
{
get => SurroundData.PointCount; set
{
try
{
SurroundData.PointCount = value;
}
catch (Exception)
{
SurroundData.PointCount = 40;
}
OnPropertyChanged(nameof(PointCount));
}
}
public string Error => throw new NotImplementedException();
public string this[string columnName]
@@ -187,12 +170,12 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
string error = String.Empty;
switch (columnName)
{
case nameof(PointCount):
if (PointCount < 24)
{
error = "Point count must be greater than 24";
}
break;
//case nameof(PointCount):
// if (PointCount < 24)
// {
// error = "Point count must be greater than 24";
// }
// break;
}
return error;
}

View File

@@ -15,6 +15,10 @@ namespace StructureHelper.Windows.Graphs
{
lineSeries.Stroke = new SolidColorBrush(color);
lineSeries.Fill = new SolidColorBrush(color) { Opacity = visualProps.Opacity };
SetVisualProps(lineSeries, visualProps);
}
public static void SetVisualProps(LineSeries lineSeries, GraphVisualProps visualProps)
{
lineSeries.LineSmoothness = visualProps.LineSmoothness;
lineSeries.PointGeometry = DefaultGeometries.Circle;
lineSeries.PointGeometrySize = visualProps.StrokeSize;

View File

@@ -24,15 +24,19 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="170"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid>
<ListBox ItemsSource="{Binding Series}">
<ListBox.ItemTemplate>
<DataTemplate>
<Expander Header="{Binding Name}" IsExpanded="True" Background="{Binding Color}">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
<RowDefinition/>
<RowDefinition Height="170"/>
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Header="X-axis values">
<GroupBox Grid.Row="0" Margin="10,0,10,0" Header="X-axis values">
<StackPanel>
<ComboBox ItemsSource="{Binding XItems.Collection}" SelectedItem="{Binding XItems.SelectedItem}">
<ComboBox.ItemTemplate>
@@ -56,7 +60,7 @@
</StackPanel>
</GroupBox>
<GroupBox Grid.Row="1" Header="Y-axis values">
<GroupBox Grid.Row="1" Margin="10,0,10,0" Header="Y-axis values">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
@@ -66,9 +70,14 @@
<CheckBox Grid.Row="1" Margin="5" Content="Invert Values" IsChecked="{Binding InvertYValues}"/>
</Grid>
</GroupBox>
<ContentControl Grid.Row="2" ContentTemplate="{StaticResource ResourceKey=LineVisualProperties}" Content="{Binding VisualProps}"/>
</Grid>
<StackPanel Grid.Row="1">
</Expander>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ContentControl Grid.Row="1" ContentTemplate="{StaticResource ResourceKey=LineVisualProperties}" Content="{Binding VisualProps}"/>
<StackPanel Grid.Row="2">
<Button Margin="3" Content="Draw Lines" ToolTip="Draw Lines" Command="{Binding RedrawLinesCommand}"/>
</StackPanel>
</Grid>

View File

@@ -35,5 +35,8 @@ namespace StructureHelper.Windows.Graphs
public GraphView(ArrayParameter<double> arrayParameter) : this(new GraphViewModel(arrayParameter))
{
}
public GraphView(IEnumerable<ArrayParameter<double>> arrayParameters) : this(new GraphViewModel(arrayParameters))
{
}
}
}

View File

@@ -17,6 +17,9 @@ using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelper.Windows.Graphs
{
public class GraphViewModel : ViewModelBase
@@ -28,9 +31,8 @@ namespace StructureHelper.Windows.Graphs
}
IArrayParameter<double> arrayParameter;
List<IValueParameter<double>> valueParameters;
Dictionary<IValueParameter<double>, double[]> valueList;
List<IArrayParameter<double>> arrayParameters;
private RelayCommand redrawLinesCommand;
private bool invertXValues;
private bool invertYValues;
@@ -39,6 +41,7 @@ namespace StructureHelper.Windows.Graphs
public SelectedItemViewModel<IValueParameter<double>> XItems { get; private set; }
public SelectItemsViewModel<IValueParameter<double>> YItems { get; set; }
public ObservableCollection<ColumnInfo> Columns { get; } = new ObservableCollection<ColumnInfo>();
public ObservableCollection<Series> Series { get;}
public bool InvertXValues
@@ -68,7 +71,7 @@ namespace StructureHelper.Windows.Graphs
public ICommand RedrawLinesCommand
{
get => redrawLinesCommand ??= new RelayCommand(o => DrawLines());
get => redrawLinesCommand ??= new RelayCommand(o => DrawSeries());
}
public ICommand SaveAsImage
@@ -102,47 +105,36 @@ namespace StructureHelper.Windows.Graphs
Clipboard.SetImage(bitmapImage);
}
public GraphViewModel(IArrayParameter<double> arrayParameter)
public GraphViewModel(IArrayParameter<double> arrayParameter) : this (new List<IArrayParameter<double>>() { arrayParameter})
{
this.arrayParameter = arrayParameter;
valueParameters = GetParameters();
XItems = new SelectedItemViewModel<IValueParameter<double>>(valueParameters);
YItems = new SelectItemsViewModel<IValueParameter<double>>(valueParameters);
YItems.ShowButtons = true;
XItems.SelectedItem = XItems.Collection[0];
YItems.UnSelectAllCommand.Execute(null);
}
public GraphViewModel(IEnumerable<IArrayParameter<double>> arrayParameters)
{
this.arrayParameters = arrayParameters.ToList();
Series = new();
foreach (var item in this.arrayParameters)
{
Series.Add(new Series(item));
}
VisualProps = new();
}
private List<IValueParameter<double>> GetParameters()
public GraphViewModel(IEnumerable<Series> series)
{
valueList = new Dictionary<IValueParameter<double>, double[]>();
var items = new List<IValueParameter<double>>();
var data = arrayParameter.Data;
int columnCount = data.GetLength(1);
for (int i = 0; i < columnCount; i++)
Series = new();
foreach (var item in series)
{
var item = new ValueParameter<double>()
{
Name = arrayParameter.ColumnLabels[i],
Color = ColorProcessor.GetRandomColor(),
};
items.Add(item);
int rowCount = data.GetLength(0);
var values = new double[rowCount];
for (int j = 0; j < rowCount; j++)
{
values[j] = data[j, i];
Series.Add(item);
}
valueList.Add(item, values);
}
return items;
VisualProps = new();
}
private void DrawLines()
private void DrawSeries()
{
if (XItems.SelectedItem is null || YItems.SelectedCount == 0) return;
SetLines();
OnPropertyChanged(nameof(SeriesCollection));
OnPropertyChanged(nameof(Labels));
@@ -150,47 +142,15 @@ namespace StructureHelper.Windows.Graphs
private void SetLines()
{
var xParameter = XItems.SelectedItem;
var yParameters = YItems.SelectedItems;
var xFactor = invertXValues ? -1d : 1d;
var yFactor = invertYValues ? -1d : 1d;
var labels = new List<double>();
SeriesCollection = new SeriesCollection();
foreach (var yParameter in yParameters)
Labels = new();
foreach (var series in Series)
{
var localLabels = new List<double>();
var lineSeries = new LineSeries()
{
Configuration = new CartesianMapper<IPoint2D>()
.X(point => point.X)
.Y(point => point.Y),
Title = yParameter.Name,
};
GraphService.SetVisualProps(lineSeries, VisualProps, yParameter.Color);
_ = valueList.TryGetValue(xParameter, out double[] xValues);
_ = valueList.TryGetValue(yParameter, out double[] yValues);
var chartValues = new ChartValues<Point2D>();
for (int i = 0; i < yValues.Count(); i++)
{
double diagramValue = yValues[i] * yFactor;
var x = xValues[i] * xFactor;
var y = yValues[i] * yFactor;
var point = new Point2D() { X = x, Y = y };
chartValues.Add(point);
labels.Add(x);
localLabels.Add(x);
series.VisualProps = VisualProps;
series.RefreshSeries();
SeriesCollection.AddRange(series.SeriesCollection);
Labels.AddRange(series.Labels);
}
lineSeries.Values = chartValues;
//lineSeries.LabelPoint = point => localLabels[(int)point.X].ToString();
SeriesCollection.Add(lineSeries);
}
Labels = labels
.OrderBy(x => x)
.Distinct()
.Select(x => x.ToString())
.ToList();
}
}
}

View File

@@ -220,7 +220,7 @@ namespace StructureHelper.Windows.Graphs
}
else
{
GraphService.SetVisualProps(lineSeries, VisualProps, ColorProcessor.GetRandomColor());
GraphService.SetVisualProps(lineSeries, VisualProps);
}
var chartValues = new ChartValues<double>();
for (double s = minValue; s < maxValue; s += step)

View File

@@ -0,0 +1,148 @@
using LiveCharts;
using LiveCharts.Configurations;
using LiveCharts.Wpf;
using StructureHelper.Infrastructure;
using StructureHelper.Windows.ViewModels;
using StructureHelperCommon.Models.Parameters;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Services.ColorServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelper.Windows.Graphs
{
public class Series : ViewModelBase
{
private IArrayParameter<double> arrayParameter;
private List<IValueParameter<double>> valueParameters;
private Dictionary<IValueParameter<double>, double[]> valueList;
private bool invertXValues;
private bool invertYValues;
public SelectedItemViewModel<IValueParameter<double>> XItems { get; }
public SelectItemsViewModel<IValueParameter<double>> YItems { get; }
public bool InvertXValues
{
get { return invertXValues; }
set
{
invertXValues = value;
OnPropertyChanged(nameof(InvertXValues));
}
}
public bool InvertYValues
{
get { return invertYValues; }
set
{
invertYValues = value;
OnPropertyChanged(nameof(InvertYValues));
}
}
public GraphVisualProps VisualProps { get; set; }
public SeriesCollection SeriesCollection { get; private set; }
public List<string> Labels { get; private set; }
public Color Color { get; private set; }
public string Name { get; set; }
public IArrayParameter<double> ArrayParameter { get; set; }
public Series(IArrayParameter<double> arrayParameter)
{
this.arrayParameter = arrayParameter;
valueParameters = GetParameters();
XItems = new SelectedItemViewModel<IValueParameter<double>>(valueParameters);
YItems = new SelectItemsViewModel<IValueParameter<double>>(valueParameters);
YItems.ShowButtons = true;
XItems.SelectedItem = XItems.Collection[0];
YItems.UnSelectAllCommand.Execute(null);
VisualProps = new();
Color = ColorProcessor.GetRandomColor();
}
private List<IValueParameter<double>> GetParameters()
{
valueList = new Dictionary<IValueParameter<double>, double[]>();
var items = new List<IValueParameter<double>>();
var data = arrayParameter.Data;
int columnCount = data.GetLength(1);
for (int i = 0; i < columnCount; i++)
{
var item = new ValueParameter<double>()
{
Name = arrayParameter.ColumnLabels[i],
Color = ColorProcessor.GetRandomColor(),
};
items.Add(item);
int rowCount = data.GetLength(0);
var values = new double[rowCount];
for (int j = 0; j < rowCount; j++)
{
values[j] = data[j, i];
}
valueList.Add(item, values);
}
return items;
}
public void DrawLines()
{
if (XItems.SelectedItem is null || YItems.SelectedCount == 0) return;
RefreshSeries();
OnPropertyChanged(nameof(SeriesCollection));
OnPropertyChanged(nameof(Labels));
}
public void RefreshSeries()
{
var xParameter = XItems.SelectedItem;
var yParameters = YItems.SelectedItems;
var xFactor = invertXValues ? -1d : 1d;
var yFactor = invertYValues ? -1d : 1d;
var labels = new List<double>();
SeriesCollection = new SeriesCollection();
foreach (var yParameter in yParameters)
{
var localLabels = new List<double>();
var lineSeries = new LineSeries()
{
Configuration = new CartesianMapper<IPoint2D>()
.X(point => point.X)
.Y(point => point.Y),
Title = yParameter.Name,
};
GraphService.SetVisualProps(lineSeries, VisualProps, yParameter.Color);
_ = valueList.TryGetValue(xParameter, out double[] xValues);
_ = valueList.TryGetValue(yParameter, out double[] yValues);
var chartValues = new ChartValues<Point2D>();
for (int i = 0; i < yValues.Count(); i++)
{
double diagramValue = yValues[i] * yFactor;
var x = xValues[i] * xFactor;
var y = yValues[i] * yFactor;
var point = new Point2D() { X = x, Y = y };
chartValues.Add(point);
labels.Add(x);
localLabels.Add(x);
}
lineSeries.Values = chartValues;
//lineSeries.LabelPoint = point => localLabels[(int)point.X].ToString();
SeriesCollection.Add(lineSeries);
}
Labels = labels
.OrderBy(x => x)
.Distinct()
.Select(x => x.ToString())
.ToList();
}
}
}

View File

@@ -26,5 +26,14 @@ namespace StructureHelper.Windows.ViewModels.Errors
new ErrorMessage(vm).ShowDialog();
}
}
public static void ShowMessage(string shortText, string detailText)
{
var vm = new ErrorProcessor()
{
ShortText = shortText,
DetailText = detailText
};
new ErrorMessage(vm).ShowDialog();
}
}
}

View File

@@ -48,7 +48,7 @@ namespace StructureHelperCommon.Models.Calculators
{
if (predicate(end) == false)
{
throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ": pridicate for end value must be true");
throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ": predicate for end value must be true");
}
double precision = Accuracy.IterationAccuracy;

View File

@@ -13,5 +13,6 @@ namespace StructureHelperCommon.Models.Calculators
public double Parameter { get; set; }
public int IterationNumber { get; set; }
public double CurrentAccuracy { get; set; }
public int MaxIterationCount { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelperCommon.Models.Calculators
{
public interface IInputData
{
}
}

View File

@@ -8,6 +8,7 @@ namespace StructureHelperCommon.Models.Calculators
{
public interface IiterationResult
{
int MaxIterationCount { get; set; }
int IterationNumber { get; set; }
}
}

View File

@@ -15,4 +15,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Infrastructures\Predicates\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
{
public class PredicateEntry
{
public string Name { get; set; }
public PredicateTypes PredicateType { get; set; }
}
}

View File

@@ -1,19 +1,21 @@
using LoaderCalculator.Data.Ndms;
using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.NdmCalculations.Cracking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
{
public enum PredicateTypes
{
Strength,
Cracking
}
public class PredicateFactory
{
private ForceTupleCalculator calculator;
private ForceTuple tuple;
private ForceTupleInputData inputData;
@@ -24,7 +26,23 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
inputData = new();
calculator = new() { InputData = inputData };
}
public bool IsSectionFailure(IPoint2D point2D)
public Predicate<IPoint2D> GetPredicate(PredicateTypes predicateType)
{
if (predicateType == PredicateTypes.Strength)
{
return point2D => IsSectionFailure(point2D);
}
else if (predicateType == PredicateTypes.Cracking)
{
return point2D => IsSectionCracked(point2D);
}
else
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(predicateType));
}
}
private bool IsSectionFailure(IPoint2D point2D)
{
var point3D = ConvertLogic.GetPoint3D(point2D);
tuple = new()
@@ -40,7 +58,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
return !result.IsValid;
}
public bool IsSectionCracked(IPoint2D point2D)
private bool IsSectionCracked(IPoint2D point2D)
{
var logic = new HoleSectionCrackedLogic();
var point3D = ConvertLogic.GetPoint3D(point2D);
@@ -48,7 +66,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
{
Nz = point3D.Z,
Mx = point3D.X,
My = point2D.Y
My = point3D.Y
};
logic.Tuple = tuple;
logic.NdmCollection = Ndms;

View File

@@ -0,0 +1,12 @@
using StructureHelperCommon.Models.Calculators;
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
{
public interface ILimitCurveCalculator : ICalculator, IHasActionByResult
{
Action<IResult> ActionToOutputResults { get; set; }
SurroundData SurroundData { get; set; }
int PointCount { get; set; }
ISurroundProc SurroundProcLogic { get; set; }
}
}

View File

@@ -10,6 +10,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
public interface ISurroundProc
{
SurroundData SurroundData { get; set; }
int PointCount { get; set; }
List<IPoint2D> GetPoints();
}
}

View File

@@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
{
public class LimitCurveCalculator : ICalculator, IHasActionByResult
public class LimitCurveCalculator : ILimitCurveCalculator
{
private LimitCurveResult result;
private List<IPoint2D> surroundList;
@@ -19,6 +19,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
public string Name { get; set; }
public SurroundData SurroundData { get; set; }
public int PointCount { get; set; }
public ISurroundProc SurroundProcLogic { get; set; }
public IResult Result => result;
@@ -46,7 +47,9 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
{
result = new LimitCurveResult();
result.IsValid = true;
result.Name = Name;
SurroundProcLogic.SurroundData = SurroundData;
SurroundProcLogic.PointCount = PointCount;
surroundList = SurroundProcLogic.GetPoints();
try
{

View File

@@ -0,0 +1,35 @@
using StructureHelperCommon.Infrastructures.Enums;
using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve
{
public class LimitCurveInputData : IInputData
{
public List<LimitStates> LimitStates { get; }
public List<CalcTerms> CalcTerms { get; }
public List<INdmPrimitive> Primitives { get; set; }
public List<PredicateEntry> PredicateEntries { get; }
public SurroundData SurroundData { get; set; }
public int PointCount { get; set; }
public LimitCurveInputData()
{
LimitStates = new();
CalcTerms = new();
Primitives = new();
PredicateEntries = new();
SurroundData = new();
PointCount = 80;
}
}
}

View File

@@ -33,16 +33,49 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
var range = points.Select(point => new Point2D { X = point.X * 0d, Y = point.Y * 0d }).ToList();
resultList.AddRange(range);
return resultList;
//throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ": predicate for zero value is not valid");
}
//MultyProcessPoints(points);
MonoProcessPoints(points);
return resultList;
}
private void MultyProcessPoints(IEnumerable<IPoint2D> points)
{
Task<IPoint2D>[] tasks = new Task<IPoint2D>[points.Count()];
for (int i = 0; i < points.Count(); i++)
{
var point = points.ToList()[i];
tasks[i] = new Task<IPoint2D>(() => FindResultPoint(point));
tasks[i].Start();
}
Task.WaitAll(tasks);
for (int j = 0; j < points.Count(); j++)
{
var taskResult = tasks[j].Result;
resultList.Add(taskResult);
result.IterationNumber = resultList.Count;
ActionToOutputResults?.Invoke(result);
}
}
private void MonoProcessPoints(IEnumerable<IPoint2D> points)
{
foreach (var point in points)
{
FindParameter(point);
}
return resultList;
}
private void FindParameter(IPoint2D point)
{
IPoint2D resultPoint = FindResultPoint(point);
resultList.Add(resultPoint);
result.IterationNumber = resultList.Count;
ActionToOutputResults?.Invoke(result);
}
private Point2D FindResultPoint(IPoint2D point)
{
double parameter;
currentPoint = point.Clone() as IPoint2D;
@@ -60,9 +93,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
X = currentPoint.X * parameter,
Y = currentPoint.Y * parameter
};
resultList.Add(resultPoint);
result.IterationNumber = resultList.Count;
ActionToOutputResults?.Invoke(result);
return resultPoint;
}
}
}

View File

@@ -6,14 +6,19 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
{
public class LimitCurveResult : IResult, IiterationResult
{
public bool IsValid { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<IPoint2D> Points { get; set; }
public int IterationNumber { get; set; }
public int MaxIterationCount { get; set; }
public LimitCurveResult()
{

View File

@@ -0,0 +1,117 @@
using LoaderCalculator.Data.Ndms;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.Models.Calculations.CalculationsResults;
using StructureHelperLogics.Services.NdmPrimitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve
{
public class LimitCurvesCalculator : ISaveable, ICalculator, IHasActionByResult
{
private LimitCurvesResult result;
private int curvesIterationCount;
public Guid Id { get; }
public string Name { get; set; }
public LimitCurveInputData InputData { get; set; }
public IResult Result => result;
public Action<IResult> ActionToOutputResults { get; set; }
public void Run()
{
GetNewResult();
try
{
var calculators = GetCalulators();
curvesIterationCount = 0;
foreach (var item in calculators)
{
item.Run();
var locResult = item.Result as LimitCurveResult;
result.LimitCurveResults.Add(locResult);
if (locResult.IsValid == false) { result.Description += locResult.Description; }
result.IterationNumber = curvesIterationCount * InputData.PointCount + locResult.IterationNumber;
ActionToOutputResults?.Invoke(result);
curvesIterationCount++;
}
}
catch (Exception ex)
{
result.IsValid = false;
result.Description += ex;
}
}
private void GetNewResult()
{
result = new()
{
IsValid = true
};
}
private List<ILimitCurveCalculator> GetCalulators()
{
List<ILimitCurveCalculator> calculators = new();
foreach (var limitState in InputData.LimitStates)
{
foreach (var calcTerm in InputData.CalcTerms)
{
var ndms = NdmPrimitivesService.GetNdms(InputData.Primitives, limitState, calcTerm);
foreach (var predicateEntry in InputData.PredicateEntries)
{
string calcName = $"{predicateEntry.Name}_{limitState}_{calcTerm}";
LimitCurveCalculator calculator = GetCalculator(ndms, predicateEntry, calcName);
calculators.Add(calculator);
}
}
}
return calculators;
}
private LimitCurveCalculator GetCalculator(List<INdm> ndms, PredicateEntry predicateEntry, string calcName)
{
var factory = new PredicateFactory()
{
Ndms = ndms,
ConvertLogic = InputData.SurroundData.ConvertLogicEntity.ConvertLogic
};
var predicateType = predicateEntry.PredicateType;
var predicate = factory.GetPredicate(predicateType);
//Predicate<IPoint2D> predicate = factory.IsSectionCracked;
var logic = new LimitCurveLogic(predicate);
//var logic = new StabLimitCurveLogic();
var calculator = new LimitCurveCalculator(logic)
{
Name = calcName,
SurroundData = InputData.SurroundData,
PointCount = InputData.PointCount,
ActionToOutputResults = SetCurveCount
};
return calculator;
}
public object Clone()
{
throw new NotImplementedException();
}
private void SetCurveCount(IResult locResult)
{
var curveResult = locResult as IiterationResult;;
result.IterationNumber = curvesIterationCount * InputData.PointCount + curveResult.IterationNumber;
ActionToOutputResults?.Invoke(result);
}
}
}

View File

@@ -0,0 +1,23 @@
using StructureHelperCommon.Models.Calculators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve
{
public class LimitCurvesResult : IResult, IiterationResult
{
public bool IsValid { get; set; }
public string? Description { get; set; }
public List<LimitCurveResult> LimitCurveResults {get;set;}
public int MaxIterationCount { get; set; }
public int IterationNumber { get; set; }
public LimitCurvesResult()
{
LimitCurveResults = new();
}
}
}

View File

@@ -1,4 +1,5 @@
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models.Shapes;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -12,13 +13,20 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
private List<IPoint2D> surroundList;
public SurroundData SurroundData { get; set; }
public int PointCount { get; set; }
public RectSurroundProc()
{
}
public List<IPoint2D> GetPoints()
{
CheckParameters();
var xRadius = (SurroundData.XMax - SurroundData.XMin) / 2;
var yRadius = (SurroundData.YMax - SurroundData.YMin) / 2;
surroundList = new();
var pointCount = Convert.ToInt32(Math.Ceiling(SurroundData.PointCount / 8d));
var pointCount = Convert.ToInt32(Math.Ceiling(PointCount / 8d));
double xStep = xRadius / pointCount;
double yStep = yRadius / pointCount;
double x, y;
@@ -49,5 +57,17 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
surroundList.Add(surroundList[0].Clone() as IPoint2D);
return surroundList;
}
private void CheckParameters()
{
//if (surroundList is null || surroundList.Count == 0)
//{
// throw new StructureHelperException(ErrorStrings.ParameterIsNull);
//}
if (PointCount < 12)
{
throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": Point count must be grater than 12, but was {PointCount}");
}
}
}
}

View File

@@ -12,6 +12,8 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
private List<IPoint2D> surroundList;
public SurroundData SurroundData { get; set; }
public int PointCount { get; set; }
public RoundSurroundProc()
{
SurroundData = new();
@@ -23,7 +25,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
var xCenter = (SurroundData.XMax + SurroundData.XMin) / 2;
var yCenter = (SurroundData.YMax + SurroundData.YMin) / 2;
surroundList = new();
var pointCount = Convert.ToInt32(Math.Ceiling(SurroundData.PointCount / 4d) * 4d);
var pointCount = Convert.ToInt32(Math.Ceiling(PointCount / 4d) * 4d);
double angleStep = 2d * Math.PI / pointCount;
double angle;
for (int i = 0; i < pointCount; i++)

View File

@@ -18,6 +18,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
foreach (var item in points)
{
result.Add(new Point2D() { X = item.X * 0.5d, Y = item.Y * 0.5d });
Thread.Sleep(10);
}
return result;
}

View File

@@ -6,24 +6,37 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
{
/// <summary>
/// Limits of coordinates for workplane
/// </summary>
public class SurroundData
{
public double XMax { get; set; }
public double XMin { get; set; }
public double YMax { get; set; }
public double YMin { get; set; }
/// <summary>
/// Constant value of coordinate in direction, which is normal to specific workplane
/// </summary>
public double ConstZ { get; set; }
/// <summary>
/// Logic for transformation of 2D worplane to 3D space
/// </summary>
public ConstOneDirectionConverter ConvertLogicEntity { get; set; }
public int PointCount { get; set; }
/// <summary>
/// Returns new instance of class
/// </summary>
public SurroundData()
{
XMax = 1e7d;
XMin = -1e7d;
YMax = 1e7d;
YMin = -1e7d;
PointCount = 80;
ConvertLogicEntity = ConvertLogics.ConverterLogics[0];
}
}