// 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.Common.Base.Data;
using Core.Common.Util.Extensions;
using Core.Components.Stack.Data;
using Ringtoets.Common.Forms.Properties;
using Ringtoets.Common.Forms.Views;
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(IEnumerable illustrationPointControlItems,
StackChartData stackChartData)
{
if (illustrationPointControlItems == null)
{
throw new ArgumentNullException(nameof(illustrationPointControlItems));
}
if (stackChartData == null)
{
throw new ArgumentNullException(nameof(stackChartData));
}
IEnumerable> labels =
illustrationPointControlItems.Select(controlItem => Tuple.Create(controlItem.WindDirectionName,
controlItem.ClosingSituation)).ToArray();
bool showClosingSituation = illustrationPointControlItems.HasMultipleUniqueValues(item => item.ClosingSituation);
foreach (Tuple label in labels)
{
string columnName = label.Item1;
if (showClosingSituation)
{
columnName = string.Format(Resources.RingtoetsStackChartDataFactory_CreateColumns_WindDirection_0_ClosingSituation_1,
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(IEnumerable illustrationPointControlItems, StackChartData stackChartData)
{
if (illustrationPointControlItems == null)
{
throw new ArgumentNullException(nameof(illustrationPointControlItems));
}
if (stackChartData == null)
{
throw new ArgumentNullException(nameof(stackChartData));
}
var stochastValues = new List>();
foreach (IllustrationPointControlItem illustrationPointControlItem in illustrationPointControlItems)
{
stochastValues.AddRange(GetStochastValues(illustrationPointControlItem));
}
IDictionary> stochasts = CreateStochastsLookup(stochastValues);
CreateRowsForStochasts(stackChartData, stochasts);
}
private static IEnumerable> GetStochastValues(IllustrationPointControlItem illustrationPointControlItem)
{
return illustrationPointControlItem.Stochasts
.Select(stochast => Tuple.Create(stochast.Name,
new RoundedDouble(5, Math.Pow(stochast.Alpha, 2))))
.ToArray();
}
private static IDictionary> CreateStochastsLookup(IEnumerable> stochastValues)
{
var 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.Select(v => v.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;
}
}
}