/// <summary> /// Ensures statistics data for specific AB variant. /// </summary> /// <param name="variantName">Variant name</param> private void EnsureVariantStatisticsData(string variantName) { if (!VariantsStatisticsData.ContainsKey(variantName)) { // Select both abvisitfirst and abvisitreturn by default string visitType = "abvisit%"; // If counting methodology is set to visitor conversion, select abvisitfirst only string countingMethodology = drpCountingMethodology.Items[mDrpCountingMethodologyIndex].Value; if (countingMethodology == "absessionconversionfirst") { visitType = "abvisitfirst"; } string conversionsCodename = countingMethodology + ";" + ABTest.ABTestName + ";" + variantName; string visitsCodename = visitType + ";" + ABTest.ABTestName + ";" + variantName; // Get conversions count and value DataRow conversions = GetHits(conversionsCodename, "Sum(HitsCount), Sum(HitsValue)", mDrpCultureValue, GetConversionCondition()); int conversionsCount = ValidationHelper.GetInteger(conversions[0], 0); double conversionsValue = ValidationHelper.GetDouble(conversions[1], 0); // Get visits count int visits = ValidationHelper.GetInteger(GetHits(visitsCodename, "Sum(HitsCount)", mDrpCultureValue)[0], 0); // Add statistics data VariantsStatisticsData.Add(variantName, new ABVariantStatisticsData(conversionsCount, conversionsValue, visits)); // Add conversion rate intervals if ((VariantPerformanceCalculator != null) && (visits > 0) && (conversionsCount <= visits)) { ABConversionRateIntervals.Add(variantName, VariantPerformanceCalculator.GetConversionRateInterval(conversionsCount, visits)); } } }
protected object gridElem_OnExternalDataBound(object sender, string sourceName, object parameter) { if (!RequestHelper.IsPostBack()) { return(string.Empty); } // Handle the grid action first because it doesn't require access to VariantsStatisticsData if (sourceName == "selectwinner") { var gridViewRow = parameter as GridViewRow; if (gridViewRow != null) { var dataRowView = gridViewRow.DataItem as DataRowView; if (dataRowView != null) { var img = sender as CMSGridActionButton; if (img != null) { // Check permissions to select winner if (!IsUserAuthorizedToManageTest) { img.Enabled = false; img.ToolTip = GetString("abtesting.selectwinner.permission.tooltip"); } else { var winner = GetTestWinner(); if (winner != null) { string variantName = (ValidationHelper.GetString(dataRowView["ABVariantName"], "")); if (variantName == winner.ABVariantName) { // Disable action image for the winning variant img.Enabled = false; } else { // Hide action image for other variants img.Visible = false; } } } } } } return(string.Empty); } string currentVariantName = parameter.ToString(); if (String.IsNullOrEmpty(currentVariantName) || (OriginalVariant == null) || !VariantsStatisticsData.ContainsKey(currentVariantName)) { return(string.Empty); } var variantData = VariantsStatisticsData[currentVariantName]; switch (sourceName) { case "name": var variant = ABVariants.FirstOrDefault(v => v.ABVariantName == currentVariantName); if (variant != null) { var link = new HtmlAnchor(); link.InnerText = ResHelper.LocalizeString(variant.ABVariantDisplayName); link.HRef = DocumentURLProvider.GetUrl(variant.ABVariantPath); link.Target = "_blank"; return(link); } break; case "conversionsovervisits": return(variantData.ConversionsCount + " / " + variantData.Visits); case "chancetobeatoriginal": if ((currentVariantName != OriginalVariant.ABVariantName) && (VariantPerformanceCalculator != null) && (variantData.Visits > 0)) { double chanceToBeatOriginal = VariantPerformanceCalculator.GetChanceToBeatOriginal(variantData.ConversionsCount, variantData.Visits); // Check whether the variant is most probably winning already and mark the row green if ((chanceToBeatOriginal >= WINNING_VARIANT_MIN_CHANCETOBEAT) && (variantData.ConversionsCount >= WINNING_VARIANT_MIN_CONVERSIONS)) { AddCSSToParentControl(sender as WebControl, "winning-variant-row"); } return(String.Format("{0:P2}", chanceToBeatOriginal)); } break; case "conversionrate": if ((VariantPerformanceCalculator != null) && (variantData.Visits > 0) && ABConversionRateIntervals.ContainsKey(currentVariantName) && ABConversionRateIntervals.ContainsKey(OriginalVariant.ABVariantName)) { // Render the picture representing how the challenger variant is performing against the original variant return(new ABConversionRateIntervalVisualizer( mMinConversionRateLowerBound, mConversionRateRange, ABConversionRateIntervals[currentVariantName], ABConversionRateIntervals[OriginalVariant.ABVariantName])); } break; case "conversionvalue": return(variantData.ConversionsValue); case "averageconversionvalue": return(String.Format("{0:#.##}", variantData.AverageConversionValue)); case "improvement": if ((currentVariantName != OriginalVariant.ABVariantName) && VariantsStatisticsData.ContainsKey(OriginalVariant.ABVariantName)) { var originalData = VariantsStatisticsData[OriginalVariant.ABVariantName]; switch (drpSuccessMetric.SelectedValue) { case "conversioncount": if (!originalData.ConversionsCount.Equals(0)) { return(GetPercentageImprovementPanel((variantData.ConversionsCount / (double)originalData.ConversionsCount) - 1)); } break; case "conversionvalue": if (!originalData.ConversionsValue.Equals(0)) { return(GetPercentageImprovementPanel((variantData.ConversionsValue / originalData.ConversionsValue) - 1)); } break; case "conversionrate": if (!originalData.ConversionRate.Equals(0)) { return(GetPercentageImprovementPanel((variantData.ConversionRate / originalData.ConversionRate) - 1)); } break; case "averageconversionvalue": if (!originalData.AverageConversionValue.Equals(0)) { return(GetPercentageImprovementPanel((variantData.AverageConversionValue / originalData.AverageConversionValue) - 1)); } break; } } break; } return(string.Empty); }