diff --git a/frontend/src/metabase/static-viz/components/Legend/types.ts b/frontend/src/metabase/static-viz/components/Legend/types.ts
index 2e8344955da2cef8e3c25669656ab1f58d1ce8a2..225c48b134768f9163fbb44acb9e3efdb0c4b063 100644
--- a/frontend/src/metabase/static-viz/components/Legend/types.ts
+++ b/frontend/src/metabase/static-viz/components/Legend/types.ts
@@ -1,7 +1,4 @@
-export type LegendItem = {
-  name: string;
-  color: string;
-};
+import type { LegendItem } from "metabase/visualizations/echarts/cartesian/model/types";
 
 export type PositionedLegendItem = LegendItem & {
   left: number;
diff --git a/frontend/src/metabase/static-viz/components/Legend/utils.ts b/frontend/src/metabase/static-viz/components/Legend/utils.ts
index 9aa4dbc6b9d9f6b306e20a22910b192b2c0ed941..be59194e31c45c2ea0cfb2bd2e9606c9ae262bf1 100644
--- a/frontend/src/metabase/static-viz/components/Legend/utils.ts
+++ b/frontend/src/metabase/static-viz/components/Legend/utils.ts
@@ -1,4 +1,5 @@
 import { measureTextWidth, truncateText } from "metabase/static-viz/lib/text";
+import type { LegendItem } from "metabase/visualizations/echarts/cartesian/model/types";
 
 import {
   DEFAULT_LEGEND_FONT_SIZE,
@@ -8,7 +9,7 @@ import {
   LEGEND_ITEM_MARGIN_RIGHT,
   DEFAULT_LEGEND_LINE_HEIGHT,
 } from "./constants";
-import type { LegendItem, PositionedLegendItem } from "./types";
+import type { PositionedLegendItem } from "./types";
 
 const calculateItemWidth = (
   item: LegendItem,
@@ -89,6 +90,7 @@ export const calculateLegendRows = ({
       currentRowX = horizontalPadding + itemWidth + LEGEND_ITEM_MARGIN_RIGHT;
     } else {
       currentRow.push({
+        key: item.key,
         color: item.color,
         name: truncateText(
           item.name,
diff --git a/frontend/src/metabase/static-viz/components/RowChart/RowChart.tsx b/frontend/src/metabase/static-viz/components/RowChart/RowChart.tsx
index 5e455b0c5323dd752025adfdb9c7d4ab4f5786ad..d8a70c5df1da4460267532445be114772c6b1193 100644
--- a/frontend/src/metabase/static-viz/components/RowChart/RowChart.tsx
+++ b/frontend/src/metabase/static-viz/components/RowChart/RowChart.tsx
@@ -92,6 +92,7 @@ const StaticRowChart = ({ data, settings, getColor }: StaticRowChartProps) => {
 
   const legend = calculateLegendRows({
     items: series.map(series => ({
+      key: series.seriesKey,
       name: series.seriesName,
       color: seriesColors[series.seriesKey],
     })),
diff --git a/frontend/src/metabase/visualizations/components/legend/Legend.jsx b/frontend/src/metabase/visualizations/components/legend/Legend.jsx
index c780fddf9725725db9449988ce363790ca558181..f9e21efdf92211604b7340a84a1b0410b9511b25 100644
--- a/frontend/src/metabase/visualizations/components/legend/Legend.jsx
+++ b/frontend/src/metabase/visualizations/components/legend/Legend.jsx
@@ -19,8 +19,7 @@ const POPOVER_OFFSET = POPOVER_BORDER + POPOVER_PADDING;
 
 const propTypes = {
   className: PropTypes.string,
-  labels: PropTypes.array.isRequired,
-  colors: PropTypes.array.isRequired,
+  items: PropTypes.array.isRequired,
   hovered: PropTypes.object,
   visibleIndex: PropTypes.number,
   visibleLength: PropTypes.number,
@@ -36,11 +35,10 @@ const alwaysTrue = () => true;
 
 const Legend = ({
   className,
-  labels: originalLabels,
-  colors: originalColors,
+  items: originalItems,
   hovered,
   visibleIndex = 0,
-  visibleLength = originalLabels.length,
+  visibleLength = originalItems.length,
   isVertical,
   onHoverChange,
   onSelectSeries,
@@ -62,16 +60,11 @@ const Legend = ({
     setMaxWidth(0);
   }, []);
 
-  const labels = isReversed
-    ? _.clone(originalLabels).reverse()
-    : originalLabels;
-  const colors = isReversed
-    ? _.clone(originalColors).reverse()
-    : originalColors;
+  const items = isReversed ? _.clone(originalItems).reverse() : originalItems;
 
   const overflowIndex = visibleIndex + visibleLength;
-  const visibleLabels = labels.slice(visibleIndex, overflowIndex);
-  const overflowLength = labels.length - overflowIndex;
+  const visibleItems = items.slice(visibleIndex, overflowIndex);
+  const overflowLength = items.length - overflowIndex;
 
   return (
     <LegendRoot
@@ -79,18 +72,17 @@ const Legend = ({
       aria-label={t`Legend`}
       isVertical={isVertical}
     >
-      {visibleLabels.map((label, index) => {
+      {visibleItems.map((item, index) => {
         const localIndex = index + visibleIndex;
         const itemIndex = isReversed
-          ? labels.length - 1 - localIndex
+          ? items.length - 1 - localIndex
           : localIndex;
 
         return (
           <LegendItem
-            key={itemIndex}
-            label={label}
+            key={item.key}
+            item={item}
             index={itemIndex}
-            color={colors[localIndex % colors.length]}
             isMuted={hovered && itemIndex !== hovered.index}
             isVertical={isVertical}
             isReversed={isReversed}
@@ -120,8 +112,7 @@ const Legend = ({
         >
           <LegendPopoverContainer style={{ maxWidth }}>
             <Legend
-              labels={originalLabels}
-              colors={originalColors}
+              items={originalItems}
               hovered={hovered}
               visibleIndex={overflowIndex}
               visibleLength={overflowLength}
diff --git a/frontend/src/metabase/visualizations/components/legend/LegendItem.jsx b/frontend/src/metabase/visualizations/components/legend/LegendItem.jsx
index 8680f0f9f3ccaa57507d61c77b2a69d3958596f3..4b87bc6bd189940ff05fc003b8e0e969b600b063 100644
--- a/frontend/src/metabase/visualizations/components/legend/LegendItem.jsx
+++ b/frontend/src/metabase/visualizations/components/legend/LegendItem.jsx
@@ -15,9 +15,8 @@ import {
 } from "./LegendItem.styled";
 
 const propTypes = {
-  label: PropTypes.string,
+  item: PropTypes.object,
   index: PropTypes.number,
-  color: PropTypes.string,
   isMuted: PropTypes.bool,
   isVertical: PropTypes.bool,
   isReversed: PropTypes.bool,
@@ -27,9 +26,8 @@ const propTypes = {
 };
 
 const LegendItem = ({
-  label,
+  item,
   index,
-  color,
   isMuted,
   isVertical,
   isReversed,
@@ -61,7 +59,7 @@ const LegendItem = ({
         onMouseEnter={onHoverChange && handleItemMouseEnter}
         onMouseLeave={onHoverChange && handleItemMouseLeave}
       >
-        <LegendItemDot color={color} />
+        <LegendItemDot color={item.color} />
         <LegendItemTitle
           className={cx(
             DashboardS.fullscreenNormalText,
@@ -69,7 +67,7 @@ const LegendItem = ({
             EmbedFrameS.fullscreenNightText,
           )}
         >
-          <Ellipsified>{label}</Ellipsified>
+          <Ellipsified>{item.name}</Ellipsified>
         </LegendItemTitle>
       </LegendItemLabel>
       {onRemoveSeries && <LegendItemRemoveIcon onClick={handleRemoveClick} />}
diff --git a/frontend/src/metabase/visualizations/components/legend/LegendLayout.jsx b/frontend/src/metabase/visualizations/components/legend/LegendLayout.jsx
index dcdc8227804f5370c1bf77f471fe4ff849edaa72..6a7056a026fb384c68312d06057937900a73d57e 100644
--- a/frontend/src/metabase/visualizations/components/legend/LegendLayout.jsx
+++ b/frontend/src/metabase/visualizations/components/legend/LegendLayout.jsx
@@ -19,8 +19,7 @@ const MIN_LEGEND_WIDTH = 400;
 
 const propTypes = {
   className: PropTypes.string,
-  labels: PropTypes.array.isRequired,
-  colors: PropTypes.array.isRequired,
+  items: PropTypes.array.isRequired,
   hovered: PropTypes.object,
   width: PropTypes.number,
   height: PropTypes.number,
@@ -38,8 +37,7 @@ const propTypes = {
 
 const LegendLayout = ({
   className,
-  labels,
-  colors,
+  items,
   hovered,
   width = 0,
   height = 0,
@@ -59,12 +57,12 @@ const LegendLayout = ({
   const maxXItems = Math.floor(width / MIN_ITEM_WIDTH);
   const maxYItems = Math.floor(height / itemHeight);
   const maxYLabels = Math.max(maxYItems - 1, 0);
-  const minYLabels = labels.length > maxYItems ? maxYLabels : labels.length;
+  const minYLabels = items.length > maxYItems ? maxYLabels : items.length;
 
   const isNarrow = width < MIN_LEGEND_WIDTH;
-  const isVertical = maxXItems < labels.length;
+  const isVertical = maxXItems < items.length;
   const isVisible = hasLegend && !(isVertical && isNarrow);
-  const visibleLength = isVertical ? minYLabels : labels.length;
+  const visibleLength = isVertical ? minYLabels : items.length;
 
   return (
     <LegendLayoutRoot className={className} isVertical={isVertical}>
@@ -74,8 +72,7 @@ const LegendLayout = ({
           isQueryBuilder={isQueryBuilder}
         >
           <Legend
-            labels={labels}
-            colors={colors}
+            items={items}
             hovered={hovered}
             visibleLength={visibleLength}
             isVertical={isVertical}
diff --git a/frontend/src/metabase/visualizations/echarts/cartesian/model/legend.ts b/frontend/src/metabase/visualizations/echarts/cartesian/model/legend.ts
index 4f2752e478ed5798fe5661ec0ced98666ccc43cd..452ac74c278a487a5923fb9c4ec49386b50ab6e2 100644
--- a/frontend/src/metabase/visualizations/echarts/cartesian/model/legend.ts
+++ b/frontend/src/metabase/visualizations/echarts/cartesian/model/legend.ts
@@ -1,10 +1,10 @@
 import { isBreakoutSeries } from "./guards";
-import type { SeriesModel } from "./types";
+import type { LegendItem, SeriesModel } from "./types";
 
 export const getLegendItems = (
   seriesModels: SeriesModel[],
   showAllLegendItems: boolean = false,
-) => {
+): LegendItem[] => {
   if (
     seriesModels.length === 1 &&
     !isBreakoutSeries(seriesModels[0]) &&
@@ -14,6 +14,7 @@ export const getLegendItems = (
   }
 
   return seriesModels.map(seriesModel => ({
+    key: seriesModel.dataKey,
     name: seriesModel.name,
     color: seriesModel.color,
   }));
diff --git a/frontend/src/metabase/visualizations/echarts/cartesian/model/legend.unit.spec.ts b/frontend/src/metabase/visualizations/echarts/cartesian/model/legend.unit.spec.ts
index 03025a47463c335e47e786f9f7db9c3ad1a69e39..1fceea1e2de9d056752c933ee8c58d25a9f0309a 100644
--- a/frontend/src/metabase/visualizations/echarts/cartesian/model/legend.unit.spec.ts
+++ b/frontend/src/metabase/visualizations/echarts/cartesian/model/legend.unit.spec.ts
@@ -17,8 +17,8 @@ describe("getLegendItems", () => {
       createMockSeriesModel({ name: "Series 2", color: "blue" }),
     ]);
     expect(legendItems).toStrictEqual([
-      { name: "Series 1", color: "red" },
-      { name: "Series 2", color: "blue" },
+      { name: "Series 1", color: "red", key: "dataKey" },
+      { name: "Series 2", color: "blue", key: "dataKey" },
     ]);
   });
 
@@ -26,6 +26,8 @@ describe("getLegendItems", () => {
     const legendItems = getLegendItems([
       createMockBreakoutSeriesModel({ name: "breakout series" }),
     ]);
-    expect(legendItems).toEqual([{ name: "breakout series", color: "red" }]);
+    expect(legendItems).toEqual([
+      { name: "breakout series", color: "red", key: "dataKey" },
+    ]);
   });
 });
diff --git a/frontend/src/metabase/visualizations/echarts/cartesian/model/types.ts b/frontend/src/metabase/visualizations/echarts/cartesian/model/types.ts
index f46724eb485a184330cb609eecf8dc2c53af6325..46bd03f53b1c70fb0ea4aaa9fc79a583a9ac7c55 100644
--- a/frontend/src/metabase/visualizations/echarts/cartesian/model/types.ts
+++ b/frontend/src/metabase/visualizations/echarts/cartesian/model/types.ts
@@ -205,3 +205,9 @@ export type CartesianChartModel = BaseCartesianChartModel & {
 };
 
 export type ShowWarning = (warning: string) => void;
+
+export type LegendItem = {
+  key: string;
+  name: string;
+  color: string;
+};
diff --git a/frontend/src/metabase/visualizations/visualizations/CartesianChart/CartesianChart.tsx b/frontend/src/metabase/visualizations/visualizations/CartesianChart/CartesianChart.tsx
index 9756feb1415199017f0da89ecb9ed8d684f1da4d..c5d1392d6e2da2f371697789ec698a68268e7197 100644
--- a/frontend/src/metabase/visualizations/visualizations/CartesianChart/CartesianChart.tsx
+++ b/frontend/src/metabase/visualizations/visualizations/CartesianChart/CartesianChart.tsx
@@ -106,8 +106,7 @@ function _CartesianChart(props: VisualizationProps) {
       <CartesianChartLegendLayout
         isReversed={settings["legend.is_reversed"]}
         hasLegend={hasLegend}
-        labels={legendItems.map(item => item.name)}
-        colors={legendItems.map(item => item.color)}
+        items={legendItems}
         actionButtons={!hasTitle ? actionButtons : undefined}
         hovered={hovered}
         isFullscreen={isFullscreen}
diff --git a/frontend/src/metabase/visualizations/visualizations/RowChart/RowChart.tsx b/frontend/src/metabase/visualizations/visualizations/RowChart/RowChart.tsx
index 5d96a9543d371518a59e996b8216d76a6a0d7997..3322728ff57e223df3527349b4410db6d9f3a63f 100644
--- a/frontend/src/metabase/visualizations/visualizations/RowChart/RowChart.tsx
+++ b/frontend/src/metabase/visualizations/visualizations/RowChart/RowChart.tsx
@@ -234,7 +234,7 @@ const RowChartVisualization = ({
   const description = settings["card.description"];
   const canSelectTitle = !!onChangeCardAndRun;
 
-  const { labels, colors } = useMemo(
+  const legendItems = useMemo(
     () => getLegendItems(series, seriesColors, settings),
     [series, seriesColors, settings],
   );
@@ -279,8 +279,7 @@ const RowChartVisualization = ({
       )}
       <RowChartLegendLayout
         hasLegend={hasLegend}
-        labels={labels}
-        colors={colors}
+        items={legendItems}
         actionButtons={!hasTitle ? actionButtons : undefined}
         hovered={hovered}
         onHoverChange={onHoverChange}
diff --git a/frontend/src/metabase/visualizations/visualizations/RowChart/utils/legend.ts b/frontend/src/metabase/visualizations/visualizations/RowChart/utils/legend.ts
index e167e79b1ebd2d09d2b4f9a642cc9fddf24f5868..1ab4a54bb5307f06de65e73c464bc39e36b19ccb 100644
--- a/frontend/src/metabase/visualizations/visualizations/RowChart/utils/legend.ts
+++ b/frontend/src/metabase/visualizations/visualizations/RowChart/utils/legend.ts
@@ -1,3 +1,4 @@
+import type { LegendItem } from "metabase/visualizations/echarts/cartesian/model/types";
 import type { Series } from "metabase/visualizations/shared/components/RowChart/types";
 import type { VisualizationSettings } from "metabase-types/api";
 
@@ -5,14 +6,11 @@ export const getLegendItems = <TDatum>(
   multipleSeries: Series<TDatum, unknown>[],
   seriesColors: Record<string, string>,
   settings: VisualizationSettings,
-) => {
-  const orderedTitles = multipleSeries.map(
-    series =>
+): LegendItem[] => {
+  return multipleSeries.map(series => ({
+    key: series.seriesKey,
+    name:
       settings?.series_settings?.[series.seriesKey]?.title ?? series.seriesName,
-  );
-
-  return {
-    labels: orderedTitles,
-    colors: multipleSeries.map(single => seriesColors[single.seriesKey]),
-  };
+    color: seriesColors[series.seriesKey],
+  }));
 };