I'm creating family tree using d3.js and i want to do 2 things
- how can i highlight the parents names and the connection lines when I hover on their child like this image when i hover on axelenter image description here
- how can i determine the last child in each branch so i can give it unique style or add icon after it eg: tree leaf like this image enter image description here
Here is a snippet of my code:
const familyData = [
{
_id: '60da7d37b8ca2d2590f0b713',
child: 'William',
parent: '',
parentId: null
},
{
_id: '60da7d7f6a89ad1fecc905e9',
child: 'James',
parent: 'William',
parentId: '60da7d37b8ca2d2590f0b713'
},
{
_id: '60da7d9619156a6d90874aa1',
child: 'Henry',
parent: 'William',
parentId: '60da7d37b8ca2d2590f0b713'
},
{
_id: '60da7db3c1f2f27368395212',
child: 'Michael',
parent: 'James',
parentId: '60da7d7f6a89ad1fecc905e9'
},
{
_id: '60da7dd32796ae5cbc0e1810',
child: 'Ethan',
parent: 'James',
parentId: '60da7d7f6a89ad1fecc905e9'
},
{
_id: '60da7df79f58c4028cb21d06',
child: 'Jacob',
parent: 'Henry',
parentId: '60da7d9619156a6d90874aa1'
},
{
_id: '60da7e149cf24f1d20167c14',
child: 'Jack',
parent: 'William',
parentId: '60da7d37b8ca2d2590f0b713'
},
{
_id: '60da7e2add5413458427c4b2',
child: 'Joseph',
parent: 'Jack',
parentId: '60da7e149cf24f1d20167c14'
},
{
_id: '60da7e48fec03d0b1c2d10d3',
child: 'Asher',
parent: 'Joseph',
parentId: '60da7e2add5413458427c4b2'
},
{
_id: '60da7e5c8cc6f66264b23e70',
child: 'Leo',
parent: 'Ethan',
parentId: '60da7dd32796ae5cbc0e1810'
},
{
_id: '60da7e89cefbdd785cec5ada',
child: 'Isaac',
parent: 'Leo',
parentId: '60da7e5c8cc6f66264b23e70'
},
{
_id: '60da7e93ed9bd0402487e5c8',
child: 'Charles',
parent: 'Leo',
parentId: '60da7e5c8cc6f66264b23e70'
},
{
_id: '60da7ea006b3694914c99ee0',
child: 'Caleb',
parent: 'Michael',
parentId: '60da7db3c1f2f27368395212'
},
{
_id: '60da7eab6a06e223e42b5d65',
child: 'Ryan',
parent: 'Michael',
parentId: '60da7db3c1f2f27368395212'
},
{
_id: '60da7e6b05ff5f0468d8e835',
child: 'Thomas',
parent: 'Jacob',
parentId: '60da7df79f58c4028cb21d06'
},
{
_id: '60da7eb5b7a93714303ef471',
child: 'Aaron',
parent: 'Thomas',
parentId: '60da7e6b05ff5f0468d8e835'
},
{
_id: '60da7ebcf21a2a44503b7596',
child: 'Axel',
parent: 'Thomas',
parentId: '60da7e6b05ff5f0468d8e835'
}
]
const dataStructure = d3.stratify()
.id(d => d._id)
.parentId(d => d.parentId)(familyData)
const treeStructure = d3.tree()
.size([500,300])
let root = treeStructure(dataStructure)
console.log(root.descendants());
console.log(root.links());
const svg = d3.select('svg')
.attr('width',600)
.attr('height',600)
const nodes = svg.append('g')
.attr('transform','translate(50,50)')
.selectAll('circle')
.data(root.descendants())
.enter()
.append('circle')
.attr('cx', d => d.x)
.attr('cy', d => d.y)
.attr('r', 3)
.attr('fill', function(d){
if(d.depth === 0) return 'black'
else if (d.depth === 1) return 'red'
else if (d.depth === 2) return 'green'
else if (d.depth === 3) return 'magenta'
else return 'brown'
})
const connections = svg.append('g')
.attr('transform','translate(50,50)')
.selectAll('path')
.data(root.links())
.enter()
.append('path')
.attr('d', d => `M ${d.source.x} ${d.source.y} C ${d.source.x} ${(d.source.y + d.target.y) / 2},
${d.target.x} ${(d.source.y + d.target.y) / 2}, ${d.target.x} ${d.target.y}`)
const names = svg.append('g')
.attr('transform','translate(50,50)')
.selectAll('text')
.data(root.descendants())
.enter()
.append('text')
.text(d => d.data.child)
.attr('x', d => d.x + 8)
.attr('y', d => d.y + 2)
.style('font-size', '1rem')
.on('mouseover', function(e,d){
d3.select(this)
.transition()
.duration('100')
.attr('opacity', 1)
.style('font-size','2rem')
d3.selectAll('text').attr('opacity', '0.3')
d3.selectAll('circle').attr('opacity', '0.3')
})
.on('mouseout', function(d){
d3.select(this)
.style('font-size','1rem')
d3.selectAll('text').attr('opacity', '1')
d3.selectAll('circle').attr('opacity', '1')
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/[email protected]/dist/d3.min.js"></script>
<script src='try.js' defer></script>
<style>
path {
fill:transparent;
stroke:teal;
}
text {
cursor: pointer;
}
</style>
<title>Document</title>
</head>
<body>
<svg></svg>
</body>
</html>