Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zoom and click on d3 Sankey #3817

Closed
gitgitwhat opened this issue Jan 29, 2024 · 0 comments
Closed

Zoom and click on d3 Sankey #3817

gitgitwhat opened this issue Jan 29, 2024 · 0 comments

Comments

@gitgitwhat
Copy link

I'm having trouble making zoom/pan work with sankey along with mouse events.

There are plenty of examples on the ether that show how to do zooming but they all seem to be using old d3 versions. Nothing that I've tried has worked. Same with node double clicks.

Here is my code based on https://observablehq.com/@d3/sankey-component.

	const margin = {
		top: 20,
		right: 20,
		bottom: 20,
		left: 20,
	};

	var container = d3.select("#" + elem);
	const svg = container.append("svg")
		.attr("width", width)
		.attr("height", height)
		.attr("viewBox", [0, 0, width, height])
		.attr("style", "max-width: 100%; height: auto; font: 10px sans-serif;");

	const sankey = d3.sankey()
		.nodeId(d => d.name)
		.nodeAlign(d3[d3.sankeyLeft])
		.nodeWidth(20)
		.nodePadding(20)
		.extent([[1, 5], [width - 1, height - 5]]);

	const { nodes, links } = sankey({
		nodes: na.map(d => Object.assign({}, d)),
		links: la.map(d => Object.assign({}, d))
	});

	const color = d3.scaleOrdinal(d3.schemeCategory10);
	const vsclr = function(d) {
		return color(d.category);
	};

	const rect = svg.append("g")
		.attr('transform', `translate(${margin.left}, ${margin.top})`)
		.attr("stroke", "#000")
		.selectAll()
		.data(nodes)
		.on("dblclick", d => {
			console.log(d);
		})
		.join("rect")
		.attr("x", d => d.x0)
		.attr("y", d => d.y0)
		.attr("height", d => d.y1 - d.y0)
		.attr("width", d => d.x1 - d.x0)
		.attr("fill", d => vsclr(d));

	const link = svg.append("g")
		.attr("fill", "none")
		.attr("stroke-opacity", 0.5)
		.selectAll()
		.data(links)
		.join("g")
		.style("mix-blend-mode", "multiply");

	var linkColor = "target";
	var uid = 1;

	if (linkColor === "source-target") {
		const gradient = link.append("linearGradient")
			.attr("id", d => (d.uid = (uid++).toString()).id)
			.attr("gradientUnits", "userSpaceOnUse")
			.attr("x1", d => d.source.x1)
			.attr("x2", d => d.target.x0);
		gradient.append("stop")
			.attr("offset", "0%")
			.attr("stop-color", d => vsclr(d.source));
		gradient.append("stop")
			.attr("offset", "100%")
			.attr("stop-color", d => vsclr(d.target));
	}

	link.append("path")
		.attr("d", d3.sankeyLinkHorizontal())
		.attr("stroke", linkColor === "source-target" ? (d) => d.uid
			: linkColor === "source" ? (d) => vsclr(d.source)
				: linkColor === "target" ? (d) => vsclr(d.target)
					: linkColor)
		.attr("stroke-width", d => Math.max(1, d.width));

	const tooltip = container
		.append('div')
		.attr('id', 'tooltip')
		.style('position', 'absolute')
		.style('padding', '1rem')
		.style('background-color', 'white');

	link.on("mouseover", (event, d) => {
		tooltip.style("opacity", 1)
			.style("left", (event.offsetX + 3) + "px")
			.style("top", (event.offsetY +  5) + "px")
			.html(`<strong>${d.source.name}</strong> - <strong>${d.target.name}</strong>`);
	})
	.on("mouseout", (event, d) => {
		tooltip.style("opacity", 0)
	});

	svg.append("g")
		.selectAll()
		.data(nodes)
		.join("text")
		.attr("x", d => d.x0 < width / 2 ? d.x1 + 6 : d.x0 - 6)
		.attr("y", d => (d.y1 + d.y0) / 2)
		.attr("dy", "0.35em")
		.attr("text-anchor", d => d.x0 < width / 2 ? "start" : "end")
		.text(d => d.name);

	var zoom = d3.zoom()
		.scaleExtent([1, 8])
		.on('zoom', function(event) {
			rect.selectAll().attr('transform', event.transform);
	});

	svg.call(zoom);
@d3 d3 locked and limited conversation to collaborators Jan 29, 2024
@mbostock mbostock converted this issue into discussion #3818 Jan 29, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Development

No branches or pull requests

1 participant