Skip to content

Commit fb36c5d

Browse files
committed
tidy up things
1 parent 92dea1d commit fb36c5d

File tree

1 file changed

+43
-136
lines changed

1 file changed

+43
-136
lines changed

src/ui/SunburstChart/SunburstChart.jsx

Lines changed: 43 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ function SunburstChart({
2323
const clickHandler = useRef(onClick)
2424
const hoverHandler = useRef(onHover)
2525

26-
/*
27-
* I don't think the depthIndex will work, because we're not trying to render a given depth, we're trying to render a folder and all of its children.
28-
* So we need to render all children of a given folder at once.
29-
*/
30-
3126
// this state stores the root node of the sunburst chart
3227
const [root] = useState(() =>
3328
Sentry.startSpan({ name: 'SunburstChart.createRoot' }, () => {
@@ -41,6 +36,7 @@ function SunburstChart({
4136
while (stack.length > 0) {
4237
const node = stack.pop()
4338

39+
// set the value of the node if not previously set
4440
if (!('value' in node)) {
4541
node.value = selectorHandler.current(node)
4642
}
@@ -50,32 +46,13 @@ function SunburstChart({
5046
node.children.forEach((child) => stack.push(child))
5147
}
5248

53-
const root = partitionFn(result).each((d) => (d.current = d))
54-
55-
root.each((d) => {
56-
const collection = depthIndex.get(d.depth) ?? []
57-
collection.push(d)
58-
depthIndex.set(d.depth, collection)
59-
})
60-
6149
// partition the data and add the `current` property to each node
62-
return { root, depthIndex }
50+
return partitionFn(result).each((d) => (d.current = d))
6351
}
64-
65-
// if the node has children, process them
66-
if (Array.isArray(node.children)) {
67-
node.children.forEach((child) => stack.push(child))
68-
}
69-
70-
const root = partitionFn(result).each((d) => (d.current = d))
71-
72-
// partition the data and add the `current` property to each node
73-
return root
7452
})
7553
)
7654

7755
const [selectedNode, setSelectedNode] = useState(root)
78-
const [forceUpdate, setForceUpdate] = useState(false)
7956

8057
// In this case D3 is handling rendering not React, so useLayoutEffect is used to handle rendering
8158
// and changes outside of the React lifecycle.
@@ -121,17 +98,16 @@ function SunburstChart({
12198
.attr('transform', `translate(${width / 2},${width / 2})`)
12299

123100
function renderArcs() {
101+
const nodesToRender = selectedNode
102+
.descendants()
103+
.slice(1)
104+
.filter((d) => d.depth <= selectedNode.depth + 2)
105+
124106
// Renders an arc per data point in the correct location. (Pieces of the circle that add up to a circular graph)
125-
console.debug('renderArcs', selectedNode)
126107
const path = g
127108
.append('g')
128109
.selectAll('path')
129-
.data(
130-
selectedNode
131-
.descendants()
132-
.slice(1)
133-
.filter((d) => d.depth <= selectedNode.depth + 2)
134-
)
110+
.data(nodesToRender)
135111
.join('path')
136112
.attr('fill', (d) => color(d?.data?.value || 0))
137113
// If data point is a file fade the background color a bit.
@@ -144,15 +120,25 @@ function SunburstChart({
144120
.filter((d) => d.children)
145121
.style('cursor', 'pointer')
146122
.on('click', clickedFolder)
147-
.on('mouseover', hoveredFolder)
148-
.on('mouseout', mouseout)
123+
.on('mouseover', function (_event, p) {
124+
select(this).attr('fill-opacity', 0.6)
125+
reactHoverCallback({ target: p, type: 'folder' })
126+
})
127+
.on('mouseout', function (_event, _node) {
128+
select(this).attr('fill-opacity', 1)
129+
})
149130

150131
// Events for file
151132
path
152133
.filter((d) => !d.children)
153134
.style('cursor', 'pointer')
154-
.on('click', clickedFile)
155-
.on('mouseover', hoveredFile)
135+
.on('click', function (_event, node) {
136+
reactClickCallback({ target: node, type: 'file' })
137+
})
138+
.on('mouseover', function (_event, node) {
139+
select(this).attr('fill-opacity', 0.6)
140+
reactHoverCallback({ target: node, type: 'file' })
141+
})
156142

157143
// Create a11y label / mouse hover tooltip
158144
const formatTitle = (d) => {
@@ -172,54 +158,35 @@ function SunburstChart({
172158
g.append('circle')
173159
.datum(selectedNode.parent)
174160
.attr('r', radius)
161+
.attr('class', 'fill-none')
175162
.attr('fill', 'none')
176163
.attr('pointer-events', 'all')
177-
.attr('cursor', 'pointer')
164+
.attr('cursor', (d) => (d ? 'pointer' : 'default'))
178165
.on('click', clickedFolder)
179166
.on('mouseover', hoveredRoot)
180167

181168
g.append('text')
182169
.datum(selectedNode.parent)
183170
.text('..')
184-
.attr('fill-opacity', (d) => {
185-
// if the parent exists, show the text
186-
return d ? 1 : 0
187-
})
171+
// if the parent exists (i.e. not root), show the text
172+
.attr('fill-opacity', (d) => (d ? 1 : 0))
188173
.attr('text-anchor', 'middle')
189-
.attr('class', 'text-7xl fill-ds-gray-quinary')
174+
.attr('class', 'text-7xl fill-ds-gray-quinary select-none')
190175
.attr('cursor', 'pointer')
191176
.on('click', clickedFolder)
192177
.on('mouseover', hoveredRoot)
193178

194-
function clickedFolder(_event, p) {
195-
reactClickCallback({ target: p, type: 'folder' })
196-
changeLocation(p)
197-
}
198-
199-
function clickedFile(_event, p) {
200-
reactClickCallback({ target: p, type: 'file' })
179+
function clickedFolder(_event, node) {
180+
reactClickCallback({ target: node, type: 'folder' })
181+
changeLocation(node)
201182
}
202183

203-
function hoveredRoot(_event, p) {
184+
function hoveredRoot(_event, node) {
204185
if (previous) {
205186
reactHoverCallback({ target: previous, type: 'folder' })
206187
return
207188
}
208-
reactHoverCallback({ target: p, type: 'folder' })
209-
}
210-
211-
function hoveredFolder(_event, p) {
212-
select(this).attr('fill-opacity', 0.6)
213-
reactHoverCallback({ target: p, type: 'folder' })
214-
}
215-
216-
function hoveredFile(_event, p) {
217-
select(this).attr('fill-opacity', 0.6)
218-
reactHoverCallback({ target: p, type: 'file' })
219-
}
220-
221-
function mouseout(_event, _p) {
222-
select(this).attr('fill-opacity', 1)
189+
reactHoverCallback({ target: node, type: 'folder' })
223190
}
224191

225192
function reactClickCallback({ target, type }) {
@@ -264,99 +231,39 @@ function SunburstChart({
264231
}
265232
}
266233

267-
function changeLocation(p) {
234+
function changeLocation(node) {
268235
// Because you can move two layers at a time previous !== parent
269-
previous = p
270-
// const selected = p.parent || root
271-
// const t = transition(g).duration(750)
236+
previous = node
272237

273-
if (p) {
238+
if (node) {
274239
// Update the selected node
275240
setSelectedNode(
276-
p.each((d) => {
241+
node.each((d) => {
277242
// determine x0 and y0
278-
const x0Min = Math.min(1, (d.x0 - p.x0) / (p.x1 - p.x0))
243+
const x0Min = Math.min(1, (d.x0 - node.x0) / (node.x1 - node.x0))
279244
const x0 = Math.max(0, x0Min) * 2 * Math.PI
280-
const y0 = Math.max(0, d.y0 - p.depth)
245+
const y0 = Math.max(0, d.y0 - node.depth)
281246

282247
// determine x1 and y1
283-
const x1Min = Math.min(1, (d.x1 - p.x0) / (p.x1 - p.x0))
248+
const x1Min = Math.min(1, (d.x1 - node.x0) / (node.x1 - node.x0))
284249
const x1 = Math.max(0, x1Min) * 2 * Math.PI
285-
const y1 = Math.max(0, d.y1 - p.depth)
250+
const y1 = Math.max(0, d.y1 - node.depth)
286251

252+
// update the cords for the node
287253
d.current = { x0, y0, x1, y1 }
288254
})
289255
)
290-
setForceUpdate(!forceUpdate)
291256
}
292-
293-
// handleTextUpdate({ current: p, selected, transition: t })
294257
}
295-
296-
// function handleArcsUpdate({ current, selected, transition }) {
297-
// parent.datum(selected)
298-
299-
// // Handle animating in/out of a folder
300-
// root.each((d) => {
301-
// // determine x0 and y0
302-
// const x0Min = Math.min(
303-
// 1,
304-
// (d.x0 - current.x0) / (current.x1 - current.x0)
305-
// )
306-
// const x0 = Math.max(0, x0Min) * 2 * Math.PI
307-
// const y0 = Math.max(0, d.y0 - current.depth)
308-
309-
// // determine x1 and y1
310-
// const x1Min = Math.min(
311-
// 1,
312-
// (d.x1 - current.x0) / (current.x1 - current.x0)
313-
// )
314-
// const x1 = Math.max(0, x1Min) * 2 * Math.PI
315-
// const y1 = Math.max(0, d.y1 - current.depth)
316-
317-
// d.target = { x0, y0, x1, y1 }
318-
// })
319-
320-
// // Transition the data on all arcs, even the ones that aren’t visible,
321-
// // so that if this transition is interrupted, entering arcs will start
322-
// // the next transition from the desired position.
323-
// path
324-
// .transition(transition)
325-
// .tween('data', (d) => {
326-
// const i = interpolate(d.current, d.target)
327-
// return (t) => (d.current = i(t))
328-
// })
329-
// .filter(function (d) {
330-
// return +this.getAttribute('fill-opacity') || arcVisible(d.target)
331-
// })
332-
// .attr('fill-opacity', (d) =>
333-
// arcVisible(d.target) ? (d.children ? 1 : 0.6) : 0
334-
// )
335-
// .attr('pointer-events', (d) =>
336-
// arcVisible(d.target) ? 'auto' : 'none'
337-
// )
338-
// .attrTween('d', (d) => () => drawArc(d.current))
339-
// }
340-
341-
// function handleTextUpdate({ current, selected, transition }) {
342-
// backText.datum(selected)
343-
344-
// // Only show back if not on root
345-
// if (current.parent) {
346-
// backText.transition(transition).attr('fill-opacity', 1)
347-
// } else {
348-
// backText.transition(transition).attr('fill-opacity', 0)
349-
// }
350-
// }
351258
}
352259

353260
renderArcs()
354261

355-
// On cleanup remove the root DOM generated by D3
356262
return () => {
263+
// On cleanup remove the root DOM generated by D3
357264
g.remove()
358265
}
359-
}, [colorDomainMax, colorDomainMin, forceUpdate, selectedNode, svgRenderSize])
266+
}, [colorDomainMax, colorDomainMin, selectedNode, svgRenderSize])
360267

361268
return (
362269
<svg

0 commit comments

Comments
 (0)