我试图用一个自定义按键功能.data()与.selectAll()在D3的选择。但是,让它兼容 TypeScript 变得如此痛苦。
如果没有 key 函数,元素将不会被正确删除,因为默认情况下 D3 使用索引来检查更新。
所以,这是JavaScript代码片段,按预期工作正常:
const circles = svg
.select("g")
.selectAll("circle")
.data(data, d => d.val);
Run Code Online (Sandbox Code Playgroud)
用TypeScript尝试同样的方法,
interface IData {
val: number;
}
Run Code Online (Sandbox Code Playgroud)
尝试 1
const circles = svg
.select("g")
.selectAll("circle")
.data<IData>(data, (d) => d.val);
Run Code Online (Sandbox Code Playgroud)
Object d is of type 'unknown'. TS2571
35 | .select("g")
36 | .selectAll("circle")
> 37 | .data<IData>(data, (d) => d.val);
Run Code Online (Sandbox Code Playgroud)
尝试 2
Object d is of type 'unknown'. TS2571
35 | .select("g")
36 | .selectAll("circle")
> 37 | .data<IData>(data, (d) => d.val);
Run Code Online (Sandbox Code Playgroud)
No overload matches this call.
Overload 1 of 3, '(data: IData[], key?: ValueFn<SVGSVGElement | Element | EnterElement | Document | Window | null, IData, string> | undefined): Selection<...>', gave the following error.
Argument of type '(this: SVGSVGElement | Element | EnterElement | Document | Window | null, d: IData) => number' is not assignable to parameter of type 'ValueFn<SVGSVGElement | Element | EnterElement | Document | Window | null, IData, string>'.
Type 'number' is not assignable to type 'string'.
Overload 2 of 3, '(data: ValueFn<BaseType, unknown, IData[]>, key?: ValueFn<SVGSVGElement | Element | EnterElement | Document | Window | null, IData, string> | undefined): Selection<...>', gave the following error.
Argument of type 'IData[]' is not assignable to parameter of type 'ValueFn<BaseType, unknown, IData[]>'.
Type 'IData[]' provides no match for the signature '(this: BaseType, datum: unknown, index: number, groups: BaseType[] | ArrayLike<BaseType>): IData[]'. TS2769
Run Code Online (Sandbox Code Playgroud)
而且,如果没有数据的关键功能,一切都可以正常工作:
const circles = svg
.select("g")
.selectAll<SVGSVGElement, IData>("circle")
.data<IData>(data, (d) => d.val);
Run Code Online (Sandbox Code Playgroud)
从文档中可以看出,关键函数需要返回一个字符串(重点是我的):
通过计算每个数据和元素的字符串标识符,可以指定一个键函数来控制将哪个数据分配给哪个元素,替换默认的按索引连接。
这也可以通过查看看出类型定义为selection.data():
data<NewDatum>(data: NewDatum[], key?: ValueFn<GElement | PElement, Datum | NewDatum, string>): Selection<GElement, NewDatum, PElement, PDatum>;
Run Code Online (Sandbox Code Playgroud)
这里的关键函数定义为
key?: ValueFn<GElement | PElement, Datum | NewDatum, string>
Run Code Online (Sandbox Code Playgroud)
与ValueFn类型为
export type ValueFn<T extends BaseType, Datum, Result> = (this: T, datum: Datum, index: number, groups: T[] | ArrayLike<T>) => Result;
Run Code Online (Sandbox Code Playgroud)
看上面两个定义不难看出,Resultkey函数定义的type参数设置为string,这就是你编译出错的原因。
从您的键函数返回一个字符串将解决这个问题:
.data(data, d => "" + d.val);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
435 次 |
| 最近记录: |