Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import { Button } from '$lib/components';
import Typography from '$lib/components/Typography/Typography.svelte';
import { Select, type SelectItem } from '$lib/components/Select';
import { BarChart, type CategoryCount } from '$lib/components/BarChart';
import {
BarChart,
type CategoryCount,
type CategoryCountSeries
} from '$lib/components/BarChart';
import { Histogram, type HistogramRange } from '$lib/components/Histogram';
import { formatFloat, formatInteger } from '$lib/utils';
import DistributionConfigDialog from './DistributionConfigDialog/DistributionConfigDialog.svelte';
Expand Down Expand Up @@ -115,7 +119,30 @@
activeSource.groups?.find(groupHasContent) ??
activeSource.groups?.[0]
);
const activeData = $derived<CategoryCount[]>(activeGroup?.data ?? activeSource.data ?? []);
const activeSingleSeriesData = $derived<CategoryCount[]>(
activeGroup?.data ?? activeSource.data ?? []
);
const activeComparisonData = $derived(
activeGroup?.comparisonData ?? activeSource.comparisonData ?? []
);
const activeSeries = $derived<CategoryCountSeries[]>(
activeComparisonData.map((tag) => ({
id: tag.sample_tag_id,
label: tag.sample_tag_name,
data: tag.counts.map((item) => ({ label: item.label_name, count: item.count }))
}))
);
// Rank the shared axis by the aggregate across tags; individual series stay independent.
const activeData = $derived.by<CategoryCount[]>(() => {
if (activeSeries.length === 0) return activeSingleSeriesData;
const totals = new Map<string, number>();
for (const series of activeSeries) {
for (const item of series.data) {
totals.set(item.label, (totals.get(item.label) ?? 0) + item.count);
}
}
return [...totals].map(([label, count]) => ({ label, count }));
});
// A group/source carrying bins renders as a histogram instead of a bar
// chart; the categorical controls (sort, top-N, orientation) don't apply.
const activeHistogram = $derived(activeGroup?.histogram ?? activeSource.histogram ?? null);
Expand Down Expand Up @@ -164,6 +191,13 @@
);

const visible = $derived(selectVisibleCounts(activeData, config));
const visibleLabels = $derived(new Set(visible.map((item) => item.label)));
const visibleSeries = $derived(
activeSeries.map((series) => ({
...series,
data: series.data.filter((item) => visibleLabels.has(item.label))
}))
);
const totalCount = $derived(activeData.reduce((sum, item) => sum + item.count, 0));

function applyConfig(next: DistributionConfig) {
Expand Down Expand Up @@ -284,7 +318,8 @@
{config}
classCount={activeData.length}
visibleClassCount={visible.length}
totalCount={showTotalCount ? totalCount : undefined}
totalCount={showTotalCount && activeSeries.length === 0 ? totalCount : undefined}
seriesCount={activeSeries.length || undefined}
{valueNoun}
onConfigure={() => (configDialogOpen = true)}
onShowAll={() => (config = { ...config, mode: 'topN', n: activeData.length })}
Expand Down Expand Up @@ -316,6 +351,7 @@
maxHeightPx={chartHeight || undefined}
maxWidthPx={clientWidth || undefined}
{totalCount}
series={visibleSeries}
{onBarClick}
/>
{/if}
Expand All @@ -330,6 +366,7 @@
<ExpandDialog
bind:open={expandOpen}
data={activeData}
series={activeSeries}
{config}
{valueNoun}
onConfigChange={applyConfig}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<script lang="ts">
import * as Dialog from '$lib/components/ui/dialog';
import { BarChart, type CategoryCount } from '$lib/components/BarChart';
import {
BarChart,
type CategoryCount,
type CategoryCountSeries
} from '$lib/components/BarChart';
import DistributionConfigDialog from '../DistributionConfigDialog/DistributionConfigDialog.svelte';
import PanelHeader from '../PanelHeader/PanelHeader.svelte';
import { selectVisibleCounts } from '../selectVisibleCounts';
Expand All @@ -11,6 +15,8 @@
open: boolean;
/** Full class counts; the dialog applies `config` itself. */
data: CategoryCount[];
/** Optional comparison series rendered on the shared class axis. */
series?: CategoryCountSeries[];
/** The applied view config, shared with the panel. */
config: DistributionConfig;
/** Noun for the header summary (e.g. 'annotations', 'samples'). */
Expand All @@ -23,6 +29,7 @@
let {
open = $bindable(),
data,
series = [],
config,
valueNoun = 'annotations',
onConfigChange,
Expand All @@ -36,6 +43,13 @@
let clientWidth = $state(0);

const visible = $derived(selectVisibleCounts(data, config));
const visibleLabels = $derived(new Set(visible.map((item) => item.label)));
const visibleSeries = $derived(
series.map((item) => ({
...item,
data: item.data.filter((count) => visibleLabels.has(count.label))
}))
);
const totalCount = $derived(data.reduce((sum, item) => sum + item.count, 0));
</script>

Expand All @@ -49,7 +63,8 @@
{config}
classCount={data.length}
visibleClassCount={visible.length}
{totalCount}
totalCount={series.length === 0 ? totalCount : undefined}
seriesCount={series.length || undefined}
{valueNoun}
onConfigure={() => (configDialogOpen = true)}
onShowAll={() => onConfigChange({ ...config, mode: 'topN', n: data.length })}
Expand All @@ -70,6 +85,7 @@
maxHeightPx={chartHeight || undefined}
maxWidthPx={clientWidth || undefined}
{totalCount}
series={visibleSeries}
{onBarClick}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
visibleClassCount: number;
/** Sum of counts across all classes, for the summary line. Omit to hide the count. */
totalCount?: number;
/** Number of compared sample-tag series; shown instead of a combined count. */
seriesCount?: number;
/** Noun for the total count summary (e.g. 'annotations', 'samples'). */
valueNoun?: string;
/** Opens the view-config dialog (top-N and sort order). */
Expand All @@ -36,6 +38,7 @@
classCount,
visibleClassCount,
totalCount,
seriesCount,
valueNoun = 'annotations',
onConfigure,
onShowAll,
Expand All @@ -59,6 +62,9 @@
· {totalCount.toLocaleString('en-US')}
{valueNoun}
{/if}
{#if seriesCount !== undefined}
· {seriesCount} sample {seriesCount === 1 ? 'tag' : 'tags'}
{/if}
{#if onShowAll && visibleClassCount < classCount}
·
<button
Expand Down