Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions experimenter/experimenter/experiments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1659,11 +1659,21 @@ def get_weekly_metric_data(self, analysis_basis, segment, reference_branch):
abs_list = branch_data.get("absolute") or []
rel_list = branch_data.get("relative") or []

weekly_data[branch_slug] = list(
zip_longest(abs_list, rel_list, fillvalue=None)
)
if abs_list or rel_list:
weekly_data[branch_slug] = list(
zip_longest(abs_list, rel_list, fillvalue=None)
)

weekly_metric_data[metric_metadata["slug"]] = weekly_data
if weekly_data:
weekly_metric_data[metric_metadata["slug"]] = {
"has_weekly_data": True,
"data": weekly_data,
}
else:
weekly_metric_data[metric_metadata["slug"]] = {
"has_weekly_data": False,
"data": {},
}

return weekly_metric_data

Expand Down
169 changes: 169 additions & 0 deletions experimenter/experimenter/experiments/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,175 @@ def test_targeting_config_returns_None_with_invalid_slug(self):
experiment = NimbusExperimentFactory.create(targeting_config_slug="invalid slug")
self.assertIsNone(experiment.targeting_config)

@mock_valid_outcomes
def test_get_weekly_metric_data(self):
experiment = NimbusExperimentFactory.create()
branch_a = NimbusBranchFactory.create(
experiment=experiment, name="Branch A", slug="branch-a"
)
branch_b = NimbusBranchFactory.create(
experiment=experiment, name="Branch B", slug="branch-b"
)

experiment.results_data = {
"v3": {
"weekly": {
"enrollments": {
"all": {
branch_a.slug: {
"branch_data": {
"other_metrics": {
"retained": {
"absolute": {
"all": [
{
"lower": 140,
"upper": 160,
"point": 150,
},
{
"lower": 130,
"upper": 150,
"point": 140,
},
{
"lower": 120,
"upper": 140,
"point": 130,
},
]
},
"relative_uplift": {
branch_a.slug: {"all": []},
},
}
}
},
},
branch_b.slug: {
"branch_data": {
"other_metrics": {
"retained": {
"absolute": {
"all": [
{
"lower": 140,
"upper": 160,
"point": 150,
},
{
"lower": 130,
"upper": 150,
"point": 140,
},
{
"lower": 120,
"upper": 140,
"point": 130,
},
]
},
"relative_uplift": {
branch_a.slug: {
"all": [
{
"lower": 10,
"upper": 20,
"point": 15,
},
{
"lower": 5,
"upper": 15,
"point": 10,
},
{
"lower": 0,
"upper": 10,
"point": 5,
},
]
},
branch_b.slug: {"all": []},
},
}
}
}
},
}
}
}
}
}
experiment.save()

expected_weekly_data = {
"retained": {
"data": {
branch_a.slug: [
(
{"lower": 140, "upper": 160, "significance": "neutral"},
None,
),
(
{"lower": 130, "upper": 150, "significance": "neutral"},
None,
),
(
{"lower": 120, "upper": 140, "significance": "neutral"},
None,
),
],
branch_b.slug: [
(
{"lower": 140, "upper": 160, "significance": "neutral"},
{
"avg_rel_change": 15,
"lower": 10,
"upper": 20,
"significance": "neutral",
},
),
(
{"lower": 130, "upper": 150, "significance": "neutral"},
{
"avg_rel_change": 10,
"lower": 5,
"upper": 15,
"significance": "neutral",
},
),
(
{"lower": 120, "upper": 140, "significance": "neutral"},
{
"avg_rel_change": 5,
"lower": 0,
"upper": 10,
"significance": "neutral",
},
),
],
},
"has_weekly_data": True,
},
"search_count": {
"data": {},
"has_weekly_data": False,
},
"total_amazon_search_count": {
"data": {},
"has_weekly_data": False,
},
"urlbar_amazon_search_count": {
"data": {},
"has_weekly_data": False,
},
}

self.assertEqual(
experiment.get_weekly_metric_data("enrollments", "all", branch_a.slug),
expected_weekly_data,
)

