diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-08-23 17:10:46 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-08-23 17:15:05 +0200 |
commit | 64f4035ac49b449ed53ba439dcef2fa94cc5844d (patch) | |
tree | 858681c4be75643b5906050210387d5e7e56662b | |
parent | feat(web): zoom controls (diff) | |
download | refinery-64f4035ac49b449ed53ba439dcef2fa94cc5844d.tar.gz refinery-64f4035ac49b449ed53ba439dcef2fa94cc5844d.tar.zst refinery-64f4035ac49b449ed53ba439dcef2fa94cc5844d.zip |
refactor(web): move d3-zoom patch into repo
Instead of referencing an external pull request, move the patch into
yarn/.patches and update it to handle pinch-to-zoom.
-rw-r--r-- | .yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch | 134 | ||||
-rw-r--r-- | package.json | 3 | ||||
-rw-r--r-- | subprojects/frontend/package.json | 2 | ||||
-rw-r--r-- | subprojects/frontend/src/graph/GraphArea.tsx | 189 | ||||
-rw-r--r-- | yarn.lock | 14 |
5 files changed, 247 insertions, 95 deletions
diff --git a/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch b/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch new file mode 100644 index 00000000..88d32c72 --- /dev/null +++ b/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch | |||
@@ -0,0 +1,134 @@ | |||
1 | diff --git a/src/zoom.js b/src/zoom.js | ||
2 | index d56438823b2882856f156b0915ccbac038d6923e..50936066a3597c46ad65f690e9c8417e9d3375f8 100644 | ||
3 | --- a/src/zoom.js | ||
4 | +++ b/src/zoom.js | ||
5 | @@ -14,6 +14,10 @@ function defaultFilter(event) { | ||
6 | return (!event.ctrlKey || event.type === 'wheel') && !event.button; | ||
7 | } | ||
8 | |||
9 | +function defaultCenter(event) { | ||
10 | + return pointer(event, this); | ||
11 | +} | ||
12 | + | ||
13 | function defaultExtent() { | ||
14 | var e = this; | ||
15 | if (e instanceof SVGElement) { | ||
16 | @@ -27,6 +31,10 @@ function defaultExtent() { | ||
17 | return [[0, 0], [e.clientWidth, e.clientHeight]]; | ||
18 | } | ||
19 | |||
20 | +function defaultCentroid(extent) { | ||
21 | + return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; | ||
22 | +} | ||
23 | + | ||
24 | function defaultTransform() { | ||
25 | return this.__zoom || identity; | ||
26 | } | ||
27 | @@ -52,7 +60,9 @@ function defaultConstrain(transform, extent, translateExtent) { | ||
28 | |||
29 | export default function() { | ||
30 | var filter = defaultFilter, | ||
31 | + center = defaultCenter, | ||
32 | extent = defaultExtent, | ||
33 | + centroid = defaultCentroid, | ||
34 | constrain = defaultConstrain, | ||
35 | wheelDelta = defaultWheelDelta, | ||
36 | touchable = defaultTouchable, | ||
37 | @@ -148,9 +158,6 @@ export default function() { | ||
38 | return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y); | ||
39 | } | ||
40 | |||
41 | - function centroid(extent) { | ||
42 | - return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; | ||
43 | - } | ||
44 | |||
45 | function schedule(transition, transform, point, event) { | ||
46 | transition | ||
47 | @@ -243,6 +250,7 @@ export default function() { | ||
48 | if (g.wheel) { | ||
49 | if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) { | ||
50 | g.mouse[1] = t.invert(g.mouse[0] = p); | ||
51 | + g.mouse[2] = center.apply(this, arguments); | ||
52 | } | ||
53 | clearTimeout(g.wheel); | ||
54 | } | ||
55 | @@ -252,14 +260,14 @@ export default function() { | ||
56 | |||
57 | // Otherwise, capture the mouse point and location at the start. | ||
58 | else { | ||
59 | - g.mouse = [p, t.invert(p)]; | ||
60 | + g.mouse = [p, t.invert(p), center.apply(this, arguments)]; | ||
61 | interrupt(this); | ||
62 | g.start(); | ||
63 | } | ||
64 | |||
65 | noevent(event); | ||
66 | g.wheel = setTimeout(wheelidled, wheelDelay); | ||
67 | - g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent)); | ||
68 | + g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[2], t.invert(g.mouse[2])), g.extent, translateExtent)); | ||
69 | |||
70 | function wheelidled() { | ||
71 | g.wheel = null; | ||
72 | @@ -278,7 +286,7 @@ export default function() { | ||
73 | |||
74 | dragDisable(event.view); | ||
75 | nopropagation(event); | ||
76 | - g.mouse = [p, this.__zoom.invert(p)]; | ||
77 | + g.prev = p; | ||
78 | interrupt(this); | ||
79 | g.start(); | ||
80 | |||
81 | @@ -288,8 +296,10 @@ export default function() { | ||
82 | var dx = event.clientX - x0, dy = event.clientY - y0; | ||
83 | g.moved = dx * dx + dy * dy > clickDistance2; | ||
84 | } | ||
85 | + var p = pointer(event, currentTarget); | ||
86 | g.event(event) | ||
87 | - .zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = pointer(event, currentTarget), g.mouse[1]), g.extent, translateExtent)); | ||
88 | + .zoom("mouse", constrain(translate(g.that.__zoom, p, g.that.__zoom.invert(g.prev)), g.extent, translateExtent)); | ||
89 | + g.prev = p; | ||
90 | } | ||
91 | |||
92 | function mouseupped(event) { | ||
93 | @@ -303,7 +313,7 @@ export default function() { | ||
94 | function dblclicked(event, ...args) { | ||
95 | if (!filter.apply(this, arguments)) return; | ||
96 | var t0 = this.__zoom, | ||
97 | - p0 = pointer(event.changedTouches ? event.changedTouches[0] : event, this), | ||
98 | + p0 = center.call(this, event.changedTouches ? event.changedTouches[0] : event), | ||
99 | p1 = t0.invert(p0), | ||
100 | k1 = t0.k * (event.shiftKey ? 0.5 : 2), | ||
101 | t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, args), translateExtent); | ||
102 | @@ -322,7 +332,7 @@ export default function() { | ||
103 | |||
104 | nopropagation(event); | ||
105 | for (i = 0; i < n; ++i) { | ||
106 | - t = touches[i], p = pointer(t, this); | ||
107 | + t = touches[i], p = center.call(this, t); | ||
108 | p = [p, this.__zoom.invert(p), t.identifier]; | ||
109 | if (!g.touch0) g.touch0 = p, started = true, g.taps = 1 + !!touchstarting; | ||
110 | else if (!g.touch1 && g.touch0[2] !== p[2]) g.touch1 = p, g.taps = 0; | ||
111 | @@ -345,7 +355,7 @@ export default function() { | ||
112 | |||
113 | noevent(event); | ||
114 | for (i = 0; i < n; ++i) { | ||
115 | - t = touches[i], p = pointer(t, this); | ||
116 | + t = touches[i], p = center.call(this, t); | ||
117 | if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; | ||
118 | else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p; | ||
119 | } | ||
120 | @@ -406,6 +416,14 @@ export default function() { | ||
121 | return arguments.length ? (touchable = typeof _ === "function" ? _ : constant(!!_), zoom) : touchable; | ||
122 | }; | ||
123 | |||
124 | + zoom.center = function(_) { | ||
125 | + return arguments.length ? (center = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), zoom) : center; | ||
126 | + }; | ||
127 | + | ||
128 | + zoom.centroid = function(_) { | ||
129 | + return arguments.length ? (centroid = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), zoom) : centroid; | ||
130 | + }; | ||
131 | + | ||
132 | zoom.extent = function(_) { | ||
133 | return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent; | ||
134 | }; | ||
diff --git a/package.json b/package.json index bdac68a6..d527c291 100644 --- a/package.json +++ b/package.json | |||
@@ -29,6 +29,7 @@ | |||
29 | "typescript": "5.1.6" | 29 | "typescript": "5.1.6" |
30 | }, | 30 | }, |
31 | "resolutions": { | 31 | "resolutions": { |
32 | "d3-zoom@npm:^3.0.0": "git@github.com:d3/d3-zoom.git#commit=3afbe2ae2dfb3129231c5567db56dafb2d6a56a6" | 32 | "d3-zoom@npm:^3.0.0": "patch:d3-zoom@npm%3A3.0.0#~/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch", |
33 | "d3-zoom@npm:3": "patch:d3-zoom@npm%3A3.0.0#~/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch" | ||
33 | } | 34 | } |
34 | } | 35 | } |
diff --git a/subprojects/frontend/package.json b/subprojects/frontend/package.json index 9df8d85f..97f6baf6 100644 --- a/subprojects/frontend/package.json +++ b/subprojects/frontend/package.json | |||
@@ -51,7 +51,7 @@ | |||
51 | "d3": "^7.8.5", | 51 | "d3": "^7.8.5", |
52 | "d3-graphviz": "patch:d3-graphviz@npm%3A5.1.0#~/.yarn/patches/d3-graphviz-npm-5.1.0-ba6bed3fec.patch", | 52 | "d3-graphviz": "patch:d3-graphviz@npm%3A5.1.0#~/.yarn/patches/d3-graphviz-npm-5.1.0-ba6bed3fec.patch", |
53 | "d3-selection": "^3.0.0", | 53 | "d3-selection": "^3.0.0", |
54 | "d3-zoom": "^3.0.0", | 54 | "d3-zoom": "patch:d3-zoom@npm%3A3.0.0#~/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch", |
55 | "escape-string-regexp": "^5.0.0", | 55 | "escape-string-regexp": "^5.0.0", |
56 | "json-stringify-pretty-compact": "^4.0.0", | 56 | "json-stringify-pretty-compact": "^4.0.0", |
57 | "lodash-es": "^4.17.21", | 57 | "lodash-es": "^4.17.21", |
diff --git a/subprojects/frontend/src/graph/GraphArea.tsx b/subprojects/frontend/src/graph/GraphArea.tsx index aec5d1c6..6ca3bc87 100644 --- a/subprojects/frontend/src/graph/GraphArea.tsx +++ b/subprojects/frontend/src/graph/GraphArea.tsx | |||
@@ -11,6 +11,7 @@ import Box from '@mui/material/Box'; | |||
11 | import IconButton from '@mui/material/IconButton'; | 11 | import IconButton from '@mui/material/IconButton'; |
12 | import Stack from '@mui/material/Stack'; | 12 | import Stack from '@mui/material/Stack'; |
13 | import { useTheme } from '@mui/material/styles'; | 13 | import { useTheme } from '@mui/material/styles'; |
14 | import { CSSProperties } from '@mui/material/styles/createTypography'; | ||
14 | import * as d3 from 'd3'; | 15 | import * as d3 from 'd3'; |
15 | import { type Graphviz, graphviz } from 'd3-graphviz'; | 16 | import { type Graphviz, graphviz } from 'd3-graphviz'; |
16 | import type { BaseType, Selection } from 'd3-selection'; | 17 | import type { BaseType, Selection } from 'd3-selection'; |
@@ -109,15 +110,21 @@ export default function GraphArea(): JSX.Element { | |||
109 | zoomBehavior as unknown as { | 110 | zoomBehavior as unknown as { |
110 | center(callback: (event: MouseEvent) => [number, number]): unknown; | 111 | center(callback: (event: MouseEvent) => [number, number]): unknown; |
111 | } | 112 | } |
112 | ).center((event: MouseEvent) => { | 113 | ).center((event: MouseEvent | Touch) => { |
113 | const { width, height } = element.getBoundingClientRect(); | 114 | const { width, height } = element.getBoundingClientRect(); |
114 | const [x, y] = d3.pointer(event, element); | 115 | const [x, y] = d3.pointer(event, element); |
115 | return [x - width / 2, y - height / 2]; | 116 | return [x - width / 2, y - height / 2]; |
116 | }); | 117 | }); |
118 | // Custom `centroid` method added via patch. | ||
119 | ( | ||
120 | zoomBehavior as unknown as { | ||
121 | centroid(centroid: [number, number]): unknown; | ||
122 | } | ||
123 | ).centroid([0, 0]); | ||
117 | zoomBehavior.on('zoom', (event: d3.D3ZoomEvent<HTMLDivElement, unknown>) => | 124 | zoomBehavior.on('zoom', (event: d3.D3ZoomEvent<HTMLDivElement, unknown>) => |
118 | setZoom(event.transform), | 125 | setZoom(event.transform), |
119 | ); | 126 | ); |
120 | d3.select(element).call(zoomBehavior).on('dblclick.zoom', null); | 127 | d3.select(element).call(zoomBehavior); |
121 | zoomRef.current = zoomBehavior; | 128 | zoomRef.current = zoomBehavior; |
122 | }, []); | 129 | }, []); |
123 | 130 | ||
@@ -213,25 +220,17 @@ export default function GraphArea(): JSX.Element { | |||
213 | [editorStore], | 220 | [editorStore], |
214 | ); | 221 | ); |
215 | 222 | ||
216 | const { | 223 | const changeZoom = useCallback((event: React.MouseEvent, factor: number) => { |
217 | transitions: { | 224 | if (canvasRef.current === undefined || zoomRef.current === undefined) { |
218 | duration: { short: zoomDuration }, | 225 | return; |
219 | }, | 226 | } |
220 | } = theme; | 227 | const selection = d3.select(canvasRef.current); |
221 | const changeZoom = useCallback( | 228 | const zoomTransition = selection.transition().duration(250); |
222 | (event: React.MouseEvent, factor: number) => { | 229 | const center: [number, number] = [0, 0]; |
223 | if (canvasRef.current === undefined || zoomRef.current === undefined) { | 230 | zoomRef.current.scaleBy(zoomTransition, factor, center); |
224 | return; | 231 | event.preventDefault(); |
225 | } | 232 | event.stopPropagation(); |
226 | const selection = d3.select(canvasRef.current); | 233 | }, []); |
227 | const zoomTransition = selection.transition().duration(zoomDuration); | ||
228 | const center: [number, number] = [0, 0]; | ||
229 | zoomRef.current.scaleBy(zoomTransition, factor, center); | ||
230 | event.preventDefault(); | ||
231 | event.stopPropagation(); | ||
232 | }, | ||
233 | [zoomDuration], | ||
234 | ); | ||
235 | 234 | ||
236 | const fitZoom = useCallback((event: React.MouseEvent) => { | 235 | const fitZoom = useCallback((event: React.MouseEvent) => { |
237 | if ( | 236 | if ( |
@@ -255,7 +254,8 @@ export default function GraphArea(): JSX.Element { | |||
255 | (canvasHeight - 64) / height, | 254 | (canvasHeight - 64) / height, |
256 | ); | 255 | ); |
257 | const selection = d3.select(canvasRef.current); | 256 | const selection = d3.select(canvasRef.current); |
258 | zoomRef.current.transform(selection, d3.zoomIdentity.scale(factor)); | 257 | const zoomTransition = selection.transition().duration(250); |
258 | zoomRef.current.transform(zoomTransition, d3.zoomIdentity.scale(factor)); | ||
259 | } | 259 | } |
260 | event.preventDefault(); | 260 | event.preventDefault(); |
261 | event.stopPropagation(); | 261 | event.stopPropagation(); |
@@ -268,79 +268,96 @@ export default function GraphArea(): JSX.Element { | |||
268 | height: '100%', | 268 | height: '100%', |
269 | position: 'relative', | 269 | position: 'relative', |
270 | overflow: 'hidden', | 270 | overflow: 'hidden', |
271 | '& svg': { | ||
272 | userSelect: 'none', | ||
273 | '& .node': { | ||
274 | '& text': { | ||
275 | ...theme.typography.body2, | ||
276 | fill: theme.palette.text.primary, | ||
277 | }, | ||
278 | '& [stroke="black"]': { | ||
279 | stroke: theme.palette.text.primary, | ||
280 | }, | ||
281 | '& [fill="green"]': { | ||
282 | fill: | ||
283 | theme.palette.mode === 'dark' | ||
284 | ? theme.palette.primary.dark | ||
285 | : theme.palette.primary.light, | ||
286 | }, | ||
287 | '& [fill="white"]': { | ||
288 | fill: theme.palette.background.default, | ||
289 | stroke: theme.palette.background.default, | ||
290 | }, | ||
291 | }, | ||
292 | '& .edge': { | ||
293 | '& text': { | ||
294 | ...theme.typography.caption, | ||
295 | fill: theme.palette.text.primary, | ||
296 | }, | ||
297 | '& [stroke="black"]': { | ||
298 | stroke: theme.palette.text.primary, | ||
299 | }, | ||
300 | '& [fill="black"]': { | ||
301 | fill: theme.palette.text.primary, | ||
302 | }, | ||
303 | }, | ||
304 | '& .edge-UNKNOWN': { | ||
305 | '& text': { | ||
306 | fill: theme.palette.text.secondary, | ||
307 | }, | ||
308 | '& [stroke="black"]': { | ||
309 | stroke: theme.palette.text.secondary, | ||
310 | }, | ||
311 | '& [fill="black"]': { | ||
312 | fill: theme.palette.text.secondary, | ||
313 | }, | ||
314 | }, | ||
315 | '& .edge-ERROR': { | ||
316 | '& text': { | ||
317 | fill: theme.palette.error.main, | ||
318 | }, | ||
319 | '& [stroke="black"]': { | ||
320 | stroke: theme.palette.error.main, | ||
321 | }, | ||
322 | '& [fill="black"]': { | ||
323 | fill: theme.palette.error.main, | ||
324 | }, | ||
325 | }, | ||
326 | }, | ||
327 | }} | 271 | }} |
328 | ref={setCanvas} | ||
329 | > | 272 | > |
330 | <Box | 273 | <Box |
331 | sx={{ | 274 | sx={{ |
332 | position: 'absolute', | 275 | position: 'absolute', |
333 | top: '50%', | 276 | overflow: 'hidden', |
334 | left: '50%', | 277 | top: 0, |
335 | transform: ` | 278 | left: 0, |
279 | right: 0, | ||
280 | bottom: 0, | ||
281 | }} | ||
282 | ref={setCanvas} | ||
283 | > | ||
284 | <Box | ||
285 | sx={{ | ||
286 | position: 'absolute', | ||
287 | top: '50%', | ||
288 | left: '50%', | ||
289 | transform: ` | ||
336 | translate(${zoom.x}px, ${zoom.y}px) | 290 | translate(${zoom.x}px, ${zoom.y}px) |
337 | scale(${zoom.k}) | 291 | scale(${zoom.k}) |
338 | translate(-50%, -50%) | 292 | translate(-50%, -50%) |
339 | `, | 293 | `, |
340 | transformOrigin: '0 0', | 294 | transformOrigin: '0 0', |
341 | }} | 295 | '& svg': { |
342 | ref={setElement} | 296 | userSelect: 'none', |
343 | /> | 297 | '& .node': { |
298 | '& text': { | ||
299 | ...(theme.typography.body2 as Omit< | ||
300 | CSSProperties, | ||
301 | '@font-face' | ||
302 | >), | ||
303 | fill: theme.palette.text.primary, | ||
304 | }, | ||
305 | '& [stroke="black"]': { | ||
306 | stroke: theme.palette.text.primary, | ||
307 | }, | ||
308 | '& [fill="green"]': { | ||
309 | fill: | ||
310 | theme.palette.mode === 'dark' | ||
311 | ? theme.palette.primary.dark | ||
312 | : theme.palette.primary.light, | ||
313 | }, | ||
314 | '& [fill="white"]': { | ||
315 | fill: theme.palette.background.default, | ||
316 | stroke: theme.palette.background.default, | ||
317 | }, | ||
318 | }, | ||
319 | '& .edge': { | ||
320 | '& text': { | ||
321 | ...(theme.typography.caption as Omit< | ||
322 | CSSProperties, | ||
323 | '@font-face' | ||
324 | >), | ||
325 | fill: theme.palette.text.primary, | ||
326 | }, | ||
327 | '& [stroke="black"]': { | ||
328 | stroke: theme.palette.text.primary, | ||
329 | }, | ||
330 | '& [fill="black"]': { | ||
331 | fill: theme.palette.text.primary, | ||
332 | }, | ||
333 | }, | ||
334 | '& .edge-UNKNOWN': { | ||
335 | '& text': { | ||
336 | fill: theme.palette.text.secondary, | ||
337 | }, | ||
338 | '& [stroke="black"]': { | ||
339 | stroke: theme.palette.text.secondary, | ||
340 | }, | ||
341 | '& [fill="black"]': { | ||
342 | fill: theme.palette.text.secondary, | ||
343 | }, | ||
344 | }, | ||
345 | '& .edge-ERROR': { | ||
346 | '& text': { | ||
347 | fill: theme.palette.error.main, | ||
348 | }, | ||
349 | '& [stroke="black"]': { | ||
350 | stroke: theme.palette.error.main, | ||
351 | }, | ||
352 | '& [fill="black"]': { | ||
353 | fill: theme.palette.error.main, | ||
354 | }, | ||
355 | }, | ||
356 | }, | ||
357 | }} | ||
358 | ref={setElement} | ||
359 | /> | ||
360 | </Box> | ||
344 | <Stack | 361 | <Stack |
345 | direction="column" | 362 | direction="column" |
346 | p={1} | 363 | p={1} |
@@ -2151,7 +2151,7 @@ __metadata: | |||
2151 | d3: "npm:^7.8.5" | 2151 | d3: "npm:^7.8.5" |
2152 | d3-graphviz: "patch:d3-graphviz@npm%3A5.1.0#~/.yarn/patches/d3-graphviz-npm-5.1.0-ba6bed3fec.patch" | 2152 | d3-graphviz: "patch:d3-graphviz@npm%3A5.1.0#~/.yarn/patches/d3-graphviz-npm-5.1.0-ba6bed3fec.patch" |
2153 | d3-selection: "npm:^3.0.0" | 2153 | d3-selection: "npm:^3.0.0" |
2154 | d3-zoom: "npm:^3.0.0" | 2154 | d3-zoom: "patch:d3-zoom@npm%3A3.0.0#~/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch" |
2155 | escape-string-regexp: "npm:^5.0.0" | 2155 | escape-string-regexp: "npm:^5.0.0" |
2156 | eslint: "npm:^8.47.0" | 2156 | eslint: "npm:^8.47.0" |
2157 | eslint-config-airbnb: "npm:^19.0.4" | 2157 | eslint-config-airbnb: "npm:^19.0.4" |
@@ -4144,29 +4144,29 @@ __metadata: | |||
4144 | languageName: node | 4144 | languageName: node |
4145 | linkType: hard | 4145 | linkType: hard |
4146 | 4146 | ||
4147 | "d3-zoom@git@github.com:d3/d3-zoom.git#commit=3afbe2ae2dfb3129231c5567db56dafb2d6a56a6": | 4147 | "d3-zoom@npm:3.0.0": |
4148 | version: 3.0.0 | 4148 | version: 3.0.0 |
4149 | resolution: "d3-zoom@git@github.com:d3/d3-zoom.git#commit=3afbe2ae2dfb3129231c5567db56dafb2d6a56a6" | 4149 | resolution: "d3-zoom@npm:3.0.0" |
4150 | dependencies: | 4150 | dependencies: |
4151 | d3-dispatch: "npm:1 - 3" | 4151 | d3-dispatch: "npm:1 - 3" |
4152 | d3-drag: "npm:2 - 3" | 4152 | d3-drag: "npm:2 - 3" |
4153 | d3-interpolate: "npm:1 - 3" | 4153 | d3-interpolate: "npm:1 - 3" |
4154 | d3-selection: "npm:2 - 3" | 4154 | d3-selection: "npm:2 - 3" |
4155 | d3-transition: "npm:2 - 3" | 4155 | d3-transition: "npm:2 - 3" |
4156 | checksum: 0cca9382fd9cf7383ecd89ae2f4a828b5088e7801eb89da0656c1d3512cda03bfade727db936721b8004a3142dbbf955a408c99cf370539e3a985da9161c6d54 | 4156 | checksum: ee2036479049e70d8c783d594c444fe00e398246048e3f11a59755cd0e21de62ece3126181b0d7a31bf37bcf32fd726f83ae7dea4495ff86ec7736ce5ad36fd3 |
4157 | languageName: node | 4157 | languageName: node |
4158 | linkType: hard | 4158 | linkType: hard |
4159 | 4159 | ||
4160 | "d3-zoom@npm:3": | 4160 | "d3-zoom@patch:d3-zoom@npm%3A3.0.0#~/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch": |
4161 | version: 3.0.0 | 4161 | version: 3.0.0 |
4162 | resolution: "d3-zoom@npm:3.0.0" | 4162 | resolution: "d3-zoom@patch:d3-zoom@npm%3A3.0.0#~/.yarn/patches/d3-zoom-npm-3.0.0-18f706a421.patch::version=3.0.0&hash=135f1c" |
4163 | dependencies: | 4163 | dependencies: |
4164 | d3-dispatch: "npm:1 - 3" | 4164 | d3-dispatch: "npm:1 - 3" |
4165 | d3-drag: "npm:2 - 3" | 4165 | d3-drag: "npm:2 - 3" |
4166 | d3-interpolate: "npm:1 - 3" | 4166 | d3-interpolate: "npm:1 - 3" |
4167 | d3-selection: "npm:2 - 3" | 4167 | d3-selection: "npm:2 - 3" |
4168 | d3-transition: "npm:2 - 3" | 4168 | d3-transition: "npm:2 - 3" |
4169 | checksum: ee2036479049e70d8c783d594c444fe00e398246048e3f11a59755cd0e21de62ece3126181b0d7a31bf37bcf32fd726f83ae7dea4495ff86ec7736ce5ad36fd3 | 4169 | checksum: fc56f5be9f492b7d7bba91b166f4b93e1761599a23496b0f2890e295476971a8db040b0c2069b670897984ed28c4f0d151caf1d51e305fe635e80cdb94f2c2af |
4170 | languageName: node | 4170 | languageName: node |
4171 | linkType: hard | 4171 | linkType: hard |
4172 | 4172 | ||