Ejemplo n.º 1
0
    /// <summary>
    /// Loads summary box in the right upper corner.
    /// </summary>
    private void LoadSummaryBox()
    {
        lnkTest.HRef      = DocumentURLProvider.GetUrl(ABTest.ABTestOriginalPage);
        lnkTest.InnerText = ShortenUrl(ABTest.ABTestOriginalPage, MAX_LINK_LENGTH);
        lnkTest.Target    = "_blank";

        // If Visitors conversion methodology selected, use "Visitors" instead of "Visits"
        if (drpCountingMethodology.SelectedValue == "absessionconversionfirst")
        {
            lblVisits.ResourceString = "abtesting.overview.summary.visitors";
        }

        lblStatus.Text = ABTestStatusEvaluator.GetFormattedStatus(TestStatus).ToString();
        int visits      = VariantsStatisticsData.Sum(d => d.Value.Visits);
        int conversions = VariantsStatisticsData.Sum(d => d.Value.ConversionsCount);

        lblTotalVisitors.Text    = String.Format("{0:N0}", visits);
        lblTotalConversions.Text = String.Format("{0:N0}", conversions);

        if (TestStatus == ABTestStatusEnum.Finished)
        {
            txtDuration.ResourceString = "abtesting.daysrun";
        }

        DateTime start  = ABTest.ABTestOpenFrom;
        DateTime finish = GetFinishDateOrToday();

        lblDuration.Text = (finish - start).Days.ToString();
    }
Ejemplo n.º 2
0
    /// <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));
            }
        }
    }
    /// <summary>
    /// Loads summary box in the right upper corner.
    /// </summary>
    private void LoadSummaryBox()
    {
        var selectionParameters = new NodeSelectionParameters
        {
            AliasPath                 = ABTest.ABTestOriginalPage,
            CultureCode               = ABTest.ABTestCulture,
            SiteName                  = SiteContext.CurrentSiteName,
            SelectOnlyPublished       = true,
            CombineWithDefaultCulture = false
        };

        var node            = new TreeProvider().SelectSingleNode(selectionParameters);
        var shortUrl        = ShortenUrl(ABTest.ABTestOriginalPage);
        var encodedShortUrl = HTMLHelper.HTMLEncode(shortUrl);

        if (node == null)
        {
            lblTest.Text    = encodedShortUrl;
            lblTest.Visible = true;
        }
        else
        {
            lnkTest.HRef      = DocumentURLProvider.GetAbsoluteLiveSiteURL(node);
            lnkTest.InnerText = encodedShortUrl;
            lnkTest.Target    = "_blank";
            lnkTest.Visible   = true;
        }

        // If Visitors conversion methodology selected, use "Visitors" instead of "Visits"
        if (drpCountingMethodology.SelectedValue == ABTestConstants.ABSESSIONCONVERSION_FIRST)
        {
            lblVisits.ResourceString = "abtesting.overview.summary.visitors";
        }

        lblStatus.Text = ABTestStatusEvaluator.GetFormattedStatus(TestStatus).ToString();
        int visits      = VariantsStatisticsData.Sum(d => d.Value.Visits);
        int conversions = VariantsStatisticsData.Sum(d => d.Value.ConversionsCount);

        lblTotalVisitors.Text    = String.Format("{0:N0}", visits);
        lblTotalConversions.Text = String.Format("{0:N0}", conversions);

        if (TestStatus == ABTestStatusEnum.Finished)
        {
            txtDuration.ResourceString = "abtesting.daysrun";
        }

        DateTime start  = ABTest.ABTestOpenFrom;
        DateTime finish = GetFinishDate();

        lblDuration.Text = (finish - start).Days.ToString();
    }
    /// <summary>
    /// Ensures statistics data for specific AB variant.
    /// </summary>
    /// <param name="variantGuid">Variant GUID</param>
    private void EnsureVariantStatisticsData(Guid variantGuid)
    {
        if (!VariantsStatisticsData.ContainsKey(variantGuid))
        {
            // 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[drpCountingMethodologyIndex].Value;
            if (countingMethodology == ABTestConstants.ABSESSIONCONVERSION_FIRST)
            {
                visitType = "abvisitfirst";
            }

            string conversionsCodename = countingMethodology + ";" + ABTest.ABTestName + ";" + variantGuid;
            string visitsCodename      = visitType + ";" + ABTest.ABTestName + ";" + variantGuid;
            string conversion          = ValidationHelper.GetString(drpConversions.SelectedValue, string.Empty);
            var    testConversions     = ABTest.ABTestConversionConfiguration.ABTestConversions.Select(c => c.ConversionName);

            // Get conversions count and value
            DataRow conversions      = GetHits(conversionsCodename, "Sum(HitsCount), Sum(HitsValue)", null, GetConversionCondition(conversion, testConversions));
            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)", null)[0], 0);

            // Add statistics data
            VariantsStatisticsData.Add(variantGuid, new ABVariantStatisticsData(conversionsCount, conversionsValue, visits));

            // Add conversion rate intervals
            if ((VariantPerformanceCalculator != null) && (visits > 0) && (conversionsCount <= visits))
            {
                ABConversionRateIntervals.Add(variantGuid, VariantPerformanceCalculator.GetConversionRateInterval(conversionsCount, visits));
            }
        }
    }
