This is an automated email from the ASF dual-hosted git repository.

pierrejeambrun pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/v3-1-test by this push:
     new 6fe77aa6b77 [v3-1-test] Fix duration chart duration format (#58561) 
(#58564)
6fe77aa6b77 is described below

commit 6fe77aa6b776929e3667e4a146066e183b8f0c43
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Nov 21 16:48:57 2025 +0100

    [v3-1-test] Fix duration chart duration format (#58561) (#58564)
    
    (cherry picked from commit 2512aa40e0372374de2a9493141f24c4566cb8b9)
    
    Co-authored-by: Pierre Jeambrun <[email protected]>
---
 .../airflow/ui/src/components/DurationChart.tsx    | 24 +++++++++++++++++++---
 .../src/airflow/ui/src/utils/datetimeUtils.ts      |  7 +++++--
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx 
b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx
index c0fd7cf796b..5699dcc8c8d 100644
--- a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx
+++ b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx
@@ -36,7 +36,7 @@ import { useNavigate } from "react-router-dom";
 
 import type { TaskInstanceResponse, GridRunsResponse } from 
"openapi/requests/types.gen";
 import { getComputedCSSVariableValue } from "src/theme";
-import { DEFAULT_DATETIME_FORMAT } from "src/utils/datetimeUtils";
+import { DEFAULT_DATETIME_FORMAT, renderDuration } from 
"src/utils/datetimeUtils";
 
 ChartJS.register(
   CategoryScale,
@@ -94,7 +94,7 @@ export const DurationChart = ({
     borderColor: "grey",
     borderWidth: 1,
     label: {
-      content: (ctx: PartialEventContext) => average(ctx, 1).toFixed(2),
+      content: (ctx: PartialEventContext) => renderDuration(average(ctx, 1), 
false) ?? "0",
       display: true,
       position: "end",
     },
@@ -106,7 +106,7 @@ export const DurationChart = ({
     borderColor: "grey",
     borderWidth: 1,
     label: {
-      content: (ctx: PartialEventContext) => average(ctx, 0).toFixed(2),
+      content: (ctx: PartialEventContext) => renderDuration(average(ctx, 0), 
false) ?? "0",
       display: true,
       position: "end",
     },
@@ -200,6 +200,17 @@ export const DurationChart = ({
                 runAnnotation,
               },
             },
+            tooltip: {
+              callbacks: {
+                label: (context) => {
+                  const datasetLabel = context.dataset.label ?? "";
+
+                  const formatted = renderDuration(context.parsed.y, false) ?? 
"0";
+
+                  return datasetLabel ? `${datasetLabel}: ${formatted}` : 
formatted;
+                },
+              },
+            },
           },
           responsive: true,
           scales: {
@@ -211,6 +222,13 @@ export const DurationChart = ({
               title: { align: "end", display: true, text: 
translate("common:dagRun.runAfter") },
             },
             y: {
+              ticks: {
+                callback: (value) => {
+                  const num = typeof value === "number" ? value : 
Number(value);
+
+                  return renderDuration(num, false) ?? "0";
+                },
+              },
               title: { align: "end", display: true, text: 
translate("common:duration") },
             },
           },
diff --git a/airflow-core/src/airflow/ui/src/utils/datetimeUtils.ts 
b/airflow-core/src/airflow/ui/src/utils/datetimeUtils.ts
index abd598e3deb..8c2f28c9541 100644
--- a/airflow-core/src/airflow/ui/src/utils/datetimeUtils.ts
+++ b/airflow-core/src/airflow/ui/src/utils/datetimeUtils.ts
@@ -26,13 +26,16 @@ dayjs.extend(tz);
 export const DEFAULT_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
 export const DEFAULT_DATETIME_FORMAT_WITH_TZ = `${DEFAULT_DATETIME_FORMAT} z`;
 
-export const renderDuration = (durationSeconds: number | null | undefined): 
string | undefined => {
+export const renderDuration = (
+  durationSeconds: number | null | undefined,
+  withMilliseconds: boolean = true,
+): string | undefined => {
   if (durationSeconds === null || durationSeconds === undefined || 
durationSeconds <= 0.01) {
     return undefined;
   }
 
   // If under 60 seconds, render milliseconds
-  if (durationSeconds < 60) {
+  if (durationSeconds < 60 && withMilliseconds) {
     return dayjs.duration(Number(durationSeconds.toFixed(3)), 
"seconds").format("HH:mm:ss.SSS");
   }
 

Reply via email to