From d74acdaa0ef38d09b235c1d3928bedee0e6f0194 Mon Sep 17 00:00:00 2001
From: Emmad Usmani <emmadusmani@berkeley.edu>
Date: Wed, 4 Sep 2024 11:49:23 -0700
Subject: [PATCH] remove static viz import from pie chart option (#47159)

---
 ...ptop_static_viz_Gauge_Truncated_Labels.png | Bin 0 -> 26421 bytes
 .../components/FunnelChart/utils/funnel.ts    |  29 +++++++++++--
 .../components/Gauge/Gauge.stories.tsx        |   4 ++
 .../components/Gauge/GaugeContainer.tsx       |  12 ++++-
 .../components/Gauge/stories-data.ts          |  40 +++++++++++++++++
 .../static-viz/components/Legend/Legend.tsx   |  12 +++--
 .../static-viz/components/Legend/utils.ts     |  12 +++--
 frontend/src/metabase/static-viz/lib/text.ts  |  21 ---------
 .../metabase/static-viz/lib/text.unit.spec.js |  16 +------
 .../visualizations/echarts/pie/option.ts      |  14 ++++--
 .../src/metabase/visualizations/lib/text.ts   |  23 ++++++++++
 .../visualizations/lib/text.unit.spec.ts      |  41 ++++++++++++++++++
 12 files changed, 173 insertions(+), 51 deletions(-)
 create mode 100644 .loki/reference/chrome_laptop_static_viz_Gauge_Truncated_Labels.png
 create mode 100644 frontend/src/metabase/visualizations/lib/text.ts
 create mode 100644 frontend/src/metabase/visualizations/lib/text.unit.spec.ts

diff --git a/.loki/reference/chrome_laptop_static_viz_Gauge_Truncated_Labels.png b/.loki/reference/chrome_laptop_static_viz_Gauge_Truncated_Labels.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d5a4b0beca413a1d8d8ff7e0c7dfbcee0e1f3af
GIT binary patch
literal 26421
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
A!vFvP

literal 0
HcmV?d00001

diff --git a/frontend/src/metabase/static-viz/components/FunnelChart/utils/funnel.ts b/frontend/src/metabase/static-viz/components/FunnelChart/utils/funnel.ts
index 77aa661e018..883c4c25d43 100644
--- a/frontend/src/metabase/static-viz/components/FunnelChart/utils/funnel.ts
+++ b/frontend/src/metabase/static-viz/components/FunnelChart/utils/funnel.ts
@@ -1,8 +1,11 @@
 import type { PolygonProps } from "@visx/shape/lib/shapes/Polygon";
 
 import { isNotNull } from "metabase/lib/types";
+import { CHAR_SIZES_FONT_WEIGHT } from "metabase/static-viz/constants/char-sizes";
 import { formatNumber, formatPercent } from "metabase/static-viz/lib/numbers";
-import { truncateText } from "metabase/static-viz/lib/text";
+import { measureTextWidth } from "metabase/static-viz/lib/text";
+import { truncateText } from "metabase/visualizations/lib/text";
+import type { TextWidthMeasurer } from "metabase/visualizations/shared/types/measure-text";
 
 import type { FunnelDatum, FunnelSettings, FunnelStep, Step } from "../types";
 
@@ -63,10 +66,21 @@ export const getFormattedStep = (
     typeof step.step === "number"
       ? formatNumber(step.step, settings?.step?.format)
       : step.step;
+
+  const textMeasurer: TextWidthMeasurer = (text, style) =>
+    measureTextWidth(text, Number(style.size), Number(style.weight));
+
+  const fontStyle = {
+    size: stepFontSize,
+    weight: CHAR_SIZES_FONT_WEIGHT,
+    family: "Lato",
+  };
+
   const stepName = truncateText(
     formattedStepName,
     maxStepTextWidth,
-    stepFontSize,
+    textMeasurer,
+    fontStyle,
   );
 
   const formattedMeasure = formatNumber(
@@ -75,12 +89,19 @@ export const getFormattedStep = (
   );
   const measure = isFirst
     ? formattedMeasure
-    : truncateText(formattedMeasure, maxStepTextWidth, measureFontSize);
+    : truncateText(formattedMeasure, maxStepTextWidth, textMeasurer, {
+        ...fontStyle,
+        size: measureFontSize,
+      });
 
   const percent = truncateText(
     formatPercent(step.percent),
     maxStepTextWidth,
-    percentFontSize,
+    textMeasurer,
+    {
+      ...fontStyle,
+      size: percentFontSize,
+    },
   );
 
   return {
diff --git a/frontend/src/metabase/static-viz/components/Gauge/Gauge.stories.tsx b/frontend/src/metabase/static-viz/components/Gauge/Gauge.stories.tsx
index 31677b8f8c6..687c02ca8ff 100644
--- a/frontend/src/metabase/static-viz/components/Gauge/Gauge.stories.tsx
+++ b/frontend/src/metabase/static-viz/components/Gauge/Gauge.stories.tsx
@@ -4,6 +4,7 @@ import { color } from "metabase/lib/colors";
 import GaugeContainer from "metabase/static-viz/components/Gauge/GaugeContainer";
 import {
   DEFAULT,
+  TRUNCATED_LABELS,
   WITH_FORMATTING,
 } from "metabase/static-viz/components/Gauge/stories-data";
 
@@ -21,3 +22,6 @@ Default.args = { ...DEFAULT, getColor: color };
 
 export const WithFormatting = Template.bind({});
 WithFormatting.args = { ...WITH_FORMATTING, getColor: color };
+
+export const TruncatedLabels = Template.bind({});
+TruncatedLabels.args = { ...TRUNCATED_LABELS, getColor: color };
diff --git a/frontend/src/metabase/static-viz/components/Gauge/GaugeContainer.tsx b/frontend/src/metabase/static-viz/components/Gauge/GaugeContainer.tsx
index 92ac7d6ad08..e45f1f978de 100644
--- a/frontend/src/metabase/static-viz/components/Gauge/GaugeContainer.tsx
+++ b/frontend/src/metabase/static-viz/components/Gauge/GaugeContainer.tsx
@@ -1,5 +1,7 @@
+import { CHAR_SIZES_FONT_WEIGHT } from "metabase/static-viz/constants/char-sizes";
 import { formatNumber } from "metabase/static-viz/lib/numbers";
-import { truncateText } from "metabase/static-viz/lib/text";
+import { measureTextWidth } from "metabase/static-viz/lib/text";
+import { truncateText } from "metabase/visualizations/lib/text";
 import type { ColorGetter } from "metabase/visualizations/types";
 
 import Gauge from "./Gauge";
@@ -126,7 +128,13 @@ export default function GaugeContainer({
         value: truncateText(
           segment.label,
           MAX_SEGMENT_VALUE_WIDTH,
-          SEGMENT_LABEL_FONT_SIZE,
+          (text, style) =>
+            measureTextWidth(text, Number(style.size), Number(style.weight)),
+          {
+            size: SEGMENT_LABEL_FONT_SIZE,
+            family: "Lato",
+            weight: CHAR_SIZES_FONT_WEIGHT,
+          },
         ),
         color: getColor("text-dark"),
       };
diff --git a/frontend/src/metabase/static-viz/components/Gauge/stories-data.ts b/frontend/src/metabase/static-viz/components/Gauge/stories-data.ts
index 2271862d785..322f4ae23ab 100644
--- a/frontend/src/metabase/static-viz/components/Gauge/stories-data.ts
+++ b/frontend/src/metabase/static-viz/components/Gauge/stories-data.ts
@@ -69,3 +69,43 @@ export const WITH_FORMATTING: Omit<GaugeContainerProps, "getColor"> = {
     rows: [[18760]],
   },
 };
+
+export const TRUNCATED_LABELS: Omit<GaugeContainerProps, "getColor"> = {
+  card: {
+    visualization_settings: {
+      "gauge.segments": [
+        {
+          min: 0,
+          max: 9380,
+          color: "#ED6E6E",
+          label: "The quick brown fox jumps over the lazy dog.",
+        },
+        {
+          min: 9380,
+          max: 18760,
+          color: "#F9CF48",
+          label: "The quick brown fox jumps over the lazy dog.",
+        },
+        {
+          min: 18760,
+          max: 37520,
+          color: "#84BB4C",
+          label: "The quick brown fox jumps over the lazy dog.",
+        },
+      ],
+      column_settings: {
+        '["name","count"]': {
+          number_style: "currency",
+          number_separators: ".’",
+          scale: 2,
+          prefix: "<",
+          suffix: ">",
+          decimals: 1,
+        },
+      },
+    },
+  },
+  data: {
+    rows: [[18760]],
+  },
+};
diff --git a/frontend/src/metabase/static-viz/components/Legend/Legend.tsx b/frontend/src/metabase/static-viz/components/Legend/Legend.tsx
index d0926d43933..27ec09a82e3 100644
--- a/frontend/src/metabase/static-viz/components/Legend/Legend.tsx
+++ b/frontend/src/metabase/static-viz/components/Legend/Legend.tsx
@@ -1,7 +1,8 @@
 import { Group } from "@visx/group";
 
 import { Text } from "metabase/static-viz/components/Text";
-import { measureTextWidth, truncateText } from "metabase/static-viz/lib/text";
+import { measureTextWidth } from "metabase/static-viz/lib/text";
+import { truncateText } from "metabase/visualizations/lib/text";
 
 import {
   DEFAULT_LEGEND_FONT_SIZE,
@@ -49,8 +50,13 @@ export const Legend = ({
                   LEGEND_CIRCLE_SIZE -
                   LEGEND_CIRCLE_MARGIN_RIGHT -
                   legendItemMarginRight,
-                fontSize,
-                fontWeight,
+                (text, style) =>
+                  measureTextWidth(
+                    text,
+                    Number(style.size),
+                    Number(style.weight),
+                  ),
+                { size: fontSize, weight: fontWeight, family: "Lato" },
               )
             : originalName;
 
diff --git a/frontend/src/metabase/static-viz/components/Legend/utils.ts b/frontend/src/metabase/static-viz/components/Legend/utils.ts
index 66719517da3..5549bf88edb 100644
--- a/frontend/src/metabase/static-viz/components/Legend/utils.ts
+++ b/frontend/src/metabase/static-viz/components/Legend/utils.ts
@@ -1,5 +1,6 @@
-import { measureTextWidth, truncateText } from "metabase/static-viz/lib/text";
+import { measureTextWidth } from "metabase/static-viz/lib/text";
 import type { LegendItem } from "metabase/visualizations/echarts/cartesian/model/types";
+import { truncateText } from "metabase/visualizations/lib/text";
 
 import {
   DEFAULT_LEGEND_FONT_SIZE,
@@ -105,8 +106,13 @@ export const calculateLegendRows = ({
         name: truncateText(
           item.name,
           availableTotalWidth,
-          fontSize,
-          fontWeight,
+          (text, style) =>
+            measureTextWidth(text, Number(style.size), Number(style.weight)),
+          {
+            size: fontSize,
+            weight: fontWeight,
+            family: "Lato",
+          },
         ),
         left: horizontalPadding,
         top: currentRowIndex * lineHeight + verticalPadding,
diff --git a/frontend/src/metabase/static-viz/lib/text.ts b/frontend/src/metabase/static-viz/lib/text.ts
index 0c92d1b6e4d..0beb06dc5c3 100644
--- a/frontend/src/metabase/static-viz/lib/text.ts
+++ b/frontend/src/metabase/static-viz/lib/text.ts
@@ -6,7 +6,6 @@ import {
   CHAR_SIZES_FONT_WEIGHT,
 } from "../constants/char-sizes";
 
-const CHAR_ELLIPSES = "…";
 const FONT_WEIGHT_WIDTH_FACTOR = 0.039;
 
 export const { getTextWidth } = init(CHAR_SIZES);
@@ -34,26 +33,6 @@ export const measureTextHeight = (fontSize: number) => {
   return fontSize * 1.3;
 };
 
-export const truncateText = (
-  text: string,
-  width: number,
-  fontSize: number,
-  fontWeight = CHAR_SIZES_FONT_WEIGHT,
-) => {
-  if (measureTextWidth(text, fontSize, fontWeight) <= width) {
-    return text;
-  }
-
-  while (
-    text.length &&
-    measureTextWidth(text + CHAR_ELLIPSES, fontSize, fontWeight) > width
-  ) {
-    text = text.substring(0, text.length - 1).trim();
-  }
-
-  return text + CHAR_ELLIPSES;
-};
-
 const parseEChartsFontString = (fontString: string) => {
   const parts = fontString.split(/\s+/);
 
diff --git a/frontend/src/metabase/static-viz/lib/text.unit.spec.js b/frontend/src/metabase/static-viz/lib/text.unit.spec.js
index 3468a2b8b88..e5d5d5fa696 100644
--- a/frontend/src/metabase/static-viz/lib/text.unit.spec.js
+++ b/frontend/src/metabase/static-viz/lib/text.unit.spec.js
@@ -1,4 +1,4 @@
-import { measureTextWidth, truncateText } from "./text";
+import { measureTextWidth } from "./text";
 
 const fontSize = 11;
 
@@ -7,17 +7,3 @@ describe("measureTextWidth", () => {
     expect(Math.round(measureTextWidth("abc", fontSize))).toBe(17);
   });
 });
-
-describe("truncateText", () => {
-  it("should not truncate text with ellipses if there is no overflow", () => {
-    expect(truncateText("John Doe", 48, fontSize)).toBe("John Doe");
-  });
-
-  it("should truncate text with ellipses if there is overflow", () => {
-    expect(truncateText("John Doe", 48, fontSize)).toBe("John Doe");
-  });
-
-  it("should use ellipses in case there is no space for text at all", () => {
-    expect(truncateText("John Doe", 0, fontSize)).toBe("…");
-  });
-});
diff --git a/frontend/src/metabase/visualizations/echarts/pie/option.ts b/frontend/src/metabase/visualizations/echarts/pie/option.ts
index 006753df1f8..0afec622d99 100644
--- a/frontend/src/metabase/visualizations/echarts/pie/option.ts
+++ b/frontend/src/metabase/visualizations/echarts/pie/option.ts
@@ -2,7 +2,7 @@ import Color from "color";
 import type { EChartsOption } from "echarts";
 
 import { getTextColorForBackground } from "metabase/lib/colors";
-import { truncateText } from "metabase/static-viz/lib/text";
+import { truncateText } from "metabase/visualizations/lib/text";
 import type {
   ComputedVisualizationSettings,
   RenderingContext,
@@ -52,17 +52,25 @@ function getTotalGraphicOption(
         weight: DIMENSIONS.total.fontWeight,
       }) > outerRadius; // innerRadius technically makes more sense, but looks too narrow in practice
 
+    const fontStyle = {
+      size: DIMENSIONS.total.valueFontSize,
+      weight: DIMENSIONS.total.fontWeight,
+      family: renderingContext.fontFamily,
+    };
+
     valueText = truncateText(
       formatters.formatMetric(sliceValueOrTotal, valueWillOverflow),
       outerRadius,
-      DIMENSIONS.total.valueFontSize,
+      renderingContext.measureText,
+      fontStyle,
     );
     labelText = truncateText(
       hoveredIndex != null
         ? chartModel.slices[hoveredIndex].data.name.toUpperCase()
         : TOTAL_TEXT,
       outerRadius,
-      DIMENSIONS.total.labelFontSize,
+      renderingContext.measureText,
+      fontStyle,
     );
   }
 
diff --git a/frontend/src/metabase/visualizations/lib/text.ts b/frontend/src/metabase/visualizations/lib/text.ts
new file mode 100644
index 00000000000..20c9aa5b3f6
--- /dev/null
+++ b/frontend/src/metabase/visualizations/lib/text.ts
@@ -0,0 +1,23 @@
+import type {
+  FontStyle,
+  TextWidthMeasurer,
+} from "../shared/types/measure-text";
+
+const CHAR_ELLIPSES = "…";
+
+export function truncateText(
+  text: string,
+  width: number,
+  measurer: TextWidthMeasurer,
+  fontStyle: FontStyle,
+) {
+  if (measurer(text, fontStyle) <= width) {
+    return text;
+  }
+
+  while (text.length && measurer(text + CHAR_ELLIPSES, fontStyle) > width) {
+    text = text.substring(0, text.length - 1).trim();
+  }
+
+  return text + CHAR_ELLIPSES;
+}
diff --git a/frontend/src/metabase/visualizations/lib/text.unit.spec.ts b/frontend/src/metabase/visualizations/lib/text.unit.spec.ts
new file mode 100644
index 00000000000..24eaa868acf
--- /dev/null
+++ b/frontend/src/metabase/visualizations/lib/text.unit.spec.ts
@@ -0,0 +1,41 @@
+import { measureTextWidth as measureDynamic } from "metabase/lib/measure-text";
+import { measureTextWidth as measureStatic } from "metabase/static-viz/lib/text";
+
+import type { TextWidthMeasurer } from "../shared/types/measure-text";
+
+import { truncateText } from "./text";
+
+const fontStyle = {
+  size: 11,
+  weight: 400,
+  family: "Lato",
+};
+
+const tests: { name: string; measurer: TextWidthMeasurer }[] = [
+  { name: "truncateText - dynamic viz measurer", measurer: measureDynamic },
+  {
+    name: "truncateText - static viz measurer",
+    measurer: (text, style) =>
+      measureStatic(text, Number(style.size), Number(style.weight)),
+  },
+];
+
+tests.map(test => {
+  describe(test.name, () => {
+    it("should not truncate text with ellipses if there is no overflow", () => {
+      expect(truncateText("John Doe", 48, test.measurer, fontStyle)).toBe(
+        "John Doe",
+      );
+    });
+
+    it("should truncate text with ellipses if there is overflow", () => {
+      expect(truncateText("John Doe", 48, test.measurer, fontStyle)).toBe(
+        "John Doe",
+      );
+    });
+
+    it("should use ellipses in case there is no space for text at all", () => {
+      expect(truncateText("John Doe", 0, test.measurer, fontStyle)).toBe("…");
+    });
+  });
+});
-- 
GitLab