(originData?: INode)
| 315 | } |
| 316 | |
| 317 | async renderData(originData?: INode) { |
| 318 | const { paddingX, autoFit, color, maxWidth, lineWidth } = this.options; |
| 319 | const rootNode = this.state.data; |
| 320 | if (!rootNode) return; |
| 321 | |
| 322 | const nodeMap: Record<number, INode> = {}; |
| 323 | const parentMap: Record<number, number> = {}; |
| 324 | const nodes: INode[] = []; |
| 325 | walkTree(rootNode, (item, next, parent) => { |
| 326 | if (!item.payload?.fold) next(); |
| 327 | nodeMap[item.state.id] = item; |
| 328 | if (parent) parentMap[item.state.id] = parent.state.id; |
| 329 | nodes.push(item); |
| 330 | }); |
| 331 | |
| 332 | const originMap: Record<number, number> = {}; |
| 333 | const sourceRectMap: Record< |
| 334 | number, |
| 335 | { x: number; y: number; width: number; height: number } |
| 336 | > = {}; |
| 337 | const setOriginNode = (originNode: INode | undefined) => { |
| 338 | if (!originNode || originMap[originNode.state.id]) return; |
| 339 | walkTree(originNode, (item, next) => { |
| 340 | originMap[item.state.id] = originNode.state.id; |
| 341 | next(); |
| 342 | }); |
| 343 | }; |
| 344 | const getOriginSourceRect = (node: INode) => { |
| 345 | const rect = sourceRectMap[originMap[node.state.id]]; |
| 346 | return rect || rootNode.state.rect; |
| 347 | }; |
| 348 | const getOriginTargetRect = (node: INode) => |
| 349 | (nodeMap[originMap[node.state.id]] || rootNode).state.rect; |
| 350 | sourceRectMap[rootNode.state.id] = rootNode.state.rect; |
| 351 | if (originData) setOriginNode(originData); |
| 352 | |
| 353 | // Update highlight |
| 354 | let { highlight } = this.state; |
| 355 | if (highlight && !nodeMap[highlight.state.id]) highlight = undefined; |
| 356 | let highlightNodes = this.g |
| 357 | .selectAll(childSelector(SELECTOR_HIGHLIGHT)) |
| 358 | .selectAll<SVGRectElement, INode>(childSelector<SVGRectElement>('rect')) |
| 359 | .data(highlight ? [this._getHighlightRect(highlight)] : []) |
| 360 | .join('rect') |
| 361 | .attr('x', (d) => d.x) |
| 362 | .attr('y', (d) => d.y) |
| 363 | .attr('width', (d) => d.width) |
| 364 | .attr('height', (d) => d.height); |
| 365 | |
| 366 | // Update the nodes |
| 367 | const mmG = this.g |
| 368 | .selectAll<SVGGElement, INode>(childSelector<SVGGElement>(SELECTOR_NODE)) |
| 369 | .each((d) => { |
| 370 | // Save the current rects before updating nodes |
| 371 | sourceRectMap[d.state.id] = d.state.rect; |
| 372 | }) |
| 373 | .data(nodes, (d) => d.state.key); |
| 374 | const mmGEnter = mmG |
no test coverage detected