diff --git a/src/components/Workflows.vue b/src/components/Workflows.vue index 7f20484fb1fe16f4c5848259de7b8eb1ed65017d..adb64b734cd187398203a72e4e6ca3363fa06249 100644 --- a/src/components/Workflows.vue +++ b/src/components/Workflows.vue @@ -52,6 +52,12 @@ workflowsStore.gt = await api.getGroundTruth() workflowsStore.workflows = await api.getWorkflows() + workflowsStore.runs.forEach(run => { + const gtId = mapGtId(run.metadata.gt_workspace.id) + + if (!workflowsStore.gt.find(gt => gt.id === gtId)) console.log(gtId) + }) + const releasesObj = workflowsStore.runs.reduce((acc, cur) => { acc[cur.metadata.release_info.tag_name] = cur.metadata.release_info return acc diff --git a/src/components/workflows/WorkflowsTimeline.vue b/src/components/workflows/WorkflowsTimeline.vue index d912a1de6a2be1fe88e3373b90771a6bd5bb5a9f..bb038ec106f82a4f67bb82d4df09ec6d01dddd3f 100644 --- a/src/components/workflows/WorkflowsTimeline.vue +++ b/src/components/workflows/WorkflowsTimeline.vue @@ -4,14 +4,14 @@ import Dropdown from 'primevue/dropdown' import {computed, onMounted, ref, watch} from "vue" import {EvaluationMetrics, getMaxValueByMetric} from '@/helpers/metrics' import { useI18n } from "vue-i18n" -import type {DropdownOption, EvaluationResultsDocumentWide, Workflow} from "@/types" +import type { DropdownOption, EvaluationResultsDocumentWide, Workflow, GroundTruth } from "@/types" import { DropdownPassThroughStyles } from '@/helpers/pt' import workflowsStore from '@/store/workflows-store' import filtersStore from '@/store/filters-store' import timelineStore from "@/store/timeline-store" const { t } = useI18n() -const gtList = computed(() => workflowsStore.gt.filter(({ id }) => filtersStore.gt.findIndex(({ value }) => value === id) > -1)) +const gtList = computed<GroundTruth[]>(() => workflowsStore.gt.filter(({ id }) => filtersStore.gt.findIndex(({ value }) => value === id) > -1)) const workflows = ref<Workflow[]>([]) const selectedMetric = ref<DropdownOption | null>(null) const metrics = computed<DropdownOption[]>(() => Object.keys(EvaluationMetrics).map(key => ({ value: EvaluationMetrics[key], label: t(EvaluationMetrics[key]) }))) diff --git a/src/components/workflows/timeline/BaseTimelineChart.vue b/src/components/workflows/timeline/BaseTimelineChart.vue index 8c92c69d279af0c9e382028344d777fb5121edd5..b52f12caae5b78c47082b9f1aa65436c9c35be6e 100644 --- a/src/components/workflows/timeline/BaseTimelineChart.vue +++ b/src/components/workflows/timeline/BaseTimelineChart.vue @@ -14,7 +14,8 @@ interface Props { startDate: Date, endDate: Date, height?: number, - tooltipContent: (d: TimelineChartDataPoint) => string + tooltipContent: (d: TimelineChartDataPoint) => string, + higherIsPositive?: boolean } const props = defineProps<Props>() @@ -28,24 +29,20 @@ const _width = computed(() => props.width ?? 300) const container = ref<HTMLDivElement>() -function isUp(data: TimelineChartDataPoint[], higherIsUp = true) { +function isUp(data: TimelineChartDataPoint[], higherIsPositive = true) { if (data.length === 0) return 0 const last = data[data.length - 1].value const secondLast = data.length > 1 ? data[data.length - 2].value : last - const diff = higherIsUp ? last - secondLast : secondLast - last + const diff = higherIsPositive ? last - secondLast : secondLast - last if (diff === 0) return 0 else if (diff > 0) return 1 else return -1 } -function renderReleases() { - -} - function render([data, startDate, endDate, maxY]) { if (!data || !startDate || !endDate) return @@ -90,13 +87,13 @@ function render([data, startDate, endDate, maxY]) { svg.selectAll('.y-axis-group .tick text').attr('fill', colors.gray['400']) - const trend = isUp(data, false) + const trend = isUp(data, props.higherIsPositive) const pathGroup = svg .append('g') .classed('path-group', true) - .classed('up', trend === 1) - .classed('down', trend === -1) + .classed('trend-positive', trend === 1) + .classed('trend-negative', trend === -1) pathGroup.append("path") .datum(data) @@ -181,7 +178,7 @@ watch([() => props.data, () => props.startDate, () => props.endDate, () => props fill: var(--color--neutral-text); } - &.up { + &.trend-positive { path { stroke: var(--color--positive-text); } @@ -191,7 +188,7 @@ watch([() => props.data, () => props.startDate, () => props.endDate, () => props } } - &.down { + &.trend-negative { path { stroke: var(--color--negative-text); } diff --git a/src/components/workflows/timeline/MetricAverageChart.vue b/src/components/workflows/timeline/MetricAverageChart.vue index 7bdbed7fc25d7b589be364a56d07cabfab26a8b9..a77e738ba01a6a41a7c28edc21be7691d93d4b3d 100644 --- a/src/components/workflows/timeline/MetricAverageChart.vue +++ b/src/components/workflows/timeline/MetricAverageChart.vue @@ -1,15 +1,12 @@ <script setup lang="ts"> import {computed, onMounted, ref, watch} from "vue" -import api from "@/helpers/api" import BaseTimelineChart from "@/components/workflows/timeline/BaseTimelineChart.vue" import type {EvaluationResultsDocumentWide, EvaluationRun, TimelineChartDataPoint} from "@/types" -import {useI18n} from "vue-i18n"; import { metricChartTooltipContent } from "@/helpers/metric-chart-tooltip-content"; import OverlayPanel from "primevue/overlaypanel"; import BaseTimelineDetailedChart from "@/components/workflows/timeline/BaseTimelineDetailedChart.vue"; import timelineStore from "@/store/timeline-store"; - -const { t } = useI18n() +import {isHigherPositive} from "@/helpers/metrics"; const props = defineProps<{ runs: EvaluationRun[], @@ -21,7 +18,6 @@ const props = defineProps<{ const data = ref<TimelineChartDataPoint[]>([]) const maxY = computed(() => timelineStore.maxValues[props.metric] ?? 0) -const runs = ref<EvaluationRun[]>([]) const op = ref<OverlayPanel | null>(null) onMounted(async () => { @@ -37,26 +33,26 @@ function init() { function getTimelineData(runs: EvaluationRun[], metric: string): TimelineChartDataPoint[] { const datesValues = runs.reduce((acc, cur) => { - const date = new Date(new Date(cur.metadata.timestamp).setHours(0, 0, 0, 0)).toDateString() - const value = cur.evaluation_results.document_wide[<keyof EvaluationResultsDocumentWide>metric] - if (!value || Array.isArray(value)) return acc + const date = new Date(new Date(cur.metadata.timestamp).setHours(0, 0, 0, 0)).toDateString() + const value = cur.evaluation_results.document_wide[<keyof EvaluationResultsDocumentWide>metric] + if (!value || Array.isArray(value)) return acc - if (!acc[date]) acc[date] = [value] - else acc[date] = [...acc[date], value] - return acc - }, - <{ [key: string]: number[] }>{}) + if (!acc[date]) acc[date] = [value] + else acc[date] = [...acc[date], value] + return acc + }, + <{ [key: string]: number[] }>{}) return Object - .keys(datesValues) - .sort((a, b) => new Date(a) - new Date(b)) - .map(date => { - const value = datesValues[date].reduce((a, b) => a + b, 0) / datesValues[date].length - return { - date: new Date(date), - value - } - }) + .keys(datesValues) + .sort((a, b) => new Date(a) - new Date(b)) + .map(date => { + const value = datesValues[date].reduce((a, b) => a + b, 0) / datesValues[date].length + return { + date: new Date(date), + value + } + }) } function tooltipContent(d: TimelineChartDataPoint) { @@ -73,6 +69,7 @@ function tooltipContent(d: TimelineChartDataPoint) { :end-date="endDate" :tooltip-content="tooltipContent" :width="400" + :higher-is-positive="isHigherPositive(metric)" /> </div> <OverlayPanel diff --git a/src/components/workflows/timeline/TimelineItem.vue b/src/components/workflows/timeline/TimelineItem.vue index 6811bfecb972de5359bed96275b9b052c9be4f13..c8b3831f2e4b7749f13ac3c41ba9036357b75ccb 100644 --- a/src/components/workflows/timeline/TimelineItem.vue +++ b/src/components/workflows/timeline/TimelineItem.vue @@ -3,13 +3,12 @@ import Panel from "primevue/panel" import OverlayPanel from 'primevue/overlaypanel' import StepsAcronyms from '@/helpers/workflow-steps-acronyms' import MetricChart from "@/components/workflows/timeline/MetricChart.vue" -import type { EvaluationResultsDocumentWide, EvaluationRun, GroundTruth, Workflow, WorkflowStep } from "@/types" +import type { EvaluationResultsDocumentWide, GroundTruth, Workflow, WorkflowStep } from "@/types" import MetricAverageChart from "@/components/workflows/timeline/MetricAverageChart.vue" import { Icon } from '@iconify/vue' import { onMounted, ref } from "vue" import { OverlayPanelDropdownStyles } from "@/helpers/pt" import workflowsStore from "@/store/workflows-store" -import HomeView from "@/views/HomeView.vue" const props = defineProps<{ gt: GroundTruth, @@ -99,13 +98,13 @@ function hideParametersOverlay() { </td> <td class="overflow-x-auto"> <MetricChart - :runs="workflowsStore.getRuns(gt.id, workflow.id)" - :workflow-name="workflow.label" - :metric="metric" - :width="400" - :start-date="startDate" - :end-date="endDate" - class="flex justify-end" + :runs="workflowsStore.getRuns(gt.id, workflow.id)" + :workflow-name="workflow.label" + :metric="metric" + :width="400" + :start-date="startDate" + :end-date="endDate" + class="flex justify-end" /> </td> </tr> diff --git a/src/helpers/metrics.ts b/src/helpers/metrics.ts index 488697d17473293594580c8f067caaa54fccfc0f..b9040fc8b196cf4fb3113d4e272a1a11949c68bb 100644 --- a/src/helpers/metrics.ts +++ b/src/helpers/metrics.ts @@ -31,13 +31,21 @@ function getMaxValueByMetric(metric: keyof EvaluationResultsDocumentWide, runs: return Math.max(...values) } -function extendMaxValue(value: number): number { - return Math.floor(value + value * 0.2) +function isHigherPositive(metric: keyof EvaluationResultsDocumentWide): boolean { + if (metric === EvaluationMetrics.CER_MEAN) return false + if (metric === EvaluationMetrics.CER_MEDIAN) return false + if (metric === EvaluationMetrics.CER_STANDARD_DEVIATION) return false + if (metric === EvaluationMetrics.WER) return false + if (metric === EvaluationMetrics.WALL_TIME) return false + if (metric === EvaluationMetrics.PAGES_PER_MINUTE) return true + if (metric === EvaluationMetrics.CPU_TIME) return false + + return false } export { EvaluationMetrics, getMaxValueByMetric, getDefaultMaxValueOfMetric, - extendMaxValue + isHigherPositive }