Jimin Huang
feature: change color
5a9e4d8
import { useMemo } from "react";
import {
looksLikeRegex,
parseSearchQuery,
getValueByPath,
} from "../utils/searchUtils";
// Calculate min/max averages
export const useAverageRange = (data) => {
return useMemo(() => {
const averages = data.map((item) => item.model.average_score);
return {
minAverage: Math.min(...averages),
maxAverage: Math.max(...averages),
};
}, [data]);
};
// Generate colors for scores
export const useColorGenerator = (minAverage, maxAverage) => {
return useMemo(() => {
const colorCache = new Map();
return (value) => {
const cached = colorCache.get(value);
if (cached) return cached;
const normalizedValue = (value - minAverage) / (maxAverage - minAverage);
const red = Math.round(255 * (1 - normalizedValue) * 1);
const green = Math.round(255 * normalizedValue) * 1;
// const color = `rgba(${red}, ${green}, 0, 1)`;
const color = `rgba(${red}, 0, ${green}, 1)`;
colorCache.set(value, color);
return color;
};
}, [minAverage, maxAverage]);
};
// Process data with boolean standardization
export const useProcessedData = (data, averageMode, visibleColumns) => {
return useMemo(() => {
let processed = data.map((item) => {
const evaluationScores = Object.entries(item.evaluations)
.filter(([key]) => {
if (averageMode === "all") return true;
return visibleColumns.includes(`evaluations.${key}.normalized_score`);
})
.map(([, value]) => value.normalized_score);
const average =
evaluationScores.length > 0
? evaluationScores.reduce((a, b) => a + b, 0) /
evaluationScores.length
: averageMode === "visible"
? null
: 0;
// Boolean standardization
const standardizedFeatures = {
...item.features,
is_moe: Boolean(item.features.is_moe),
is_flagged: Boolean(item.features.is_flagged),
is_highlighted_by_maintainer: Boolean(
item.features.is_highlighted_by_maintainer
),
is_merged: Boolean(item.features.is_merged),
is_not_available_on_hub: Boolean(item.features.is_not_available_on_hub),
};
return {
...item,
features: standardizedFeatures,
model: {
...item.model,
has_chat_template: Boolean(item.model.has_chat_template),
average_score: average,
},
};
});
processed.sort((a, b) => {
if (a.model.average_score === null && b.model.average_score === null)
return 0;
if (a.model.average_score === null) return 1;
if (b.model.average_score === null) return -1;
return b.model.average_score - a.model.average_score;
});
return processed.map((item, index) => ({
...item,
static_rank: index + 1,
}));
}, [data, averageMode, visibleColumns]);
};
// Common filtering logic
export const useFilteredData = (
processedData,
selectedPrecisions,
selectedTypes,
paramsRange,
searchValue,
selectedBooleanFilters,
rankingMode,
pinnedModels = [],
isOfficialProviderActive = false
) => {
return useMemo(() => {
const pinnedData = processedData.filter((row) => {
return pinnedModels.includes(row.id);
});
const unpinnedData = processedData.filter((row) => {
return !pinnedModels.includes(row.id);
});
let filteredUnpinned = unpinnedData;
// Filter by official providers
if (isOfficialProviderActive) {
filteredUnpinned = filteredUnpinned.filter(
(row) =>
row.features?.is_highlighted_by_maintainer ||
row.metadata?.is_highlighted_by_maintainer
);
}
// Filter by precision
if (selectedPrecisions.length > 0) {
filteredUnpinned = filteredUnpinned.filter((row) =>
selectedPrecisions.includes(row.model.precision)
);
}
// Filter by type
if (selectedTypes.length > 0) {
filteredUnpinned = filteredUnpinned.filter((row) => {
const modelType = row.model.type?.toLowerCase().trim();
return selectedTypes.some((type) => modelType?.includes(type));
});
}
// Filter by parameters
filteredUnpinned = filteredUnpinned.filter((row) => {
// Skip parameter filtering if no filter is active
if (paramsRange[0] === -1 && paramsRange[1] === 140) return true;
const params =
row.metadata?.params_billions || row.features?.params_billions;
if (params === undefined || params === null) return false;
return params >= paramsRange[0] && params < paramsRange[1];
});
// Filter by search
if (searchValue) {
const searchQueries = searchValue
.split(";")
.map((q) => q.trim())
.filter((q) => q);
if (searchQueries.length > 0) {
filteredUnpinned = filteredUnpinned.filter((row) => {
return searchQueries.some((query) => {
const { specialSearches, textSearch } = parseSearchQuery(query);
const specialSearchMatch = specialSearches.every(
({ field, value }) => {
const fieldValue = getValueByPath(row, field)
?.toString()
.toLowerCase();
return fieldValue?.includes(value.toLowerCase());
}
);
if (!specialSearchMatch) return false;
if (!textSearch) return true;
const modelName = row.model.name.toLowerCase();
const searchLower = textSearch.toLowerCase();
if (looksLikeRegex(textSearch)) {
try {
const regex = new RegExp(textSearch, "i");
return regex.test(modelName);
} catch (e) {
return modelName.includes(searchLower);
}
} else {
return modelName.includes(searchLower);
}
});
});
}
}
// Filter by booleans
if (selectedBooleanFilters.length > 0) {
filteredUnpinned = filteredUnpinned.filter((row) => {
return selectedBooleanFilters.every((filter) => {
const filterValue =
typeof filter === "object" ? filter.value : filter;
// Maintainer's Highlight keeps positive logic
if (filterValue === "is_highlighted_by_maintainer") {
return row.features[filterValue];
}
// For all other filters, invert the logic
if (filterValue === "is_not_available_on_hub") {
return row.features[filterValue];
}
return !row.features[filterValue];
});
});
}
// Create ordered array of pinned models respecting pinnedModels order
const orderedPinnedData = pinnedModels
.map((pinnedModelId) =>
pinnedData.find((item) => item.id === pinnedModelId)
)
.filter(Boolean);
// Combine all filtered data
const allFilteredData = [...filteredUnpinned, ...orderedPinnedData];
// Sort all data by average_score for dynamic_rank
const sortedByScore = [...allFilteredData].sort((a, b) => {
// Si les scores moyens sont différents, trier par score
if (a.model.average_score !== b.model.average_score) {
if (a.model.average_score === null && b.model.average_score === null)
return 0;
if (a.model.average_score === null) return 1;
if (b.model.average_score === null) return -1;
return b.model.average_score - a.model.average_score;
}
// Si les scores sont égaux, comparer le nom du modèle et la date de soumission
if (a.model.name === b.model.name) {
// Si même nom, trier par date de soumission (la plus récente d'abord)
const dateA = new Date(a.metadata?.submission_date || 0);
const dateB = new Date(b.metadata?.submission_date || 0);
return dateB - dateA;
}
// Si noms différents, trier par nom
return a.model.name.localeCompare(b.model.name);
});
// Create Map to store dynamic_ranks
const dynamicRankMap = new Map();
sortedByScore.forEach((item, index) => {
dynamicRankMap.set(item.id, index + 1);
});
// Add ranks to final data
const finalData = [...orderedPinnedData, ...filteredUnpinned].map(
(item) => {
return {
...item,
dynamic_rank: dynamicRankMap.get(item.id),
rank: item.isPinned
? pinnedModels.indexOf(item.id) + 1
: rankingMode === "static"
? item.static_rank
: dynamicRankMap.get(item.id),
isPinned: pinnedModels.includes(item.id),
};
}
);
return finalData;
}, [
processedData,
selectedPrecisions,
selectedTypes,
paramsRange,
searchValue,
selectedBooleanFilters,
rankingMode,
pinnedModels,
isOfficialProviderActive,
]);
};
// Column visibility management
export const useColumnVisibility = (visibleColumns = []) => {
// Create secure visibility object
const columnVisibility = useMemo(() => {
// Check visible columns
const safeVisibleColumns = Array.isArray(visibleColumns)
? visibleColumns
: [];
const visibility = {};
try {
safeVisibleColumns.forEach((columnKey) => {
if (typeof columnKey === "string") {
visibility[columnKey] = true;
}
});
} catch (error) {
console.warn("Error in useColumnVisibility:", error);
}
return visibility;
}, [visibleColumns]);
return columnVisibility;
};