@parameterized.expand(
[
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,66 +78,68 @@ <h2 class="accordion-header">
</div>
</div>
</div>
<div class="accordion-item p-3 px-4 rounded-4 border border-1">
<h2 class="accordion-header">
<button class="accordion-button fw-bold shadow-none bg-transparent text-body"
type="button"
data-bs-toggle="collapse"
data-bs-target="#{{ experiment_slug }}-{{ metric_info.slug }}-weekly-collapse"
aria-expanded="true"
aria-controls="{{ experiment_slug }}-{{ metric_info.slug }}-weekly-collapse">
Weekly breakdown
</button>
</h2>
{% with weekly_metric_data=all_weekly_metric_data|dict_get:metric_info.slug %}
<div class="accordion-collapse collapse show"
id="{{ experiment_slug }}-{{ metric_info.slug }}-weekly-collapse">
<div class="accordion-body d-flex">
<div class="col-2">
<p class="text-muted mb-0 invisible" aria-hidden="true">Metrics</p>
<p class="fs-5 mb-3 invisible" aria-hidden="true">Baseline</p>
{% with reference_branch_weekly=weekly_metric_data|dict_get:reference_branch %}
{% for week in experiment.get_weekly_dates %}
<div class="{% if forloop.last %}mb-4{% endif %} mb-3 d-flex text-center rounded-4 w-100 text-start position-relative d-flex flex-column align-items-center justify-content-center"
style="height: 100px">
<small class="text-muted">Week {{ forloop.counter }}</small>
<p class="mb-0">{{ week.0|date:"M j" }} - {{ week.1|date:"M j" }}</p>
</div>
{% endfor %}
{% endwith %}
</div>
<div class="col position-relative w-25">
<div class="row flex-row flex-nowrap overflow-auto mx-2 pb-3 {% if branch_data|length > 3 %}mx-4{% endif %}">
{% if branch_data|length > 3 %}
<div class="branch-fade branch-fade-left"></div>
<div class="branch-fade branch-fade-right"></div>
{% endif %}
{% for branch in branch_data %}
<div class="{% if branch.slug == selected_reference_branch %}col-2{% elif branch_data|length > 3 %}col-4{% else %}col{% endif %} d-flex flex-column align-items-center">
<p class="text-muted mb-0 text-truncate">{{ branch.name }}</p>
{% if branch.slug == selected_reference_branch %}
<p class="fs-5 mb-3">Baseline</p>
{% else %}
<p class="fs-5">{{ branch.name }}</p>
{% endif %}
<div class="d-flex flex-column gap-3 w-100">
{% for curr_branch_slug, branch_weekly_metric_data in weekly_metric_data.items %}
{% if curr_branch_slug == branch.slug %}
{% for weekly_data_point in branch_weekly_metric_data %}
{% include "common/metric_card.html" with slug=branch.slug reference_branch=selected_reference_branch absolute_lower=weekly_data_point.0.lower absolute_upper=weekly_data_point.0.upper significance=weekly_data_point.1.significance percentage=weekly_data_point.1.avg_rel_change %}
{% with weekly_metric_data=all_weekly_metric_data|dict_get:metric_info.slug %}
{% if weekly_metric_data.has_weekly_data %}
<div class="accordion-item p-3 px-4 rounded-4 border border-1">
<h2 class="accordion-header">
<button class="accordion-button fw-bold shadow-none bg-transparent text-body"
type="button"
data-bs-toggle="collapse"
data-bs-target="#{{ experiment_slug }}-{{ metric_info.slug }}-weekly-collapse"
aria-expanded="true"
aria-controls="{{ experiment_slug }}-{{ metric_info.slug }}-weekly-collapse">
Weekly breakdown
</button>
</h2>
<div class="accordion-collapse collapse show"
id="{{ experiment_slug }}-{{ metric_info.slug }}-weekly-collapse">
<div class="accordion-body d-flex">
<div class="col-2">
<p class="text-muted mb-0 invisible" aria-hidden="true">Metrics</p>
<p class="fs-5 mb-3 invisible" aria-hidden="true">Baseline</p>
{% with reference_branch_weekly=weekly_metric_data.data|dict_get:reference_branch %}
{% for week in experiment.get_weekly_dates %}
<div class="{% if forloop.last %}mb-4{% endif %} mb-3 d-flex text-center rounded-4 w-100 text-start position-relative d-flex flex-column align-items-center justify-content-center"
style="height: 100px">
<small class="text-muted">Week {{ forloop.counter }}</small>
<p class="mb-0">{{ week.0|date:"M j" }} - {{ week.1|date:"M j" }}</p>
</div>
{% endfor %}
{% endwith %}
</div>
<div class="col position-relative w-25">
<div class="row flex-row flex-nowrap overflow-auto mx-2 pb-3 {% if branch_data|length > 3 %}mx-4{% endif %}">
{% if branch_data|length > 3 %}
<div class="branch-fade branch-fade-left"></div>
<div class="branch-fade branch-fade-right"></div>
{% endif %}
{% for branch in branch_data %}
<div class="{% if branch.slug == selected_reference_branch %}col-2{% elif branch_data|length > 3 %}col-4{% else %}col{% endif %} d-flex flex-column align-items-center">
<p class="text-muted mb-0 text-truncate">{{ branch.name }}</p>
{% if branch.slug == selected_reference_branch %}
<p class="fs-5 mb-3">Baseline</p>
{% else %}
<p class="fs-5">{{ branch.name }}</p>
{% endif %}
<div class="d-flex flex-column gap-3 w-100">
{% for curr_branch_slug, branch_weekly_metric_data in weekly_metric_data.data.items %}
{% if curr_branch_slug == branch.slug %}
{% for weekly_data_point in branch_weekly_metric_data %}
{% include "common/metric_card.html" with slug=branch.slug reference_branch=selected_reference_branch absolute_lower=weekly_data_point.0.lower absolute_upper=weekly_data_point.0.upper significance=weekly_data_point.1.significance percentage=weekly_data_point.1.avg_rel_change %}

{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}
</div>
</div>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endwith %}
</div>
{% endif %}
{% endwith %}
</div>
</div>
</div>
Expand Down