Skip to content

fix(web): kb recall top_k max#1297

Merged
shuqinzhao merged 1 commit into
release/v0.3.6from
fix/v0.3.6_zy
Jun 2, 2026
Merged

fix(web): kb recall top_k max#1297
shuqinzhao merged 1 commit into
release/v0.3.6from
fix/v0.3.6_zy

Conversation

@shuqinzhao
Copy link
Copy Markdown
Collaborator

@shuqinzhao shuqinzhao commented Jun 2, 2026

Summary by Sourcery

改进图形节点标签渲染,并收紧知识库召回参数限制。

Bug 修复:

  • 将知识库召回的 top_k 输入最大值从 1024 限制为 100,以符合预期限制。

改进:

  • 优化图网络节点标签样式:根据节点大小动态调整字体大小、居中对齐、支持多行换行,并在空间不足时使用省略号截断显示。
Original summary in English

Summary by Sourcery

Improve graph node label rendering and tighten knowledge base recall parameter limits.

Bug Fixes:

  • Restrict knowledge base recall top_k input to a maximum of 100 instead of 1024 to match intended limits.

Enhancements:

  • Refine graph network node label styling with dynamic font sizing, centered alignment, multiline wrapping, and truncation with ellipsis based on node size.

@shuqinzhao shuqinzhao merged commit b1fa4b5 into release/v0.3.6 Jun 2, 2026
2 checks passed
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Jun 2, 2026

审查者指南

调整网络图中图节点标签的渲染方式以提升可读性,并将知识库召回测试的 top_k 输入上限限制为 100,同时更新校验逻辑和 UI 提示。

文件级变更

变更 详情 文件
改进 GraphNetworkChart 节点标签的渲染,支持动态尺寸和多行显示,并移除调试日志。
  • 移除遗留的图链接标签相关的 console 日志。
  • 调整节点标签的位置和锚点,使文本在节点内垂直和水平居中对齐。
  • 使节点标签字体大小依赖 node 的 symbolSize,并在可读性范围内进行钳制。
  • 简化节点标签可见性逻辑,改为基于 symbolSize 阈值,而不是通过字符串长度预估宽度。
  • 实现自定义文本布局,根据预估字符宽度、节点半径和最大行数将节点名称换行到多个 tspan 中,必要时使用省略号截断。
web/src/components/Charts/GraphNetworkChart.tsx
将知识库召回测试的 top_k 参数限制为最大 100,并使 UI 占位符与该限制保持一致。
  • 更新 InputNumber 的占位符文本,说明合法的 top_k 范围为 1–100。
  • 将 InputNumber 的最大值从 1024 改为 100,以在 UI 中强制执行新的上限。
web/src/views/KnowledgeBase/components/RecallTest.tsx

使用技巧和命令

与 Sourcery 交互

  • 触发新的审查: 在拉取请求中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub issue: 回复审查评论,请求 Sourcery 从该评论创建 issue。你也可以回复审查评论并使用 @sourcery-ai issue 来从该评论创建 issue。
  • 生成拉取请求标题: 在拉取请求标题中任意位置写入 @sourcery-ai 即可随时生成标题。你也可以在拉取请求中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成拉取请求摘要: 在拉取请求正文中任意位置写入 @sourcery-ai summary,即可在你希望的位置生成 PR 摘要。你也可以在拉取请求中评论 @sourcery-ai summary 来在任意时间(重新)生成摘要。
  • 生成审查者指南: 在拉取请求中评论 @sourcery-ai guide,即可在任意时间(重新)生成审查者指南。
  • 解决所有 Sourcery 评论: 在拉取请求中评论 @sourcery-ai resolve,以解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 关闭所有 Sourcery 审查: 在拉取请求中评论 @sourcery-ai dismiss,以关闭所有现有的 Sourcery 审查。如果你想重新开始一次新的审查,这尤其有用——别忘了再评论 @sourcery-ai review 来触发新的审查!

自定义你的使用体验

访问你的 dashboard 以:

  • 启用或禁用审查功能,例如 Sourcery 自动生成的拉取请求摘要、审查者指南等。
  • 更改审查语言。
  • 添加、移除或编辑自定义审查指令。
  • 调整其他审查相关设置。