Ejemplo n.º 5
0
    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);
    }
    protected object gridElem_OnExternalDataBound(object sender, string sourceName, object parameter)
    {
        // Handle the grid action first because it doesn't require access to VariantsStatisticsData
        if (sourceName == "selectwinner")
        {
            if (parameter is GridViewRow gridViewRow && gridViewRow.DataItem is DataRowView dataRowView)
            {
                var action      = sender as CMSAccessibleButtonBase;
                var variantGuid = ValidationHelper.GetGuid(dataRowView["ABVariantGUID"], Guid.Empty);

                InitializeGridAction(action, variantGuid);
            }

            return(string.Empty);
        }

        var currentVariantGuid = ValidationHelper.GetGuid(parameter, Guid.Empty);

        if (currentVariantGuid == Guid.Empty || (OriginalVariant == null) || !VariantsStatisticsData.ContainsKey(currentVariantGuid))
        {
            return(string.Empty);
        }

        var variantData = VariantsStatisticsData[currentVariantGuid];

        switch (sourceName)
        {
        case "name":
            var variant = ABVariants.FirstOrDefault(v => v.ABVariantGUID == currentVariantGuid);
            if (variant != null)
            {
                return(HTMLHelper.HTMLEncode(ResHelper.LocalizeString(variant.ABVariantDisplayName)));
            }
            break;

        case METRIC_CONVERSIONS_OVER_VISITS:
            return(variantData.ConversionsCount + " / " + variantData.Visits);

        case METRIC_CHANCE_TO_BEAT_ORIGINAL:
            if ((currentVariantGuid != OriginalVariant.ABVariantGUID) && (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 METRIC_CONVERSION_RATE:
            if ((VariantPerformanceCalculator != null) && (variantData.Visits > 0) &&
                ABConversionRateIntervals.ContainsKey(currentVariantGuid) && ABConversionRateIntervals.ContainsKey(OriginalVariant.ABVariantGUID))
            {
                // Render the picture representing how the challenger variant is performing against the original variant
                return(new ABConversionRateIntervalVisualizer(
                           mMinConversionRateLowerBound, mConversionRateRange, ABConversionRateIntervals[currentVariantGuid], ABConversionRateIntervals[OriginalVariant.ABVariantGUID]));
            }
            break;

        case METRIC_CONVERSION_VALUE:
            return(variantData.ConversionsValue);

        case METRIC_AVG_CONVERSION_VALUE:
            return(String.Format("{0:#.##}", variantData.AverageConversionValue));

        case "improvement":
            if ((currentVariantGuid != OriginalVariant.ABVariantGUID) && VariantsStatisticsData.ContainsKey(OriginalVariant.ABVariantGUID))
            {
                var originalData = VariantsStatisticsData[OriginalVariant.ABVariantGUID];
                switch (drpSuccessMetric.SelectedValue)
                {
                case METRIC_CONVERSION_COUNT:
                    if (!originalData.ConversionsCount.Equals(0))
                    {
                        return(GetPercentageImprovementPanel((variantData.ConversionsCount / (double)originalData.ConversionsCount) - 1));
                    }
                    break;

                case METRIC_CONVERSION_VALUE:
                    if (!originalData.ConversionsValue.Equals(0))
                    {
                        return(GetPercentageImprovementPanel((variantData.ConversionsValue / originalData.ConversionsValue) - 1));
                    }
                    break;

                case METRIC_CONVERSION_RATE:
                    if (!originalData.ConversionRate.Equals(0))
                    {
                        return(GetPercentageImprovementPanel((variantData.ConversionRate / originalData.ConversionRate) - 1));
                    }
                    break;

                case METRIC_AVG_CONVERSION_VALUE:
                    if (!originalData.AverageConversionValue.Equals(0))
                    {
                        return(GetPercentageImprovementPanel((variantData.AverageConversionValue / originalData.AverageConversionValue) - 1));
                    }
                    break;
                }
            }
            break;
        }

        return(string.Empty);
    }