Skip to content

Commit 951ba28

Browse files
committed
fix: transition handling, also refactor: replace direct d3 imports with namespace import for consistency
1 parent 286df29 commit 951ba28

File tree

3 files changed

+76
-62
lines changed

3 files changed

+76
-62
lines changed

app/components/Home/components/Section/components/SectionViz/sunburst.tsx

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,4 @@
1-
import {
2-
select,
3-
scaleOrdinal,
4-
schemeTableau10,
5-
hsl,
6-
hierarchy,
7-
partition,
8-
arc as d3Arc,
9-
interpolate,
10-
HierarchyNode,
11-
} from "d3";
1+
import * as d3 from "d3";
122
import { useRef, useEffect, useState } from "react";
133
import { getData } from "./data";
144
import { TreeNode, NodeDetails } from "./NodeDetails";
@@ -32,19 +22,20 @@ export const SectionViz = (): JSX.Element => {
3222
const svgNode = svgRef.current;
3323

3424
// Clear any existing content in case of re-render
35-
select(svgNode).selectAll("*").remove();
25+
d3.select(svgNode).selectAll("*").remove();
3626

3727
// Set up dimensions and radius for the sunburst chart
3828
const width = 800;
3929
const height = width;
4030
const radius = (width - 10) / 2;
4131

4232
// Create the main SVG container and center the group
43-
const svg = select(svgNode)
33+
const svg = d3
34+
.select(svgNode)
4435
.attr("viewBox", [-width / 2, -height / 2, width, width])
4536
.style("font", "10px sans-serif");
4637
// Define a color scale for base colors (root and first ring)
47-
const baseColor = scaleOrdinal(schemeTableau10);
38+
const baseColor = d3.scaleOrdinal(d3.schemeTableau10);
4839

4940
// Helper function to get color for a node
5041
function getNodeColor(d): string {
@@ -55,7 +46,7 @@ export const SectionViz = (): JSX.Element => {
5546
const ancestor = d.ancestors().find((n) => n.depth === 1);
5647
if (!ancestor) return "#ccc"; // fallback
5748

58-
const baseColorHsl = hsl(baseColor(ancestor.data.name));
49+
const baseColorHsl = d3.hsl(baseColor(ancestor.data.name));
5950

6051
// Increase lightness and decrease saturation as we go deeper
6152
const lightnessFactor = 0.05 * (d.depth - 1);
@@ -69,7 +60,8 @@ export const SectionViz = (): JSX.Element => {
6960
}
7061

7162
// Create a tooltip for interactivity
72-
const tooltip = select("body")
63+
const tooltip = d3
64+
.select("body")
7365
.append("div")
7466
.attr("class", "tooltip")
7567
.style("opacity", 0)
@@ -83,11 +75,12 @@ export const SectionViz = (): JSX.Element => {
8375
.style("pointer-events", "none");
8476

8577
// Create a hierarchy from the sample data.
86-
const hierarchyData = hierarchy(data)
78+
const hierarchyData = d3
79+
.hierarchy(data)
8780
.sum((d) => (d.children.length == 0 ? 1 : 0))
8881
.sort((a: unknown, b: unknown) => (a.data.name < b.data.name ? -1 : 1));
8982

90-
const root = partition().size([2 * Math.PI, hierarchyData.height + 1])(
83+
const root = d3.partition().size([2 * Math.PI, hierarchyData.height + 1])(
9184
hierarchyData
9285
);
9386

@@ -117,8 +110,8 @@ export const SectionViz = (): JSX.Element => {
117110
.outerRadius((d) => (Math.min(d.y1, DEPTH) * radius) / DEPTH - 0.5);
118111

119112
function isVisible(
120-
d: HierarchyNode<TreeNode>,
121-
currentRoot: HierarchyNode<TreeNode>,
113+
d: d3.HierarchyNode<TreeNode>,
114+
currentRoot: d3.HierarchyNode<TreeNode>,
122115
targetDepth: number
123116
): boolean {
124117
const isDescendant = d.ancestors().indexOf(currentRoot) >= 0;
@@ -282,13 +275,12 @@ export const SectionViz = (): JSX.Element => {
282275
} as NodeTarget;
283276
});
284277

285-
const transition = svg.transition().duration(750);
286-
287278
// Transition the arcs.
288279
path
289-
.transition(transition)
280+
.transition()
281+
.duration(750)
290282
.tween("data", (d: TreeNode) => {
291-
const i = interpolate(d.current, d.target);
283+
const i = d3.interpolate(d.current, d.target);
292284
// eslint-disable-next-line sonarjs/no-nested-functions -- cleaner in d3 to keep this inlined
293285
return (transition_duration: number): void => {
294286
d.current = i(transition_duration);
@@ -305,12 +297,13 @@ export const SectionViz = (): JSX.Element => {
305297

306298
// Transition the labels with updated visibility logic
307299
label
308-
.transition(svg.transition().duration(750))
300+
.transition()
301+
.duration(750)
309302
.tween("data", (d) => {
310-
const i = interpolate(d.current, d.target);
303+
const i = d3.interpolate(d.current, d.target);
311304
// eslint-disable-next-line sonarjs/no-nested-functions -- cleaner in d3 to keep this inlined
312-
return (transition: number): void => {
313-
d.current = i(transition);
305+
return (transition_duration: number): void => {
306+
d.current = i(transition_duration);
314307
};
315308
})
316309
.attrTween(
@@ -339,7 +332,7 @@ export const SectionViz = (): JSX.Element => {
339332
// Clean up on component unmount: remove tooltip and clear svg.
340333
return (): void => {
341334
tooltip.remove();
342-
select(svgNode).selectAll("*").remove();
335+
d3.select(svgNode).selectAll("*").remove();
343336
};
344337
}, []);
345338

0 commit comments

Comments
 (0)