donatso/family-chart

[NextJS] d3.select(...).transition is not a function

Opened this issue · 1 comments

Hi, I find this module interesting and tried to implement to NextJS based on code generated on https://donatso.github.io/family-chart/examples/create-tree/

I wrap all componentDidMount to a useEffect hook, createRef with useRef hook.

I did a conditional if everything was mounted based on .current presence from the ref.

However it did not run as expected and returning the exact d3.select(...).transition is not a function error which I assume this was came from the family-chart that d3 module was not yet loaded, I've attached my code I working on this page.

'use client'

import { Suspense, useEffect, useRef } from 'react'
import f3 from 'family-chart'

import '@/styles/family-tree.css'

export default function RelationshipAnalisis() {

	const treeRef = useRef<HTMLDivElement>(null)

	const treeData = [
		{
			"id": "0",
			"rels": {
				"father": "83285456-43d8-44bd-bbf1-9204bd69111e",
				"mother": "fe5debe3-2ff0-4bf5-be51-317f595575d5",
				"spouses": [
					"588da99f-31df-4887-b4c1-163e4d2a6cee"
				]
			},
			"data": {
				"first name": "Name",
				"last name": "Surname",
				"birthday": 1970,
				"avatar": "https://static8.depositphotos.com/1009634/988/v/950/depositphotos_9883921-stock-illustration-no-user-profile-picture.jpg",
				"gender": "M"
			}
		},
		{
			"id": "83285456-43d8-44bd-bbf1-9204bd69111e",
			"data": {
				"gender": "M",
				"first name": "",
				"last name": "",
				"birthday": "",
				"avatar": ""
			},
			"rels": {
				"children": [
					"0"
				],
				"spouses": [
					"fe5debe3-2ff0-4bf5-be51-317f595575d5"
				]
			}
		},
		{
			"id": "fe5debe3-2ff0-4bf5-be51-317f595575d5",
			"data": {
				"gender": "F",
				"first name": "",
				"last name": "",
				"birthday": "",
				"avatar": ""
			},
			"rels": {
				"spouses": [
					"83285456-43d8-44bd-bbf1-9204bd69111e"
				],
				"children": [
					"0"
				]
			}
		},
		{
			"id": "588da99f-31df-4887-b4c1-163e4d2a6cee",
			"data": {
				"gender": "F",
				"first name": "",
				"last name": "",
				"birthday": "",
				"avatar": ""
			},
			"rels": {
				"spouses": [
					"0"
				]
			}
		}
	]

	useEffect(() => {
		if (treeRef?.current) {
			const store = f3.createStore({
				data: treeData,
				node_separation: 250,
				level_separation: 150
			})

			const view = f3.d3AnimationView({
				store,
				cont: document.querySelector("#FamilyChart")
			})

			const Card = f3.elements.Card({
				store,
				svg: view.svg,
				card_dim: { w: 220, h: 70, text_x: 75, text_y: 15, img_w: 60, img_h: 60, img_x: 5, img_y: 5 },
				card_display: [(d: { data: { [x: string]: any } }) => `${d.data['first name'] || ''} ${d.data['last name'] || ''}`, (d: { data: { [x: string]: any } }) => `${d.data['birthday'] || ''}`],
				mini_tree: true,
				link_break: false
			})

			view.setCard(Card)
			store.setOnUpdate((props: any) => view.update(props || {}))
			store.update.tree({ initial: true })
		}
	}, [treeRef.current])

	return (
		<div className="px-12 sm:px-32">
			<h2 className="text-xl font-medium">Hubungan</h2>
			<Suspense>
				<div id="treeWrapper" className="w-full h-96">
					<div className="f3" id="FamilyChart" ref={treeRef}></div>
				</div>
			</Suspense>
		</div>
	)
}

@Fray117 it works well in my Next.js project. Try removing the useEffect dependency (treeRef.current)