获取帮助

Original review guide in English

Reviewer's Guide

Adjusts graph node label rendering for better readability in the network chart and caps the knowledge base recall test top_k input to 100, updating both validation and UI hints.

File-Level Changes

Change Details Files
Improve GraphNetworkChart node label rendering with dynamic sizing and multiline support while removing debug logging.
  • Remove leftover console logging for graph link labels.
  • Change node label positioning and anchoring to center text vertically and horizontally within the node.
  • Make node label font size depend on node symbolSize with clamped bounds for readability.
  • Simplify node label visibility logic to use a symbolSize threshold instead of string-length-based width estimation.
  • Implement custom text layout that wraps node names into multiple tspans based on estimated character width, node radius, and maximum lines, truncating with ellipsis when necessary.
web/src/components/Charts/GraphNetworkChart.tsx
Restrict Knowledge Base recall test top_k parameter to a maximum of 100 and align UI placeholder with this limit.
  • Update the InputNumber placeholder text to indicate the valid top_k range is 1–100.
  • Change the InputNumber max value from 1024 to 100 to enforce the new upper bound in the UI.
web/src/views/KnowledgeBase/components/RecallTest.tsx

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@shuqinzhao shuqinzhao deleted the fix/v0.3.6_zy branch June 2, 2026 02:38
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:

  • GraphNetworkChart 中的自动换行逻辑使用了若干“魔法数字”(例如 0.251.20.5520)——建议把这些提取成具名常量,以便更容易理解和调整尺寸相关行为。
  • 目前基于字符的宽度估算(charWidth = fontSize * 0.55 并按每个字符拆分)在非拉丁字符集或 emoji 上可能表现不佳;建议使用真实的文本测量方式(例如 getComputedTextLength),或者至少在可能的情况下按单词/字素(grapheme)拆分。
  • 针对每个节点的 .each 文本布局处理会在每次渲染时运行,在图很大时可能会变得昂贵;可以考虑对布局做缓存,或者只对大小/名称发生变化的节点重新计算。
给 AI Agent 的提示词
Please address the comments from this code review:

## Overall Comments
- The text-wrapping logic in `GraphNetworkChart` uses several magic numbers (e.g., `0.25`, `1.2`, `0.55`, `20`)—consider extracting these into named constants to make the sizing behavior easier to understand and tune.
- The character-based width approximation (`charWidth = fontSize * 0.55` and splitting on every character) may behave poorly for non-Latin scripts or emoji; consider using actual text measurement (e.g., `getComputedTextLength`) or at least splitting on words/graphemes where possible.
- The per-node `.each` text layout work runs for every render and may become expensive for large graphs; consider memoizing layout or limiting recomputation to nodes whose size/name changed.

## Individual Comments

### Comment 1
<location path="web/src/components/Charts/GraphNetworkChart.tsx" line_range="330-331" />
<code_context>
       .attr('text-anchor', 'middle')
-      .attr('font-size', '10px')
+      .attr('dominant-baseline', 'middle')
+      .attr('font-size', d => {
+        const fontSize = Math.max(6, Math.min(12, d.symbolSize * 0.25))
+        return `${fontSize}px`
+      })
</code_context>
<issue_to_address>
**suggestion:** Avoid recomputing fontSize in both the attribute and the wrapping logic to keep them in sync and slightly reduce work.

The `fontSize` logic here is duplicated in the `.each` handler below, which risks the two paths diverging and making wrapping vs. rendered size hard to reason about. Please refactor to a single source of truth (e.g., compute once in the attr callback and store on the datum, or read the computed value from the element in `.each`).

Suggested implementation:

```typescript
    nodeSel.append('text')
      .attr('x', 0)
      .attr('y', 0)
      .attr('text-anchor', 'middle')
      .attr('dominant-baseline', 'middle')
      .attr('font-size', d => {
        const fontSize = Math.max(6, Math.min(12, d.symbolSize * 0.25))
        // store on datum so wrapping logic can reuse without recomputing
        ;(d as any).labelFontSize = fontSize
        return `${fontSize}px`
      })

```

