GeneralFormulas.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. //
  5. // Purpose: This class calculates Running total and average.
  6. // Could be used for Pareto chart.
  7. //
  8. using System;
  9. namespace FastReport.DataVisualization.Charting.Formulas
  10. {
  11. /// <summary>
  12. /// This class calculates Running total and average.
  13. /// Could be used for Pareto chart
  14. /// </summary>
  15. internal class GeneralFormulas : PriceIndicators
  16. {
  17. #region Properties
  18. /// <summary>
  19. /// Formula Module name
  20. /// </summary>
  21. override public string Name { get { return SR.FormulaNameGeneralFormulas; } }
  22. #endregion
  23. #region Formulas
  24. /// <summary>
  25. /// Formula which calculates cumulative total.
  26. /// ---------------------------------------------------------
  27. /// Input:
  28. /// - Y values.
  29. /// Output:
  30. /// - Running Total.
  31. /// </summary>
  32. /// <param name="inputValues">Arrays of doubles: 1. row - X values, 2. row - Y values</param>
  33. /// <param name="outputValues">Arrays of doubles: 1. row - X values, 2. row - Moving average</param>
  34. private void RuningTotal(double [][] inputValues, out double [][] outputValues)
  35. {
  36. // There is not enough series
  37. if( inputValues.Length != 2 )
  38. {
  39. throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray);
  40. }
  41. // Different number of x and y values
  42. CheckNumOfValues( inputValues, 1 );
  43. outputValues = new double [2][];
  44. outputValues[0] = new double [inputValues[0].Length];
  45. outputValues[1] = new double [inputValues[1].Length];
  46. // Cumulative total
  47. for( int index = 0; index < inputValues[0].Length; index++ )
  48. {
  49. outputValues[0][index] = inputValues[0][index];
  50. if( index > 0 )
  51. {
  52. outputValues[1][index] = inputValues[1][index] + outputValues[1][index-1];
  53. }
  54. else
  55. {
  56. outputValues[1][index] = inputValues[1][index];
  57. }
  58. }
  59. }
  60. /// <summary>
  61. /// Running Average Formula
  62. /// ---------------------------------------------------------
  63. /// Input:
  64. /// - Y values.
  65. /// Output:
  66. /// - Running Average.
  67. /// </summary>
  68. /// <param name="inputValues">Arrays of doubles: 1. row - X values, 2. row - Y values</param>
  69. /// <param name="outputValues">Arrays of doubles: 1. row - X values, 2. row - Moving average</param>
  70. private void RunningAverage(double [][] inputValues, out double [][] outputValues)
  71. {
  72. // There is no enough series
  73. if( inputValues.Length != 2 )
  74. throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray);
  75. // Different number of x and y values
  76. CheckNumOfValues( inputValues, 1 );
  77. outputValues = new double [2][];
  78. outputValues[0] = new double [inputValues[0].Length];
  79. outputValues[1] = new double [inputValues[1].Length];
  80. // Total
  81. double total = 0;
  82. for( int index = 0; index < inputValues[0].Length; index++ )
  83. {
  84. total += inputValues[1][index];
  85. }
  86. // Runing Average
  87. for( int index = 0; index < inputValues[0].Length; index++ )
  88. {
  89. outputValues[0][index] = inputValues[0][index];
  90. if( index > 0 )
  91. outputValues[1][index] = inputValues[1][index] / total * 100 + outputValues[1][index-1];
  92. else
  93. outputValues[1][index] = inputValues[1][index] / total * 100;
  94. }
  95. }
  96. #endregion
  97. #region Methods
  98. /// <summary>
  99. /// Default constructor.
  100. /// </summary>
  101. public GeneralFormulas()
  102. {
  103. }
  104. /// <summary>
  105. /// The first method in the module, which converts a formula
  106. /// name to the corresponding private method.
  107. /// </summary>
  108. /// <param name="formulaName">String which represent a formula name.</param>
  109. /// <param name="inputValues">Arrays of doubles - Input values.</param>
  110. /// <param name="outputValues">Arrays of doubles - Output values.</param>
  111. /// <param name="parameterList">Array of strings - Formula parameters.</param>
  112. /// <param name="extraParameterList">Array of strings - Extra Formula parameters from DataManipulator object.</param>
  113. /// <param name="outLabels">Array of strings - Used for Labels. Description for output results.</param>
  114. override public void Formula( string formulaName, double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList, out string [][] outLabels )
  115. {
  116. string name;
  117. outputValues = null;
  118. // Not used for these formulas.
  119. outLabels = null;
  120. name = formulaName.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
  121. try
  122. {
  123. switch( name )
  124. {
  125. case "RUNINGTOTAL":
  126. RuningTotal( inputValues, out outputValues );
  127. break;
  128. case "RUNINGAVERAGE":
  129. RunningAverage( inputValues, out outputValues );
  130. break;
  131. default:
  132. outputValues = null;
  133. break;
  134. }
  135. }
  136. catch( IndexOutOfRangeException )
  137. {
  138. throw new InvalidOperationException( SR.ExceptionFormulaInvalidPeriod(name) );
  139. }
  140. catch( OverflowException )
  141. {
  142. throw new InvalidOperationException( SR.ExceptionFormulaNotEnoughDataPoints(name) );
  143. }
  144. }
  145. #endregion
  146. }
  147. }