Hey!
I am trying to make a graph that can output things in the console(for testing purposes) when I click a node in a d3 graph. This is not working for some odd reason - any help in solving this would be greatly appreciated. apologies if this code isn’t a total reproducible example, but I don’t think any of it is directly related here.
const updateGraphFromData = () => {
if (!currentData || currentData.length === 0) {
console.error('Current data is null, undefined, or empty.');
return;
}
d3.select('#graph').selectAll('svg').remove();
const graphContainer = document.querySelector('#graph');
const svgWidth = graphContainer.clientWidth;
const svgHeight = window.innerHeight;
const svg = d3.select('#graph').append('svg')
.attr('width', '100%') // Use 100% of the container width
.attr('height', svgHeight);
const inner = svg.append('g');
const nodeHeight = 20; // Replace 20 with whatever height you want for the nodes
svg.append('rect')
.attr('width', '100%')
.attr('height', '100%')
.attr('fill', 'black')
.attr('opacity', 0.075);
// svg.call(d3.zoom().on('zoom', (event) => {
// inner.attr('transform', event.transform);
// }));
let { nodes, links } = generateNodesAndLinks(currentData);
let centralLinks = generateCentralLinks(nodes, 300); // adjust distance as needed
links = links.concat(centralLinks);
const simulation = d3.forceSimulation(nodes)
.force('link', d3.forceLink(links).id(d => d.id).distance(d => d.distance || 250)) // Increase distance for links
.force('charge', d3.forceManyBody().strength(-1200)) // Increase repulsion strength
.force('center', d3.forceCenter(svgWidth / 2, svgHeight / 2))
.on('tick', ticked);
const link = inner.append('g')
.attr('class', 'links')
.selectAll('line')
.data(links)
.enter().append('line')
.attr('stroke-width', 2)
.attr('stroke', '#999');
const node = inner.append('g')
.attr('class', 'nodes')
.selectAll('g.node')
.data(nodes)
.enter()
.append('g')
.attr('class', 'node')
.call(drag(simulation));
node.append('rect')
.attr('height', d => d.group === 1 ? 2 * nodeHeight : nodeHeight)
.attr('fill', d => d.group === 1 ? '#1f77b4' : '#e377c2')
.attr('y', d => d.group === 1 ? -2 * nodeHeight / 2 : -nodeHeight / 2)
.attr('cursor', 'pointer')
.on('click', function (event, d) {
event.stopPropagation();
onNodeClick(d);
});
const textElements = node.append('text')
.text(d => d.id)
.attr('text-anchor', 'middle')
.attr('fill', 'white')
.each(function (d) {
d.bbox = this.getBBox();
});
node.select('rect')
.attr('width', d => d.bbox.width + 20)
.attr('x', d => -(d.bbox.width + 20) / 2);
node.filter(d => d.group === 1).append('text')
.text(d => `[${d.category}]`)
.attr('x', 0)
.attr('dy', '1em')
.attr('text-anchor', 'middle')
.attr('fill', 'white')
.attr('font-size', '0.8em');
function ticked() {
link
.attr('x1', d => d.source.x)
.attr('y1', d => d.source.y)
.attr('x2', d => d.target.x)
.attr('y2', d => d.target.y);
node
.attr('transform', d => `translate(${d.x},${d.y})`);
}
};
function ticked() {
link
.attr('x1', d => d.source.x)
.attr('y1', d => d.source.y)
.attr('x2', d => d.target.x)
.attr('y2', d => d.target.y);
node
.attr('transform', d => `translate(${d.x},${d.y})`);
};
function onNodeClick(d) {
// Implement your click behavior here
// For instance:
console.log('Node clicked:', d);
// If you want to navigate to a URL, you could use:
// window.location.href = 'your_url_here';
// Or update part of your page with the node information:
// document.getElementById('someElement').innerText = d.id;
}