Somewhere below this snippet, you likely have a `.each` handler that performs text wrapping and currently recomputes the font size using the same `Math.max(6, Math.min(12, d.symbolSize * 0.25))` logic.

Refactor that handler to read the value we just stored instead of recomputing it, e.g.:

```ts
selection
  .each(function (d) {
    const fontSize =
      (d as any).labelFontSize ??
      Math.max(6, Math.min(12, d.symbolSize * 0.25)) // optional fallback if needed
    // use `fontSize` for wrapping logic instead of recomputing
  })
```

You should:
1. Remove the duplicated `Math.max(6, Math.min(12, d.symbolSize * 0.25))` expression in the `.each` block.
2. Replace it with reading `(d as any).labelFontSize` (or use a stronger type if your node datum type can be extended).
3. Optionally keep the fallback to preserve behavior for any text elements that might not have gone through the `nodeSel.append('text')` path.
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得这次 Review 有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的 Review。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The text-wrapping logic in GraphNetworkChart uses several magic numbers (e.g., 0.25, 1.2, 0.55, 20)—consider extracting these into named constants to make the sizing behavior easier to understand and tune.
  • The character-based width approximation (charWidth = fontSize * 0.55 and splitting on every character) may behave poorly for non-Latin scripts or emoji; consider using actual text measurement (e.g., getComputedTextLength) or at least splitting on words/graphemes where possible.
  • The per-node .each text layout work runs for every render and may become expensive for large graphs; consider memoizing layout or limiting recomputation to nodes whose size/name changed.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The text-wrapping logic in `GraphNetworkChart` uses several magic numbers (e.g., `0.25`, `1.2`, `0.55`, `20`)—consider extracting these into named constants to make the sizing behavior easier to understand and tune.
- The character-based width approximation (`charWidth = fontSize * 0.55` and splitting on every character) may behave poorly for non-Latin scripts or emoji; consider using actual text measurement (e.g., `getComputedTextLength`) or at least splitting on words/graphemes where possible.
- The per-node `.each` text layout work runs for every render and may become expensive for large graphs; consider memoizing layout or limiting recomputation to nodes whose size/name changed.

## Individual Comments

### Comment 1
<location path="web/src/components/Charts/GraphNetworkChart.tsx" line_range="330-331" />
<code_context>
       .attr('text-anchor', 'middle')
-      .attr('font-size', '10px')
+      .attr('dominant-baseline', 'middle')
+      .attr('font-size', d => {
+        const fontSize = Math.max(6, Math.min(12, d.symbolSize * 0.25))
+        return `${fontSize}px`
+      })
</code_context>
<issue_to_address>
**suggestion:** Avoid recomputing fontSize in both the attribute and the wrapping logic to keep them in sync and slightly reduce work.

The `fontSize` logic here is duplicated in the `.each` handler below, which risks the two paths diverging and making wrapping vs. rendered size hard to reason about. Please refactor to a single source of truth (e.g., compute once in the attr callback and store on the datum, or read the computed value from the element in `.each`).

Suggested implementation:

```typescript
    nodeSel.append('text')
      .attr('x', 0)
      .attr('y', 0)
      .attr('text-anchor', 'middle')
      .attr('dominant-baseline', 'middle')
      .attr('font-size', d => {
        const fontSize = Math.max(6, Math.min(12, d.symbolSize * 0.25))
        // store on datum so wrapping logic can reuse without recomputing
        ;(d as any).labelFontSize = fontSize
        return `${fontSize}px`
      })

```

Somewhere below this snippet, you likely have a `.each` handler that performs text wrapping and currently recomputes the font size using the same `Math.max(6, Math.min(12, d.symbolSize * 0.25))` logic.

Refactor that handler to read the value we just stored instead of recomputing it, e.g.:

```ts
selection
  .each(function (d) {
    const fontSize =
      (d as any).labelFontSize ??
      Math.max(6, Math.min(12, d.symbolSize * 0.25)) // optional fallback if needed
    // use `fontSize` for wrapping logic instead of recomputing
  })
```

