Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as d3 from 'd3';
- import { sankey, sankeyJustify, sankeyLinkHorizontal } from 'd3-sankey';
- import { createRef, useEffect } from 'react';
- import * as data from '../../../sankeyData.json';
- const Sankey = () => {
- const d3Ref = createRef<HTMLDivElement>();
- useEffect(() => {
- const width = d3Ref.current?.getBoundingClientRect().width!;
- const height = d3Ref.current?.getBoundingClientRect().height! / 2;
- const color = () => {
- const color = d3.scaleOrdinal(d3.schemeCategory10);
- return (d: any) => color(d.category);
- };
- const format = () => {
- const format = d3.format(',.0f');
- return data.units ? (d: any) => `${format(d)} ${data.units}` : format;
- };
- const chart = () => {
- const svg = d3.create('svg').attr('viewBox', `${[0, 0, width, height]}`);
- const sankeyConstructor = sankey()
- //@ts-ignore
- .nodeId((d) => d.name)
- .nodeAlign(sankeyJustify)
- .nodeWidth(10)
- .nodePadding(10)
- .extent([
- [1, 5],
- [width - 1, height - 5],
- ]);
- const createSankey = (data: any) => {
- return sankeyConstructor({
- nodes: data.nodes.map((d: any) => Object.assign({}, d)),
- links: data.links.map((d: any) => Object.assign({}, d)),
- });
- };
- const { nodes, links }: any = createSankey(data);
- svg
- .append('g')
- // .attr('stroke', '#000')
- .selectAll('rect')
- .data(nodes)
- .join('rect')
- .attr('x', (d: any) => d.x0)
- .attr('y', (d: any) => d.y0)
- .attr('height', (d: any) => d.y1 - d.y0)
- .attr('width', (d: any) => d.x1 - d.x0)
- .attr('fill', color())
- .append('title')
- .text((d: any) => `${d.name}\n${format(d)}`);
- const link = svg
- .append('g')
- .attr('fill', 'none')
- .attr('stroke-opacity', 0.5)
- .selectAll('g')
- .data(links)
- .join('g')
- .style('mix-blend-mode', 'difference');
- // const gradient = link
- // .append('linearGradient')
- // // .attr('id', (d: any) => (d.uid = d3.DOM.uid('link')).id)
- // .attr('gradientUnits', 'userSpaceOnUse')
- // .attr('x1', (d: any) => d.source.x1)
- // .attr('x2', (d: any) => d.target.x0);
- // gradient
- // .append('stop')
- // .attr('offset', '0%')
- // //@ts-ignore
- // .attr('stop-color', (d) => '#123'); //color()
- // gradient
- // .append('stop')
- // .attr('offset', '100%')
- // //@ts-ignore
- // .attr('stop-color', (d) => '#123'); //color()
- link
- .append('path')
- //@ts-ignore
- .attr('d', sankeyLinkHorizontal())
- .attr('stroke', '#888') //(d: any) => d.value
- .attr('stroke-width', (d: any) => Math.max(1, d.width - 8));
- link.append('title').text((d: any) => `${d.source.name} → ${d.target.name}\n${format(d.value)}`); //may need d.value
- svg
- .append('g')
- .attr('font-family', 'sans-serif')
- .attr('font-size', 12)
- .selectAll('text')
- .data(nodes)
- .join('text')
- .attr('x', (d: any) => (d.x0 < width / 2 ? d.x1 + 2 : d.x0 - 2))
- .attr('y', (d: any) => (d.y1 + d.y0) / 2)
- .attr('dy', '0.35em')
- .attr('text-anchor', (d: any) => (d.x0 < width / 2 ? 'start' : 'end'))
- .text((d: any) => d.name);
- return svg.node();
- };
- d3.select(d3Ref.current).append(chart);
- }, []);
- return <div ref={d3Ref} className="w-4/5 h-screen"></div>;
- };
- export default Sankey;
Advertisement
Add Comment
Please, Sign In to add comment