-
Notifications
You must be signed in to change notification settings - Fork 18
fix(ui): add bigint display support #394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
09925c7
6763e3e
baa31db
2b656ed
d2988be
b96e14b
c7e14bc
21a1624
8d7928b
585b881
e2668be
3134b5b
f56f563
f1fa48a
ec4c3f0
d80986b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,13 @@ | ||
| // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| import { inferFieldFormatter } from '@quent/utils'; | ||
| import { inferFieldFormatter, isNumericValue } from '@quent/utils'; | ||
| import type { StatValue, ContinuousPaletteName } from '@quent/utils'; | ||
| import { continuousColor } from '@quent/utils'; | ||
|
|
||
| // Re-exported for consumers that still import it from here; defined in `@quent/utils` | ||
| export { isNumericValue }; | ||
|
|
||
| import type { | ||
| StatGroupExpandedRow, | ||
| GroupKeyEntry, | ||
|
|
@@ -23,7 +27,7 @@ export interface GroupIndexDef { | |
| getLabel: (row: StatGroupExpandedRow) => string; | ||
| } | ||
|
|
||
| export function formatNumericStat(n: number | null, statName: string): string { | ||
| export function formatNumericStat(n: number | bigint | null, statName: string): string { | ||
| if (n === null) return '-'; | ||
| return inferFieldFormatter(statName)(n); | ||
| } | ||
|
|
@@ -43,16 +47,12 @@ export function itemHasId(items: Iterable<string>, target: ReadonlySet<string>): | |
|
|
||
| export function formatStatValue(value: StatValue, statName: string): string { | ||
| if (value === null || value === undefined) return '-'; | ||
| if (typeof value === 'number') return formatNumericStat(value, statName); | ||
| if (isNumericValue(value)) return formatNumericStat(value, statName); | ||
| if (typeof value === 'boolean') return value ? 'true' : 'false'; | ||
| if (Array.isArray(value)) return value.join(', '); | ||
| return String(value); | ||
| } | ||
|
|
||
| export function isNumericValue(v: StatValue): v is number { | ||
| return typeof v === 'number'; | ||
| } | ||
|
|
||
| // --- color gradient --- | ||
|
|
||
| export function gradientBg( | ||
|
|
@@ -173,7 +173,7 @@ export function getSortValue( | |
| if (!isAgg) { | ||
| const v = row.values.get(stat); | ||
| if (v === undefined) return null; | ||
| return isNumericValue(v) ? v : null; | ||
| return isNumericValue(v) ? Number(v) : null; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== file outline =="
ast-grep outline ui/packages/@quent/components/src/pivot-table/utils.ts --view expanded || true
echo
echo "== relevant lines =="
sed -n '140,310p' ui/packages/@quent/components/src/pivot-table/utils.ts
echo
echo "== search for isNumericValue and related callers =="
rg -n "isNumericValue|parseJsonWithBigInt|Number\\(v\\)|pivot-table" ui/packages/@quent/components/src -SRepository: rapidsai/quent Length of output: 10680 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== utils.ts around numeric formatting and aggregation =="
sed -n '1,140p' ui/packages/@quent/components/src/pivot-table/utils.ts
sed -n '240,290p' ui/packages/@quent/components/src/pivot-table/utils.ts
echo
echo "== pivot-table types =="
sed -n '1,220p' ui/packages/@quent/components/src/pivot-table/types.ts
echo
echo "== search for StatValue and isNumericValue definitions =="
rg -n "type StatValue|interface StatValue|export .*isNumericValue|function isNumericValue|const isNumericValue" ui/packages/@quent -SRepository: rapidsai/quent Length of output: 11009 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== isNumericValue / formatter definitions in `@quent/utils` =="
rg -n "export .*isNumericValue|function isNumericValue|const isNumericValue|inferFieldFormatter|format.*bigint|StatValue" ui/packages/@quent/utils/src -S
echo
echo "== candidate files =="
fd -a "dagTypes.ts|.*utils.*" ui/packages/@quent/utils/src
echo
echo "== relevant source snippets =="
sed -n '1,140p' ui/packages/@quent/utils/src/dagTypes.ts
sed -n '1,220p' ui/packages/@quent/utils/src/index.tsRepository: rapidsai/quent Length of output: 8520 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== getSortValue usages =="
rg -n "getSortValue\\(" ui/packages/@quent/components/src -S
echo
echo "== sort logic around pivoted rows =="
rg -n "sortInfo|compare|localeCompare|getSortValue|aggMode" ui/packages/@quent/components/src/pivot-table -S
echo
echo "== relevant chunks from pivot-table components =="
sed -n '1,260p' ui/packages/@quent/components/src/pivot-table/GroupedDataTable.tsx
sed -n '1,260p' ui/packages/@quent/components/src/pivot-table/PivotedStatTable.tsxRepository: rapidsai/quent Length of output: 26159 Keep pivot-table stats as bigint through sort and aggregation 🤖 Prompt for AI AgentsSource: Path instructions
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This too, but if you want I can go back and do the pivot table stuff There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol, comment intended for @cmatzenbach
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @johallar Ok, just pushed up a fix for this
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, I see the agg fixes, but the line that this comment is on will still affect sorting won't it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah right, should've mentioned it - I was thinking we could address this in a follow-up PR, as that would require cascading changes to
I'm not quite sure how large those changes would be, so I thought keeping it separate might make sense.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 that works! Let's just track in an issue so we don't lose track of it
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done - logged in #475 |
||
| } | ||
| const agg = row.aggs.get(stat); | ||
| if (!agg || !agg.isNumeric) return null; | ||
|
|
@@ -197,7 +197,7 @@ type Accumulator = { | |
| keys: GroupKeyEntry[]; | ||
| rowKey: string; | ||
| values: Map<string, StatValue>; | ||
| aggBuckets: Map<string, { nums: number[]; count: number }>; | ||
| aggBuckets: Map<string, { nums: number[]; bigints: bigint[]; count: number }>; | ||
| itemIds: Set<string>; | ||
| itemScopeIds: Map<string, string>; | ||
| itemType: string; | ||
|
|
@@ -251,11 +251,13 @@ export function buildPivotedRows( | |
| } else { | ||
| let bucket = group.aggBuckets.get(row.statisticName); | ||
| if (!bucket) { | ||
| bucket = { nums: [], count: 0 }; | ||
| bucket = { nums: [], bigints: [], count: 0 }; | ||
| group.aggBuckets.set(row.statisticName, bucket); | ||
| } | ||
| bucket.count++; | ||
| if (isNumericValue(row.value)) { | ||
| if (typeof row.value === 'bigint') { | ||
| bucket.bigints.push(row.value); | ||
| } else if (typeof row.value === 'number') { | ||
| bucket.nums.push(row.value); | ||
| } | ||
| } | ||
|
|
@@ -266,17 +268,37 @@ export function buildPivotedRows( | |
| const aggs = new Map<string, PivotedRowAgg>(); | ||
| if (isAggregating) { | ||
| for (const [stat, bucket] of group.aggBuckets) { | ||
| const hasNum = bucket.nums.length > 0; | ||
| const sum = hasNum ? bucket.nums.reduce((a, b) => a + b, 0) : null; | ||
| const mean = hasNum ? sum! / bucket.nums.length : null; | ||
| const min = hasNum ? Math.min(...bucket.nums) : null; | ||
| const max = hasNum ? Math.max(...bucket.nums) : null; | ||
| const onlyBigints = bucket.bigints.length > 0 && bucket.nums.length === 0; | ||
| const allNums = onlyBigints | ||
| ? bucket.bigints.map(Number) | ||
| : [...bucket.nums, ...bucket.bigints.map(Number)]; | ||
| const hasNum = allNums.length > 0; | ||
|
|
||
| let sum: number | null = null; | ||
| let min: number | null = null; | ||
| let max: number | null = null; | ||
| let mean: number | null = null; | ||
| let stdev: number | null = null; | ||
| if (mean !== null && bucket.nums.length > 1) { | ||
| const variance = | ||
| bucket.nums.reduce((acc, v) => acc + (v - mean) ** 2, 0) / (bucket.nums.length - 1); | ||
| stdev = Math.sqrt(variance); | ||
|
|
||
| if (hasNum) { | ||
| if (onlyBigints) { | ||
| // Use bigint arithmetic for sum/min/max to avoid precision loss | ||
| sum = Number(bucket.bigints.reduce((a, b) => a + b, 0n)); | ||
| min = Number(bucket.bigints.reduce((a, b) => (a < b ? a : b))); | ||
| max = Number(bucket.bigints.reduce((a, b) => (a > b ? a : b))); | ||
| } else { | ||
| sum = allNums.reduce((a, b) => a + b, 0); | ||
| min = Math.min(...allNums); | ||
| max = Math.max(...allNums); | ||
| } | ||
| mean = sum / allNums.length; | ||
| if (allNums.length > 1) { | ||
| const variance = | ||
| allNums.reduce((acc, v) => acc + (v - mean!) ** 2, 0) / (allNums.length - 1); | ||
| stdev = Math.sqrt(variance); | ||
| } | ||
| } | ||
|
|
||
| aggs.set(stat, { sum, mean, min, max, stdev, count: bucket.count, isNumeric: hasNum }); | ||
| } | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.