From d0e49f75863e9b0133d365c6c6c2747d4afbd382 Mon Sep 17 00:00:00 2001 From: Hironsan Date: Thu, 24 Feb 2022 09:15:52 +0900 Subject: [PATCH] Enable to show relation distribution --- backend/labels/managers.py | 15 +++++++-- backend/labels/models.py | 9 +++++- backend/metrics/urls.py | 2 ++ backend/metrics/views.py | 9 ++++-- .../metrics/RelationDistribution.vue | 31 +++++++++++++++++++ .../models/metrics/metricsRepository.ts | 1 + frontend/pages/projects/_id/metrics/index.vue | 5 +++ .../metrics/apiMetricsRepository.ts | 6 ++++ .../metrics/metricsApplicationService.ts | 4 +++ 9 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 frontend/components/metrics/RelationDistribution.vue diff --git a/backend/labels/managers.py b/backend/labels/managers.py index 111d9c94..f81cfcdb 100644 --- a/backend/labels/managers.py +++ b/backend/labels/managers.py @@ -2,6 +2,8 @@ from django.db.models import Count, Manager class LabelManager(Manager): + label_type_field = "label" + def calc_label_distribution(self, examples, members, labels): """Calculate label distribution. @@ -20,12 +22,12 @@ class LabelManager(Manager): distribution = {member.username: {label.text: 0 for label in labels} for member in members} items = ( self.filter(example_id__in=examples) - .values("user__username", "label__text") - .annotate(count=Count("label__text")) + .values("user__username", f"{self.label_type_field}__text") + .annotate(count=Count(f"{self.label_type_field}__text")) ) for item in items: username = item["user__username"] - label = item["label__text"] + label = item[f"{self.label_type_field}__text"] count = item["count"] distribution[username][label] = count return distribution @@ -72,3 +74,10 @@ class TextLabelManager(LabelManager): if text.is_same_text(label): return False return True + + +class RelationManager(LabelManager): + label_type_field = "type" + + def can_annotate(self, label, project) -> bool: + return True diff --git a/backend/labels/models.py b/backend/labels/models.py index 98881b4e..be2d3cc9 100644 --- a/backend/labels/models.py +++ b/backend/labels/models.py @@ -2,7 +2,13 @@ from django.contrib.auth.models import User from django.core.exceptions import ValidationError from django.db import models -from .managers import CategoryManager, LabelManager, SpanManager, TextLabelManager +from .managers import ( + CategoryManager, + LabelManager, + RelationManager, + SpanManager, + TextLabelManager, +) from examples.models import Example from label_types.models import CategoryType, RelationType, SpanType @@ -91,6 +97,7 @@ class TextLabel(Label): class Relation(Label): + objects = RelationManager() from_id = models.ForeignKey(Span, on_delete=models.CASCADE, related_name="from_relations") to_id = models.ForeignKey(Span, on_delete=models.CASCADE, related_name="to_relations") type = models.ForeignKey(RelationType, on_delete=models.CASCADE) diff --git a/backend/metrics/urls.py b/backend/metrics/urls.py index 99b5e18d..1bcffb6f 100644 --- a/backend/metrics/urls.py +++ b/backend/metrics/urls.py @@ -4,6 +4,7 @@ from .views import ( CategoryTypeDistribution, MemberProgressAPI, ProgressAPI, + RelationTypeDistribution, SpanTypeDistribution, ) @@ -11,5 +12,6 @@ urlpatterns = [ path(route="progress", view=ProgressAPI.as_view(), name="progress"), path(route="member-progress", view=MemberProgressAPI.as_view(), name="member_progress"), path(route="category-distribution", view=CategoryTypeDistribution.as_view(), name="category_distribution"), + path(route="relation-distribution", view=RelationTypeDistribution.as_view(), name="relation_distribution"), path(route="span-distribution", view=SpanTypeDistribution.as_view(), name="span_distribution"), ] diff --git a/backend/metrics/views.py b/backend/metrics/views.py index ed1a0f25..ac39fd1a 100644 --- a/backend/metrics/views.py +++ b/backend/metrics/views.py @@ -6,8 +6,8 @@ from rest_framework.response import Response from rest_framework.views import APIView from examples.models import Example, ExampleState -from label_types.models import CategoryType, LabelType, SpanType -from labels.models import Category, Label, Span +from label_types.models import CategoryType, LabelType, RelationType, SpanType +from labels.models import Category, Label, Relation, Span from projects.models import Member from projects.permissions import IsProjectAdmin, IsProjectStaffAndReadOnly @@ -54,3 +54,8 @@ class CategoryTypeDistribution(LabelDistribution): class SpanTypeDistribution(LabelDistribution): model = Span label_type = SpanType + + +class RelationTypeDistribution(LabelDistribution): + model = Relation + label_type = RelationType diff --git a/frontend/components/metrics/RelationDistribution.vue b/frontend/components/metrics/RelationDistribution.vue new file mode 100644 index 00000000..c334b40e --- /dev/null +++ b/frontend/components/metrics/RelationDistribution.vue @@ -0,0 +1,31 @@ + + + diff --git a/frontend/domain/models/metrics/metricsRepository.ts b/frontend/domain/models/metrics/metricsRepository.ts index d5168f11..28fbaca6 100644 --- a/frontend/domain/models/metrics/metricsRepository.ts +++ b/frontend/domain/models/metrics/metricsRepository.ts @@ -3,6 +3,7 @@ import { Distribution, Progress, MyProgress } from '~/domain/models/metrics/metr export interface MetricsRepository { fetchCategoryDistribution(projectId: string): Promise fetchSpanDistribution(projectId: string): Promise + fetchRelationDistribution(projectId: string): Promise fetchMemberProgress(projectId: string): Promise fetchMyProgress(projectId: string): Promise } diff --git a/frontend/pages/projects/_id/metrics/index.vue b/frontend/pages/projects/_id/metrics/index.vue index 8870f8f8..901d7a2c 100644 --- a/frontend/pages/projects/_id/metrics/index.vue +++ b/frontend/pages/projects/_id/metrics/index.vue @@ -9,17 +9,22 @@ + + +