fix: logic errors in view models

This commit is contained in:
2026-08-10 08:59:17 +03:00
parent 5b6abc045b
commit 089df7d524
4 changed files with 121 additions and 133 deletions
@@ -89,7 +89,7 @@ public partial class AnalysisViewModel : ViewModelBase
public const double UNPROCESSED_THRESHOLD = 0.6;
public const double HOTSPOT_THRESHOLD = 1.1;
public const double EPSILON = 1e-10;
public const double UNPROCESSED_FRACTION_THRESHOLD = 10;
public const double UNPROCESSED_FRACTION_THRESHOLD = 50;
/// <summary>
/// Модель гистограммы
@@ -508,14 +508,14 @@ public partial class AnalysisViewModel : ViewModelBase
MeanInnerStdDev = -1;
MeanHotspotArea = -1;
MeanOpticalIntegral = -1;
ProcessedAreasHistogram.Clear();
UnprocessedAreasHistogram.Clear();
HotspotAreasHistogram.Clear();
OpticalIntegralsHistogram.Clear();
InnerStdDevsHistogram.Clear();
InnerHeterogeneitiesHistogram.Clear();
ParticleIndex = 0;
return;
@@ -660,7 +660,7 @@ public partial class AnalysisViewModel : ViewModelBase
// Обновляем гистограмму
ParticleValuesHistogram.Set(NormalizedValues[value], 0, 3, "Количество, шт", "Значение");
// Обновляем изображение
ZoomPanOnParticle();
}
@@ -668,10 +668,10 @@ public partial class AnalysisViewModel : ViewModelBase
{
ZoomPanOnParticle();
}
private void ZoomPanOnParticle()
{
if (ParticleIndex < 0 ||
if (ParticleIndex < 0 ||
ParticleIndex >= Xs.Count() ||
ParticleIndex >= Ys.Count())
return;
@@ -683,10 +683,10 @@ public partial class AnalysisViewModel : ViewModelBase
var maxX = Xs[ParticleIndex].Max();
var minY = Ys[ParticleIndex].Min();
var maxY = Ys[ParticleIndex].Max();
ParticleImagesZoom = MathF.Max((float)ParticleImagesBounds.Width, (float)ParticleImagesBounds.Height) * MathF.Max(maxX - minX, maxY - minY) / AnalyzerService.ANALYSIS_IMAGE_SIZE;
ParticleImagesPanX = -((maxX + minX) / 2 / AnalyzerService.ANALYSIS_IMAGE_SIZE - 0.5f) * (float)ParticleImagesBounds.Width * ParticleImagesZoom;
ParticleImagesPanY = -((maxY + minY) / 2 / AnalyzerService.ANALYSIS_IMAGE_SIZE - 0.5f) * (float)ParticleImagesBounds.Height * ParticleImagesZoom;
ParticleImagesPanX = -((maxX + minX) / 2 / AnalyzerService.ANALYSIS_IMAGE_SIZE - 0.5f) * (float)ParticleImagesBounds.Width * ParticleImagesZoom;
ParticleImagesPanY = -((maxY + minY) / 2 / AnalyzerService.ANALYSIS_IMAGE_SIZE - 0.5f) * (float)ParticleImagesBounds.Height * ParticleImagesZoom;
}
}
@@ -995,8 +995,8 @@ public partial class AnalysisViewModel : ViewModelBase
ea.PropertyName == nameof(MainSectionIsScrolling) ||
ea.PropertyName == nameof(InfoSectionIsScrolling))
UpdateCanInteract();
if (ea.PropertyName == nameof(MenuSelectedIndex) ||
ea.PropertyName == nameof(InfoSectionCurrentIndex) )
if (ea.PropertyName == nameof(MenuSelectedIndex) ||
ea.PropertyName == nameof(InfoSectionCurrentIndex))
UpdateCharts?.Invoke(this, EventArgs.Empty);
};
@@ -1012,25 +1012,24 @@ public partial class AnalysisViewModel : ViewModelBase
if (value >= MenuItems.Count())
_logger.LogError("Значение {}({}) больше количества элементов {}({})", nameof(MenuSelectedIndex), MenuSelectedIndex, nameof(MenuItems), MenuItems.Count());
// Если значение меньше 0, то значит элемент меню не выбран
if (value < 0 || value > MenuItems.Count())
{
// Логгируем как ошибку
_logger.LogError("Не удалось найти элемент с Id({}) в таблице {}", MenuItems[value].Id, nameof(_context.BrandRecords));
// Сохраняем несуществующий индекс
var nonExistingIndex = MenuSelectedIndex;
// Устанавливаем, что запись не выбрана, этот метод вызовется повторно и заполнит поля пустыми значениями
MenuSelectedIndex = -1;
// Удаляем несуществующий элемент из списка
MenuItems.RemoveAt(nonExistingIndex);
return;
}
_logger.LogTrace("Выбран элемент из списка: {}", value);
// Находим запись в базе данных
var selectedRecord = _context.ResultRecords.Find(MenuItems[value].Id);
// Если запись найдена, то заполняем поля из базы данных
if (selectedRecord is not null)
if (value >= 0 && value < MenuItems.Count())
{
_logger.LogTrace("Выбран элемент из списка: {}", value);
// Находим запись в базе данных
var selectedRecord = _context.ResultRecords.Find(MenuItems[value].Id);
// Если запись не найдена
if (selectedRecord is null)
{
// Логгируем как ошибку
_logger.LogError("Не удалось найти элемент с Id({}) в таблице {}", MenuItems[value].Id, nameof(_context.ResultRecords));
var nonExistingIndex = MenuSelectedIndex; // Сохраняем несуществующий индекс
// Устанавливаем, что запись не выбрана, этот метод вызовется повторно и заполнит поля пустыми значениями
MenuSelectedIndex = -1;
// Удаляем несуществующий элемент из списка
MenuItems.RemoveAt(nonExistingIndex);
return;
}
// Если запись найдена, то заполняем поля из базы данных
// Заполняем простые поля
Record.Id = selectedRecord.Id;
Record.Uuid = selectedRecord.Uuid;
@@ -1781,7 +1780,7 @@ public partial class AnalysisViewModel : ViewModelBase
_logger.LogError("Не удалось найти элемент с Id({}) в таблице {}", BrandComboBoxItems[BrandComboBoxSelectedIndex].Id, nameof(_context.BrandRecords));
return;
}
if (brand.MixtureNormalRate <= 0)
if (brand.MixtureNormalRate <= 0)
{
_logger.LogError("Норма расхода выбранной марки меньше или равена 0");
return;
@@ -1878,13 +1877,13 @@ public partial class AnalysisViewModel : ViewModelBase
// Вычисляем пороговые значения
var unprocessedThreshold = RecordViewModel.UNPROCESSED_THRESHOLD * brand.MixtureNormalRate;
var hotspotsThreshold = RecordViewModel.HOTSPOT_THRESHOLD * brand.MixtureNormalRate;
// Выичсляем максимальное значение
OpenCvSharp.Cv2.MinMaxLoc(resultImage, out _, out double max);
// Если иаксмиальное значниеz слишком мало, то устанавливаем его чуть больше hotspotsThreshold, чтобы не возникло деления на ноль и отридцательных значений
if (max <= hotspotsThreshold)
if (max <= hotspotsThreshold)
max = hotspotsThreshold + 0.001;
// Создаём цветное изображение результата
var coloredResultImage = new OpenCvSharp.Mat(resultImage.Size(), OpenCvSharp.MatType.CV_8UC3, OpenCvSharp.Scalar.All(0));
// Расшрашиваем диапазон 0...unprocessedThreshold -> чёрный...белый
@@ -1898,7 +1897,7 @@ public partial class AnalysisViewModel : ViewModelBase
var invMask = new OpenCvSharp.Mat(mask.Size(), mask.Type(), OpenCvSharp.Scalar.All(0));
OpenCvSharp.Cv2.BitwiseNot(mask, invMask);
coloredResultImage.SetTo(OpenCvSharp.Scalar.All(0), invMask);
// Освобождаем память, оригинальное изображение результата можно удалить
invMask.Dispose();
resultImage.Dispose();