Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[Bug] Focus guides: `url(#id)` paints ignore `idPrefix`

オープン 初心者向け
#211 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@getdownandcode がすでに取り組んでいます。

2026年10月13日 から。

  • #217 @getdownandcode による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
78/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
d3, typescript

調査の方向性

packages/charts-core/src/svg-renderer.ts の focusGuideRenderHooks と paint() の呼び出しから始めます。次に、resolvePaint が svg.ts と svg-surface.ts を通じてどのように渡されるかを追います。issue の再現手順に基づく回帰テストを追加し、pnpm vitest run で実行します。focus-guide の paint で url(#id) を使ったときに、idPrefix のスコープ内にあるリソース ID に解決されれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Version: @tanstack/charts 1.1.0 (57774e1). Split from #191 (section C) so it can be closed on its own.

With idPrefix set, mark paints such as fill: 'url(#fade)' resolve to the scoped resource id, but the same paint on a focus guide or crosshair is written verbatim and points at a resource that does not exist. This affects gradients today and <pattern> resources once PR #166 lands.

Why
Repro

Save as packages/charts-core/src/repro.test.ts, run pnpm vitest run packages/charts-core/src/repro.test.ts.

import { expect, it } from 'vitest'
import { scaleLinear } from 'd3-scale'
import { areaY } from './area'
import { crosshair } from './crosshair'
import { motion } from './motion'
import { createChartScene, defineChart } from './scene'

const make = (end: number, top: number) =>
  createChartScene(defineChart({
    marks: [
      areaY([{ x: 0, y: 1 }, { x: 1, y: top }, { x: 2, y: 2 }], { x: 'x', y: 'y', fill: 'url(#fade)' }),
      crosshair({ y: false, stroke: 'url(#fade)' }),
    ],
    scales: { x: { scale: scaleLinear().domain([0, 2]) }, y: { scale: scaleLinear().domain([0, 4]) } },
    gradients: [{ id: 'fade', stops: [
      { offset: 0, color: '#2563eb', opacity: 0.6 }, { offset: end, color: '#2563eb', opacity: 0 }] }],
  }), { width: 320, height: 200 })
const opts = { ariaLabel: 't', idPrefix: 'a' }

it('url(#id) in a focus-guide node is scoped by idPrefix', () => {
  const el = document.createElement('div')
  const surface = motion({ initial: false }).mount(el, () => {})
  const scene = make(1, 3)
  surface.render(scene, opts)
  const p = scene.points[0]!
  surface.paintFocus({ primary: p, group: [p], source: 'pointer', pinned: false })
  const rule = el.querySelector('[data-ts-focus-guide-layer] [data-ts-key$=":x-rule"]')!
  console.log('gradient id:', el.querySelector('linearGradient')?.id, '| guide stroke:', rule.getAttribute('stroke'))
  expect(rule.getAttribute('stroke')).toBe('url(#a-fade)')
})

Actual output:

gradient id: a-fade | guide stroke: url(#fade)
AssertionError: expected 'url(#fade)' to be 'url(#a-fade)'
Expected

Guide node paints resolve to the scoped id like mark paints. Proposal: pass resolvePaint into focusGuideRenderHooks and the renderer-based path (svg-surface.ts:326-327).

Related: #191 (gradient stops and units), #128 / PR #166 (<pattern> resources).

主要言語
TypeScript
スター
842
フォーク
53
平均マージ
4時間 40分
マージ済み PR(30日)
16

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

TanStack/charts のほかの issue

TanStack/charts の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。