From cea92b0930dfd481be527f57683dc2a6fb65de6d Mon Sep 17 00:00:00 2001 From: gtarpenning Date: Thu, 10 Oct 2024 16:59:02 -0700 Subject: [PATCH 01/10] lol why is this so hard --- .../SummaryPlotsSection/PlotlyBarPlot.tsx | 33 ++- .../SummaryPlotsSection/PlotlyRadarPlot.tsx | 8 +- .../SummaryPlotsSection.tsx | 195 ++++++++++++------ 3 files changed, 152 insertions(+), 84 deletions(-) diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/PlotlyBarPlot.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/PlotlyBarPlot.tsx index 9706ac09567..1c5175a0475 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/PlotlyBarPlot.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/PlotlyBarPlot.tsx @@ -2,26 +2,12 @@ import * as Plotly from 'plotly.js'; import React, {useEffect, useMemo, useRef} from 'react'; import {PLOT_GRID_COLOR} from '../../ecpConstants'; -import {RadarPlotData} from './PlotlyRadarPlot'; export const PlotlyBarPlot: React.FC<{ height: number; - data: RadarPlotData; + plotlyData: Plotly.Data; }> = props => { const divRef = useRef(null); - const plotlyData: Plotly.Data[] = useMemo(() => { - return Object.keys(props.data).map((key, i) => { - const {metrics, name, color} = props.data[key]; - return { - type: 'bar', - y: Object.values(metrics), - x: Object.keys(metrics), - name, - marker: {color}, - }; - }); - }, [props.data]); - const plotlyLayout: Partial = useMemo(() => { return { height: props.height - 40, @@ -30,7 +16,7 @@ export const PlotlyBarPlot: React.FC<{ l: 0, r: 0, b: 20, - t: 0, + t: 20, pad: 0, }, xaxis: { @@ -44,8 +30,17 @@ export const PlotlyBarPlot: React.FC<{ gridcolor: PLOT_GRID_COLOR, linecolor: PLOT_GRID_COLOR, }, + title: { + text: props.plotlyData.name ?? '', + font: {size: 14}, + xref: 'paper', + x: 0.5, + y: 1, // Position at the top + yanchor: 'top', + }, }; - }, [props.height]); + }, [props.height, props.plotlyData]); + const plotlyConfig = useMemo(() => { return { displayModeBar: false, @@ -57,11 +52,11 @@ export const PlotlyBarPlot: React.FC<{ useEffect(() => { Plotly.newPlot( divRef.current as any, - plotlyData, + [props.plotlyData], plotlyLayout, plotlyConfig ); - }, [plotlyConfig, plotlyData, plotlyLayout]); + }, [plotlyConfig, props.plotlyData, plotlyLayout]); return
; }; diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/PlotlyRadarPlot.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/PlotlyRadarPlot.tsx index d459d1354f1..4d0aa39b29f 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/PlotlyRadarPlot.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/PlotlyRadarPlot.tsx @@ -31,13 +31,13 @@ export const PlotlyRadarPlot: React.FC<{ }, [props.data]); const plotlyLayout: Partial = useMemo(() => { return { - height: props.height, + height: props.height - 40, showlegend: false, margin: { - l: 60, + l: 0, r: 0, - b: 30, - t: 30, + b: 20, + t: 20, pad: 0, }, polar: { diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx index 5bfaa8fcb04..2d04a9a6443 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx @@ -52,9 +52,9 @@ export const SummaryPlots: React.FC<{ } }, [selectedMetrics, setSelectedMetrics, allMetricNames]); - // filter down the plotlyRadarData to only include the selected metrics, after - // computation, to allow quick addition/removal of metrics - const filteredPlotlyRadarData = useMemo(() => { + // filter down the data to only include the selected metrics, after + // computation, to allow quick addition/removal of metrics. + const filteredData = useMemo(() => { const filteredData: RadarPlotData = {}; for (const [callId, metricBin] of Object.entries(radarData)) { const metrics: {[metric: string]: number} = {}; @@ -74,71 +74,144 @@ export const SummaryPlots: React.FC<{ return filteredData; }, [radarData, selectedMetrics]); + const plots = useMemo(() => { + const plots = [ + , + ]; + + // transform the data to be a list of metrics for each callId + const metrics: {[metric: string]: {callIds: string[], values: number[], name: string, colors: string[]}} = {}; + for (const [callId, metricBin] of Object.entries(filteredData)) { + for (const [metric, value] of Object.entries(metricBin.metrics)) { + metrics[metric] = { + callIds: [...(metrics[metric]?.callIds ?? []), callId], + values: [...(metrics[metric]?.values ?? []), value], + name: metric, + colors: [...(metrics[metric]?.colors ?? []), metricBin.color], + }; + } + } + + for (const metric of Object.keys(metrics)) { + const metricBin = metrics[metric]; + const plotlyData: Plotly.Data = { + type: 'bar', + y: metricBin.values, + // x: metricBin.callIds, + xaxis: '', + name: metric, + marker: {color: metricBin.colors}, + }; + plots.push( + + ); + } + + return plots; + }, [filteredData]); + + const containerRef = useRef(null); + const [containerWidth, setContainerWidth] = useState(0); + + useEffect(() => { + const updateWidth = () => { + if (containerRef.current) { + setContainerWidth(containerRef.current.offsetWidth); + } + }; + + updateWidth(); // Initial width + + window.addEventListener('resize', updateWidth); + return () => window.removeEventListener('resize', updateWidth); + }, []); + + console.log('containerWidth', containerWidth); + + const plotsPerPage = useMemo(() => { + return Math.max(1, Math.floor(containerWidth / (PLOT_HEIGHT + 20))); // 20px for margin + }, [containerWidth]); + + const [currentPage, setCurrentPage] = useState(0); + + const totalPages = Math.ceil(plots.length / plotsPerPage); + + const handleNextPage = () => { + setCurrentPage((prevPage) => Math.min(prevPage + 1, totalPages - 1)); + }; + + const handlePrevPage = () => { + setCurrentPage((prevPage) => Math.max(prevPage - 1, 0)); + }; + + const startIndex = currentPage * plotsPerPage; + const endIndex = Math.min(startIndex + plotsPerPage, plots.length); + const currentPlots = plots.slice(startIndex, endIndex); + return ( - - - - Summary Metrics - - -
-
Configure displayed metrics
- -
-
-
- - - - - + Summary Metrics + + +
+
Configure displayed metrics
+ +
+
+
+
+ - - - - + {currentPlots.map((plot, index) => ( + + {plot} + + ))} + +
+ + + + +
+ +
+ +
+ + + ); +}; diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx index 2c0b08a3787..85dbfcc8fc6 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx @@ -1,15 +1,6 @@ import {Box} from '@material-ui/core'; -import {Popover} from '@mui/material'; -import {Switch} from '@wandb/weave/components'; import {Button} from '@wandb/weave/components/Button'; -import { - DraggableGrow, - DraggableHandle, -} from '@wandb/weave/components/DraggablePopups'; -import {TextField} from '@wandb/weave/components/Form/TextField'; import {Tailwind} from '@wandb/weave/components/Tailwind'; -import {maybePluralize} from '@wandb/weave/core/util/string'; -import classNames from 'classnames'; import React, {useEffect, useMemo, useRef, useState} from 'react'; import {buildCompositeMetricsMap} from '../../compositeMetricsUtil'; @@ -27,6 +18,7 @@ import { resolveSummaryMetricValueForEvaluateCall, } from '../../ecpUtil'; import {HorizontalBox, VerticalBox} from '../../Layout'; +import {MetricsSelector} from './MetricsSelector'; import {PlotlyBarPlot} from './PlotlyBarPlot'; import {PlotlyRadarPlot, RadarPlotData} from './PlotlyRadarPlot'; @@ -40,8 +32,8 @@ export const SummaryPlots: React.FC<{ const {radarData, allMetricNames} = useNormalizedPlotDataFromMetrics(state); const {selectedMetrics} = state; + // Initialize selectedMetrics if null useEffect(() => { - // If selectedMetrics is null, we should show all metrics if (selectedMetrics == null) { setSelectedMetrics( Object.fromEntries(Array.from(allMetricNames).map(m => [m, true])) @@ -130,6 +122,91 @@ const SectionHeader: React.FC<{
); +const RadarPlotBox: React.FC<{data: RadarPlotData}> = ({data}) => ( + + + +); + +const BarPlotBox: React.FC<{ + plot: {plotlyData: Plotly.Data; yRange: [number, number]}; +}> = ({plot}) => ( + + + +); + +const PaginationControls: React.FC<{ + currentPage: number; + totalPages: number; + startIndex: number; + endIndex: number; + totalPlots: number; + onPrevPage: () => void; + onNextPage: () => void; +}> = ({ + currentPage, + totalPages, + startIndex, + endIndex, + totalPlots, + onPrevPage, + onNextPage, +}) => ( + + + +
+
+
+
+
+); + const useFilteredData = ( radarData: RadarPlotData, selectedMetrics: Record | undefined @@ -164,6 +241,8 @@ const useBarPlotData = (filteredData: RadarPlotData) => colors: string[]; }; } = {}; + + // Reorganize data by metric instead of by call for (const [callId, metricBin] of Object.entries(filteredData)) { for (const [metric, value] of Object.entries(metricBin.metrics)) { if (!metrics[metric]) { @@ -175,6 +254,7 @@ const useBarPlotData = (filteredData: RadarPlotData) => } } + // Convert metrics object to Plotly data format return Object.entries(metrics).map(([metric, metricBin]) => { const maxY = Math.max(...metricBin.values) * 1.1; const minY = Math.min(...metricBin.values, 0); @@ -237,6 +317,7 @@ const usePaginatedPlots = ( const totalPages = Math.ceil(totalPlotWidth / plotsPerPage); const plotsToShow = useMemo(() => { + // First page always shows radar plot if (currentPage === 0) { const availableSpace = plotsPerPage - radarPlotWidth; return [ @@ -248,6 +329,7 @@ const usePaginatedPlots = ( )), ]; } else { + // Subsequent pages show only bar plots const startIdx = (currentPage - 1) * plotsPerPage + (plotsPerPage - radarPlotWidth); const endIdx = startIdx + plotsPerPage; @@ -259,6 +341,7 @@ const usePaginatedPlots = ( } }, [currentPage, plotsPerPage, filteredData, barPlotData]); + // Calculate pagination details const totalPlots = barPlotData.length + 1; // +1 for the radar plot const startIndex = currentPage === 0 ? 1 : Math.min(plotsPerPage + 1, totalPlots); @@ -270,251 +353,6 @@ const usePaginatedPlots = ( return {plotsToShow, totalPlots, startIndex, endIndex, totalPages}; }; -const RadarPlotBox: React.FC<{data: RadarPlotData}> = ({data}) => ( - - - -); - -const BarPlotBox: React.FC<{ - plot: {plotlyData: Plotly.Data; yRange: [number, number]}; -}> = ({plot}) => ( - - - -); - -const PaginationControls: React.FC<{ - currentPage: number; - totalPages: number; - startIndex: number; - endIndex: number; - totalPlots: number; - onPrevPage: () => void; - onNextPage: () => void; -}> = ({ - currentPage, - totalPages, - startIndex, - endIndex, - totalPlots, - onPrevPage, - onNextPage, -}) => ( - - - -
-
-
-
-
-); - -const MetricsSelector: React.FC<{ - setSelectedMetrics: (newModel: Record) => void; - selectedMetrics: Record | undefined; - allMetrics: string[]; -}> = ({setSelectedMetrics, selectedMetrics, allMetrics}) => { - const [search, setSearch] = useState(''); - - const ref = useRef(null); - const [anchorEl, setAnchorEl] = useState(null); - const onClick = (event: React.MouseEvent) => { - setAnchorEl(anchorEl ? null : ref.current); - setSearch(''); - }; - const open = Boolean(anchorEl); - const id = open ? 'simple-popper' : undefined; - - const filteredCols = search - ? allMetrics.filter(col => col.toLowerCase().includes(search.toLowerCase())) - : allMetrics; - - const shownMetrics = Object.values(selectedMetrics ?? {}).filter(Boolean); - - const numHidden = allMetrics.length - shownMetrics.length; - const buttonSuffix = search ? `(${filteredCols.length})` : 'all'; - - return ( - <> - - -
- -
- - - - - ); -}; - const normalizeValues = (values: Array): number[] => { // find the max value // find the power of 2 that is greater than the max value From 7e3f354afdfd89da8d0f8be3ff8e16ac2fe613ad Mon Sep 17 00:00:00 2001 From: gtarpenning Date: Tue, 3 Dec 2024 10:01:14 -0800 Subject: [PATCH 08/10] add normalization for radar plot --- .../SummaryPlotsSection.tsx | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx index 85dbfcc8fc6..8eb7ecc7e4d 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx @@ -42,6 +42,7 @@ export const SummaryPlots: React.FC<{ }, [selectedMetrics, setSelectedMetrics, allMetricNames]); const filteredData = useFilteredData(radarData, selectedMetrics); + const normalizedRadarData = normalizeDataForRadarPlot(filteredData); const barPlotData = useBarPlotData(filteredData); const { @@ -53,7 +54,12 @@ export const SummaryPlots: React.FC<{ } = useContainerDimensions(); const {plotsToShow, totalPlots, startIndex, endIndex, totalPages} = - usePaginatedPlots(filteredData, barPlotData, plotsPerPage, currentPage); + usePaginatedPlots( + normalizedRadarData, + barPlotData, + plotsPerPage, + currentPage + ); // Render placeholder during initial render if (isInitialRender) { @@ -231,6 +237,54 @@ const useFilteredData = ( return data; }, [radarData, selectedMetrics]); +function normalizeDataForRadarPlot(radarData: RadarPlotData): RadarPlotData { + // First collect all values for each metric across all calls + const metricValues: {[metric: string]: number[]} = {}; + + // Gather all values for each metric + Object.values(radarData).forEach(callData => { + Object.entries(callData.metrics).forEach(([metric, value]) => { + if (!metricValues[metric]) { + metricValues[metric] = []; + } + metricValues[metric].push(value); + }); + }); + + // Find min/max for each metric + const metricRanges: {[metric: string]: {min: number; max: number}} = {}; + Object.entries(metricValues).forEach(([metric, values]) => { + metricRanges[metric] = { + min: Math.min(...values), + max: Math.max(...values), + }; + }); + + // Create normalized data structure + const normalizedData: RadarPlotData = {}; + + Object.entries(radarData).forEach(([callId, callData]) => { + normalizedData[callId] = { + name: callData.name, + color: callData.color, + metrics: {}, + }; + + Object.entries(callData.metrics).forEach(([metric, value]) => { + const range = metricRanges[metric]; + // If min and max are the same, set normalized value to 1 + // Otherwise normalize to 0-1 range + const normalizedValue = + range.max === range.min + ? 1 + : (value - range.min) / (range.max - range.min); + normalizedData[callId].metrics[metric] = normalizedValue; + }); + }); + + return normalizedData; +} + const useBarPlotData = (filteredData: RadarPlotData) => useMemo(() => { const metrics: { From 0455a7a1fbcf306c4158609afa2b6b592f6f6183 Mon Sep 17 00:00:00 2001 From: gtarpenning Date: Tue, 3 Dec 2024 10:19:59 -0800 Subject: [PATCH 09/10] better-simpler --- .../ComparisonDefinitionSection.tsx | 2 +- .../SummaryPlotsSection.tsx | 41 ++++++++++--------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/ComparisonDefinitionSection/ComparisonDefinitionSection.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/ComparisonDefinitionSection/ComparisonDefinitionSection.tsx index b5c1a4bf96c..07ed6ac4743 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/ComparisonDefinitionSection/ComparisonDefinitionSection.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/ComparisonDefinitionSection/ComparisonDefinitionSection.tsx @@ -105,7 +105,7 @@ const AddEvaluationButton: React.FC<{ ); const expandedRefCols = useMemo(() => new Set(), []); // Don't query for output here, re-queried in tsDataModelHooksEvaluationComparison.ts - const columns = useMemo(() => ['inputs'], []); + const columns = useMemo(() => ['inputs', 'display_name'], []); const calls = useCallsForQuery( props.state.data.entity, props.state.data.project, diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx index 8eb7ecc7e4d..c23ffcce04d 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/SummaryPlotsSection/SummaryPlotsSection.tsx @@ -237,10 +237,10 @@ const useFilteredData = ( return data; }, [radarData, selectedMetrics]); -function normalizeDataForRadarPlot(radarData: RadarPlotData): RadarPlotData { - // First collect all values for each metric across all calls +function getMetricValuesFromRadarData(radarData: RadarPlotData): { + [metric: string]: number[]; +} { const metricValues: {[metric: string]: number[]} = {}; - // Gather all values for each metric Object.values(radarData).forEach(callData => { Object.entries(callData.metrics).forEach(([metric, value]) => { @@ -250,19 +250,24 @@ function normalizeDataForRadarPlot(radarData: RadarPlotData): RadarPlotData { metricValues[metric].push(value); }); }); + return metricValues; +} - // Find min/max for each metric - const metricRanges: {[metric: string]: {min: number; max: number}} = {}; +function getMetricMinsFromRadarData(radarData: RadarPlotData): { + [metric: string]: number; +} { + const metricValues = getMetricValuesFromRadarData(radarData); + const metricMins: {[metric: string]: number} = {}; Object.entries(metricValues).forEach(([metric, values]) => { - metricRanges[metric] = { - min: Math.min(...values), - max: Math.max(...values), - }; + metricMins[metric] = Math.min(...values); }); + return metricMins; +} - // Create normalized data structure - const normalizedData: RadarPlotData = {}; +function normalizeDataForRadarPlot(radarData: RadarPlotData): RadarPlotData { + const metricMins = getMetricMinsFromRadarData(radarData); + const normalizedData: RadarPlotData = {}; Object.entries(radarData).forEach(([callId, callData]) => { normalizedData[callId] = { name: callData.name, @@ -271,13 +276,9 @@ function normalizeDataForRadarPlot(radarData: RadarPlotData): RadarPlotData { }; Object.entries(callData.metrics).forEach(([metric, value]) => { - const range = metricRanges[metric]; - // If min and max are the same, set normalized value to 1 - // Otherwise normalize to 0-1 range - const normalizedValue = - range.max === range.min - ? 1 - : (value - range.min) / (range.max - range.min); + const min = metricMins[metric]; + // Only shift values if there are negative values + const normalizedValue = min < 0 ? value - min : value; normalizedData[callId].metrics[metric] = normalizedValue; }); }); @@ -407,14 +408,14 @@ const usePaginatedPlots = ( return {plotsToShow, totalPlots, startIndex, endIndex, totalPages}; }; -const normalizeValues = (values: Array): number[] => { +function normalizeValues(values: Array): number[] { // find the max value // find the power of 2 that is greater than the max value // divide all values by that power of 2 const maxVal = Math.max(...(values.filter(v => v !== undefined) as number[])); const maxPower = Math.ceil(Math.log2(maxVal)); return values.map(val => (val ? val / 2 ** maxPower : 0)); -}; +} const useNormalizedPlotDataFromMetrics = ( state: EvaluationComparisonState From b52f0d8c3d7ab67089bcf371f934b121e27d2c3a Mon Sep 17 00:00:00 2001 From: gtarpenning Date: Mon, 9 Dec 2024 15:34:31 -0800 Subject: [PATCH 10/10] small fix for button search state --- .../ComparisonDefinitionSection/ComparisonDefinitionSection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/ComparisonDefinitionSection/ComparisonDefinitionSection.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/ComparisonDefinitionSection/ComparisonDefinitionSection.tsx index 07ed6ac4743..66ce56c4cb0 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/ComparisonDefinitionSection/ComparisonDefinitionSection.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/CompareEvaluationsPage/sections/ComparisonDefinitionSection/ComparisonDefinitionSection.tsx @@ -137,7 +137,7 @@ const AddEvaluationButton: React.FC<{ return; } - const filteredOptions = calls.result.filter(call => { + const filteredOptions = evalsNotComparing.filter(call => { if ( (call.displayName ?? call.spanName) .toLowerCase()