Browse Source

Add tag display improvements and sorting controls

- Change minEventCount to 1 to display all tags regardless of occurrence count
- Add radio buttons to sort tags by count (default) or alphabetically
- Add "Invert Selection" checkbox to toggle all tags at once
- Fix tag sorting implementation with proper Svelte @const placement

These changes provide better control over tag visibility and organization,
making it easier to explore and filter the visualization by tags.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
master
limina1 9 months ago
parent
commit
5195eb18d6
  1. 52
      src/lib/navigator/EventNetwork/Legend.svelte
  2. 5
      src/lib/navigator/EventNetwork/utils/tagNetworkBuilder.ts

52
src/lib/navigator/EventNetwork/Legend.svelte

@ -56,6 +56,7 @@ @@ -56,6 +56,7 @@
let tagAnchorsExpanded = $state(true);
let tagControlsExpanded = $state(true);
let personVisualizerExpanded = $state(true);
let tagSortMode = $state<'count' | 'alphabetical'>('count');
$effect(() => {
if (collapsedOnInteraction) {
@ -244,16 +245,65 @@ @@ -244,16 +245,65 @@
</div>
{#if tagAnchorsExpanded}
{@const sortedAnchors = tagSortMode === 'count'
? [...tagAnchors].sort((a, b) => b.count - a.count)
: [...tagAnchors].sort((a, b) => a.label.localeCompare(b.label))
}
{#if autoDisabledTags}
<div class="text-xs text-amber-600 dark:text-amber-400 mb-2 p-2 bg-amber-50 dark:bg-amber-900/20 rounded">
<strong>Note:</strong> All {tagAnchors.length} tags were auto-disabled to prevent graph overload. Click individual tags below to enable them.
</div>
{/if}
<!-- Sort options and controls -->
<div class="flex items-center justify-between gap-4 mb-3">
<div class="flex items-center gap-4">
<span class="text-xs text-gray-600 dark:text-gray-400">Sort by:</span>
<label class="flex items-center gap-1 cursor-pointer">
<input
type="radio"
name="tagSort"
value="count"
bind:group={tagSortMode}
class="w-3 h-3"
/>
<span class="text-xs">Count</span>
</label>
<label class="flex items-center gap-1 cursor-pointer">
<input
type="radio"
name="tagSort"
value="alphabetical"
bind:group={tagSortMode}
class="w-3 h-3"
/>
<span class="text-xs">Alphabetical</span>
</label>
</div>
<label class="flex items-center gap-1 cursor-pointer">
<input
type="checkbox"
onclick={() => {
// Invert selection - toggle all tags one by one
const allTagIds = tagAnchors.map(anchor => `${anchor.type}-${anchor.label}`);
// Process all tags
allTagIds.forEach(tagId => {
onTagToggle(tagId);
});
}}
class="w-3 h-3"
/>
<span class="text-xs">Invert Selection</span>
</label>
</div>
<div
class="tag-grid {tagAnchors.length > 20 ? 'scrollable' : ''}"
style="grid-template-columns: repeat({TAG_LEGEND_COLUMNS}, 1fr);"
>
{#each tagAnchors as anchor}
{#each sortedAnchors as anchor}
{@const tagId = `${anchor.type}-${anchor.label}`}
{@const isDisabled = disabledTags.has(tagId)}
<button

5
src/lib/navigator/EventNetwork/utils/tagNetworkBuilder.ts

@ -115,9 +115,8 @@ export function createTagAnchorNodes( @@ -115,9 +115,8 @@ export function createTagAnchorNodes(
const anchorNodes: NetworkNode[] = [];
// Calculate positions for tag anchors randomly within radius
// For single publication view, show all tags. For network view, only show tags with 2+ events
// Exception: for "p" tags, always use minEventCount of 1 to show all people
const minEventCount = tagType === "p" ? 1 : (tagMap.size <= 10 ? 1 : 2);
// Show all tags regardless of how many events they appear in
const minEventCount = 1;
let validTags = Array.from(tagMap.entries()).filter(
([_, eventIds]) => eventIds.size >= minEventCount,
);

Loading…
Cancel
Save