Skip to content

Commit 6844f02

Browse files
feat: randomize plot order on every page reload (#3816)
Remove deterministic shuffle seed to ensure plots appear in a new random order on each F5/reload, even when filters remain unchanged. Changes: - Remove hashFilters() function (no longer needed) - Use Math.random() instead of seeded shuffle - Applies to both filtered and unfiltered views Fixes random order behavior on homepage --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 155f2a1 commit 6844f02

File tree

1 file changed

+5
-33
lines changed

1 file changed

+5
-33
lines changed

app/src/hooks/useFilterState.ts

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,44 +12,17 @@ import { API_URL, BATCH_SIZE } from '../constants';
1212
import { useHomeState } from '../components/Layout';
1313

1414
/**
15-
* Seeded random number generator (mulberry32).
15+
* Fisher-Yates shuffle algorithm.
1616
*/
17-
function seededRandom(seed: number): () => number {
18-
return () => {
19-
let t = (seed += 0x6d2b79f5);
20-
t = Math.imul(t ^ (t >>> 15), t | 1);
21-
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
22-
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
23-
};
24-
}
25-
26-
/**
27-
* Fisher-Yates shuffle algorithm with optional seed for deterministic results.
28-
*/
29-
function shuffleArray<T>(array: T[], seed?: number): T[] {
17+
function shuffleArray<T>(array: T[]): T[] {
3018
const shuffled = [...array];
31-
const random = seed !== undefined ? seededRandom(seed) : Math.random;
3219
for (let i = shuffled.length - 1; i > 0; i--) {
33-
const j = Math.floor(random() * (i + 1));
20+
const j = Math.floor(Math.random() * (i + 1));
3421
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
3522
}
3623
return shuffled;
3724
}
3825

39-
/**
40-
* Generate a hash from filter state for deterministic shuffle.
41-
*/
42-
function hashFilters(filters: ActiveFilters): number {
43-
const str = JSON.stringify(filters);
44-
let hash = 0;
45-
for (let i = 0; i < str.length; i++) {
46-
const char = str.charCodeAt(i);
47-
hash = (hash << 5) - hash + char;
48-
hash = hash & hash;
49-
}
50-
return Math.abs(hash);
51-
}
52-
5326
/**
5427
* Parse URL params into ActiveFilters.
5528
* URL format: ?lib=matplotlib&lib=seaborn (AND) or ?lib=matplotlib,seaborn (OR within group)
@@ -349,9 +322,8 @@ export function useFilterState({
349322
setGlobalCounts(data.globalCounts || data.counts);
350323
setOrCounts(data.orCounts || []);
351324

352-
// Shuffle with deterministic seed based on filters
353-
const seed = hashFilters(activeFilters);
354-
const shuffled = shuffleArray<PlotImage>(data.images || [], seed);
325+
// Shuffle images randomly on each load
326+
const shuffled = shuffleArray<PlotImage>(data.images || []);
355327
setAllImages(shuffled);
356328

357329
// Initial display count

0 commit comments

Comments
 (0)