// Copyright (C) Stichting Deltares 2017. All rights reserved.
//
// This file is part of Ringtoets.
//
// Ringtoets is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Core.Components.Stack.Data;
using Ringtoets.Common.Data.Hydraulics.IllustrationPoints;
using Ringtoets.Common.Forms.Properties;
namespace Ringtoets.Common.Forms.Factories
{
///
/// Factory for creating based on information used as input.
///
public static class RingtoetsStackChartDataFactory
{
private const double minAlphaSquared = 0.01;
///
/// Creates a new .
///
/// The created .
public static StackChartData Create()
{
return new StackChartData();
}
///
/// Creates the columns for the given .
///
/// The data to create the columns from.
/// The stack chart data to create the columns for.
/// Thrown when any parameter is null.
public static void CreateColumns(GeneralResult generalResult, StackChartData stackChartData)
{
if (generalResult == null)
{
throw new ArgumentNullException(nameof(generalResult));
}
if (stackChartData == null)
{
throw new ArgumentNullException(nameof(stackChartData));
}
Tuple[] labels = generalResult.WindDirectionClosingSituationIllustrationPoints
.Select(illustrationPoint =>
new Tuple(illustrationPoint.WindDirection.Name,
illustrationPoint.ClosingSituation))
.ToArray();
bool showClosingSituation = labels.Any(l => l.Item2 != labels[0].Item2);
foreach (Tuple label in labels)
{
string columnName = label.Item1;
if (showClosingSituation)
{
columnName = $"{columnName} ({label.Item2})";
}
stackChartData.AddColumn(columnName);
}
}
///
/// Creates the rows for the given .
///
/// The data to create the rows from.
/// The stack chart data to create the rows for.
/// Thrown when any parameter is null.
public static void CreateRows(GeneralResult generalResult, StackChartData stackChartData)
{
if (generalResult == null)
{
throw new ArgumentNullException(nameof(generalResult));
}
if (stackChartData == null)
{
throw new ArgumentNullException(nameof(stackChartData));
}
var stochastValues = new List>();
foreach (WindDirectionClosingSituationIllustrationPoint illustrationPoint in generalResult.WindDirectionClosingSituationIllustrationPoints)
{
stochastValues.AddRange(illustrationPoint.IllustrationPoint.Stochasts
.Select(illustrationPointStochast =>
new Tuple(illustrationPointStochast.Name,
Math.Pow(illustrationPointStochast.Alpha, 2))));
}
IDictionary> stochasts = CreateStochastsLookup(stochastValues);
CreateRowsForStochasts(stackChartData, stochasts);
}
private static IDictionary> CreateStochastsLookup(List> stochastValues)
{
IDictionary> lookup = new Dictionary>();
foreach (Tuple stochastValue in stochastValues)
{
if (!lookup.ContainsKey(stochastValue.Item1))
{
lookup.Add(stochastValue.Item1, new List());
}
lookup[stochastValue.Item1].Add(stochastValue.Item2);
}
return lookup;
}
private static void CreateRowsForStochasts(StackChartData stackChartData, IDictionary> stochasts)
{
IDictionary> significantStochasts = new Dictionary>();
IDictionary> remainingStochasts = new Dictionary>();
foreach (KeyValuePair> stochast in stochasts)
{
if (!StochastIsSignificant(stochast))
{
significantStochasts.Add(stochast);
}
else
{
remainingStochasts.Add(stochast);
}
}
foreach (KeyValuePair> significantStochast in significantStochasts)
{
stackChartData.AddRow(significantStochast.Key, significantStochast.Value.ToArray());
}
if (remainingStochasts.Any())
{
stackChartData.AddRow(Resources.RingtoetsStackChartDataFactory_RemainingRow_DisplayName,
GetValuesForRemainingRow(remainingStochasts),
Color.Gray);
}
}
private static bool StochastIsSignificant(KeyValuePair> stochast)
{
return stochast.Value.Any(v => v < minAlphaSquared);
}
private static double[] GetValuesForRemainingRow(IDictionary> stochasts)
{
var values = new double[stochasts.First().Value.Count];
var index = 0;
foreach (KeyValuePair> stochast in stochasts)
{
foreach (double value in stochast.Value)
{
values[index] += value;
index++;
}
index = 0;
}
return values;
}
}
}