You should:
1. Remove the duplicated `Math.max(6, Math.min(12, d.symbolSize * 0.25))` expression in the `.each` block.
2. Replace it with reading `(d as any).labelFontSize` (or use a stronger type if your node datum type can be extended).
3. Optionally keep the fallback to preserve behavior for any text elements that might not have gone through the `nodeSel.append('text')` path.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +330 to +331
.attr('font-size', d => {
const fontSize = Math.max(6, Math.min(12, d.symbolSize * 0.25))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: 避免在属性设置和换行逻辑中重复计算 fontSize,这样既能保持两者一致,又能稍微减少一些计算工作。

这里的 fontSize 逻辑在下面的 .each 处理函数中又写了一遍,这会带来两个路径行为不一致的风险,从而让“换行效果”和“实际渲染的字号”变得难以推理。请重构为单一数据源(例如:在 attr 回调里计算一次并存到 datum 上,或者在 .each 中从元素上读取已计算好的值)。

建议实现方式:

    nodeSel.append('text')
      .attr('x', 0)
      .attr('y', 0)
      .attr('text-anchor', 'middle')
      .attr('dominant-baseline', 'middle')
      .attr('font-size', d => {
        const fontSize = Math.max(6, Math.min(12, d.symbolSize * 0.25))
        // store on datum so wrapping logic can reuse without recomputing
        ;(d as any).labelFontSize = fontSize
        return `${fontSize}px`
      })

在这段代码下面,你很可能有一个负责文本换行的 .each 处理函数,目前会使用相同的 Math.max(6, Math.min(12, d.symbolSize * 0.25)) 逻辑再次计算字号。

请重构该处理函数,让它读取我们刚才存储的值,而不是重新计算,例如:

selection
  .each(function (d) {
    const fontSize =
      (d as any).labelFontSize ??
      Math.max(6, Math.min(12, d.symbolSize * 0.25)) // optional fallback if needed
    // use `fontSize` for wrapping logic instead of recomputing
  })

你应该:

  1. 删除 .each 代码块中重复的 Math.max(6, Math.min(12, d.symbolSize * 0.25)) 表达式。
  2. 改为读取 (d as any).labelFontSize(如果你的节点数据类型可以扩展,也可以使用更强类型的方式)。
  3. 可以保留这个回退逻辑,以保证那些没有走过 nodeSel.append('text') 路径的文本元素行为不变。
Original comment in English

suggestion: Avoid recomputing fontSize in both the attribute and the wrapping logic to keep them in sync and slightly reduce work.

The fontSize logic here is duplicated in the .each handler below, which risks the two paths diverging and making wrapping vs. rendered size hard to reason about. Please refactor to a single source of truth (e.g., compute once in the attr callback and store on the datum, or read the computed value from the element in .each).

Suggested implementation:

    nodeSel.append('text')
      .attr('x', 0)
      .attr('y', 0)
      .attr('text-anchor', 'middle')
      .attr('dominant-baseline', 'middle')
      .attr('font-size', d => {
        const fontSize = Math.max(6, Math.min(12, d.symbolSize * 0.25))
        // store on datum so wrapping logic can reuse without recomputing
        ;(d as any).labelFontSize = fontSize
        return `${fontSize}px`
      })

Somewhere below this snippet, you likely have a .each handler that performs text wrapping and currently recomputes the font size using the same Math.max(6, Math.min(12, d.symbolSize * 0.25)) logic.

Refactor that handler to read the value we just stored instead of recomputing it, e.g.:

selection
  .each(function (d) {
    const fontSize =
      (d as any).labelFontSize ??
      Math.max(6, Math.min(12, d.symbolSize * 0.25)) // optional fallback if needed
    // use `fontSize` for wrapping logic instead of recomputing
  })

You should:

  1. Remove the duplicated Math.max(6, Math.min(12, d.symbolSize * 0.25)) expression in the .each block.
  2. Replace it with reading (d as any).labelFontSize (or use a stronger type if your node datum type can be extended).
  3. Optionally keep the fallback to preserve behavior for any text elements that might not have gone through the nodeSel.append('text') path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant