Skip to content
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

feat(sankey): add @visx/sankey #1880

Merged
merged 29 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f235e4e
initialize package
jacksonhardaker Sep 25, 2024
6a0fc55
add `Sankey` component
jacksonhardaker Sep 25, 2024
f6b1495
add exports
jacksonhardaker Sep 25, 2024
eacc1e9
add default color
jacksonhardaker Sep 25, 2024
ad0e4c4
add docs page
jacksonhardaker Sep 25, 2024
4a36269
fix package
jacksonhardaker Sep 25, 2024
afd0826
fix import and tsconfig
jacksonhardaker Sep 25, 2024
c1ee24d
extract to types
jacksonhardaker Sep 25, 2024
560120d
add example
jacksonhardaker Sep 25, 2024
5ea7cfd
change version to 1.0.0
jacksonhardaker Sep 26, 2024
ff3d5c7
add to visx-visx
jacksonhardaker Sep 26, 2024
dc8a980
pin version
jacksonhardaker Sep 26, 2024
31d4d6e
add controls to sankey example
jacksonhardaker Sep 26, 2024
5affdce
add sankey tile
jacksonhardaker Sep 26, 2024
726ea17
add styles to example
jacksonhardaker Sep 26, 2024
71208f7
add example tile to docs page
jacksonhardaker Sep 26, 2024
057267a
add usage to readme
jacksonhardaker Sep 26, 2024
70546d6
remove console.log
jacksonhardaker Sep 26, 2024
dd8595b
add class names
jacksonhardaker Sep 26, 2024
8a2e81a
add tests
jacksonhardaker Sep 27, 2024
0cd4c44
fix readme
jacksonhardaker Sep 27, 2024
1c4b2d2
add tooltip to example
jacksonhardaker Sep 27, 2024
2fe3b62
update references
jacksonhardaker Sep 30, 2024
979dbec
pin d3-shape version d3-sankey dep
jacksonhardaker Sep 30, 2024
c9068b8
revert automatically applied demo tsconfig changes
jacksonhardaker Oct 2, 2024
ff039e1
remove newline
jacksonhardaker Oct 2, 2024
73eaace
build sizes
jacksonhardaker Oct 2, 2024
71649a3
remove console.log
jacksonhardaker Nov 6, 2024
be8b3df
format
jacksonhardaker Nov 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/sizes.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"visx-annotation":{"esm":31002,"lib":43431},"visx-axis":{"esm":21783,"lib":26434},"visx-bounds":{"esm":2948,"lib":3371},"visx-brush":{"esm":56194,"lib":60810},"visx-chord":{"esm":3478,"lib":4691},"visx-clip-path":{"esm":4524,"lib":6062},"visx-curve":{"esm":323,"lib":1462},"visx-delaunay":{"esm":2599,"lib":3428},"visx-demo":{"esm":0,"lib":36731},"visx-drag":{"esm":12756,"lib":14402},"visx-event":{"esm":3878,"lib":5194},"visx-geo":{"esm":13662,"lib":16903},"visx-glyph":{"esm":15177,"lib":19992},"visx-gradient":{"esm":18202,"lib":22847},"visx-grid":{"esm":18982,"lib":22665},"visx-group":{"esm":1648,"lib":2267},"visx-heatmap":{"esm":7394,"lib":8731},"visx-hierarchy":{"esm":12093,"lib":17910},"visx-legend":{"esm":26975,"lib":34055},"visx-marker":{"esm":9152,"lib":11350},"visx-mock-data":{"esm":326040,"lib":329480},"visx-network":{"esm":4674,"lib":6809},"visx-pattern":{"esm":11689,"lib":15763},"visx-point":{"esm":1003,"lib":1818},"visx-react-spring":{"esm":14040,"lib":17765},"visx-responsive":{"esm":16350,"lib":18791},"visx-scale":{"esm":18870,"lib":30555},"visx-shape":{"esm":86912,"lib":108820},"visx-stats":{"esm":13738,"lib":15320},"visx-text":{"esm":8567,"lib":10114},"visx-threshold":{"esm":2907,"lib":3806},"visx-tooltip":{"esm":15233,"lib":21734},"visx-vendor":{"esm":2492,"lib":2702},"visx-visx":{"esm":1524,"lib":4487},"visx-voronoi":{"esm":2314,"lib":3021},"visx-wordcloud":{"esm":2620,"lib":3455},"visx-xychart":{"esm":178473,"lib":240315},"visx-zoom":{"esm":16239,"lib":19297}}
{"visx-annotation":{"esm":31002,"lib":43431},"visx-axis":{"esm":21783,"lib":26434},"visx-bounds":{"esm":2948,"lib":3371},"visx-brush":{"esm":56194,"lib":60810},"visx-chord":{"esm":3478,"lib":4691},"visx-clip-path":{"esm":4524,"lib":6062},"visx-curve":{"esm":323,"lib":1462},"visx-delaunay":{"esm":2599,"lib":3428},"visx-demo":{"esm":0,"lib":36869},"visx-drag":{"esm":12756,"lib":14402},"visx-event":{"esm":3878,"lib":5194},"visx-geo":{"esm":13662,"lib":16903},"visx-glyph":{"esm":15177,"lib":19992},"visx-gradient":{"esm":18202,"lib":22847},"visx-grid":{"esm":18982,"lib":22665},"visx-group":{"esm":1648,"lib":2267},"visx-heatmap":{"esm":7394,"lib":8731},"visx-hierarchy":{"esm":12093,"lib":17910},"visx-legend":{"esm":26975,"lib":34055},"visx-marker":{"esm":9152,"lib":11350},"visx-mock-data":{"esm":326040,"lib":329480},"visx-network":{"esm":4674,"lib":6809},"visx-pattern":{"esm":11689,"lib":15763},"visx-point":{"esm":1003,"lib":1818},"visx-react-spring":{"esm":14040,"lib":17765},"visx-responsive":{"esm":16350,"lib":18791},"visx-sankey":{"esm":3606,"lib":4677},"visx-scale":{"esm":18870,"lib":30555},"visx-shape":{"esm":86912,"lib":108820},"visx-stats":{"esm":13738,"lib":15320},"visx-text":{"esm":8567,"lib":10114},"visx-threshold":{"esm":2907,"lib":3806},"visx-tooltip":{"esm":15233,"lib":21734},"visx-vendor":{"esm":2492,"lib":2702},"visx-visx":{"esm":1524,"lib":4487},"visx-voronoi":{"esm":2314,"lib":3021},"visx-wordcloud":{"esm":2620,"lib":3455},"visx-xychart":{"esm":178473,"lib":240315},"visx-zoom":{"esm":16239,"lib":19297}}
1 change: 1 addition & 0 deletions packages/visx-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@visx/point": "3.3.0",
"@visx/react-spring": "3.10.1",
"@visx/responsive": "3.10.2",
"@visx/sankey": "1.0.0",
"@visx/scale": "3.5.0",
"@visx/shape": "3.5.0",
"@visx/stats": "3.5.0",
Expand Down
23 changes: 23 additions & 0 deletions packages/visx-demo/src/components/Gallery/SankeyTile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import Sankey, { SankeyDemoProps, background, color } from '../../sandboxes/visx-sankey/Example';
import GalleryTile from '../GalleryTile';

export { default as packageJson } from '../../sandboxes/visx-sankey/package.json';

const tileStyles = { background };
const detailsStyles = { color };
const exampleProps = { showControls: false };

export default function SankeyTile() {
return (
<GalleryTile<SankeyDemoProps>
title="Sankey"
description="<Sankey.Sankey />"
exampleProps={exampleProps}
exampleRenderer={Sankey}
exampleUrl="/sankey"
tileStyles={tileStyles}
detailsStyles={detailsStyles}
/>
);
}
2 changes: 2 additions & 0 deletions packages/visx-demo/src/components/Gallery/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import * as PolygonsTile from './PolygonsTile';
import * as RadarTile from './RadarTile';
import * as RadialBarsTile from './RadialBarsTile';
import * as ResponsiveTile from './ResponsiveTile';
import * as SankeyTile from './SankeyTile';
import * as SplitLinePathTile from './SplitLinePathTile';
import * as StackedAreasTile from './StackedAreasTile';
import * as StatsPlotTile from './StatsPlotTile';
Expand Down Expand Up @@ -98,6 +99,7 @@ export const tiles = [
RadarTile,
RadialBarsTile,
ResponsiveTile,
SankeyTile,
SplitLinePathTile,
StatsPlotTile,
TextTile,
Expand Down
6 changes: 6 additions & 0 deletions packages/visx-demo/src/components/PackageList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ export default function PackageList({
</Link>
{!compact && <p>Animated visx primitives</p>}
</li>
<li className={cx(emphasizePackage === 'sankey' && 'emphasize')}>
<Link href="/docs/sankey">
<a>sankey</a>
</Link>
{!compact && <p>Components to visualize sankey charts</p>}
</li>
<li className={cx(emphasizePackage === 'stats' && 'emphasize')}>
<Link href="/docs/stats">
<a>stats</a>
Expand Down
21 changes: 21 additions & 0 deletions packages/visx-demo/src/pages/docs/sankey.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import SankeyReadme from '!!raw-loader!../../../../visx-sankey/Readme.md';
import Sankey from '../../../../visx-sankey/src/Sankey';
import DocPage from '../../components/DocPage';
import SankeyTile from '../../components/Gallery/SankeyTile';

const components = [Sankey];

const examples = [SankeyTile];

function SankeyDocs() {
return (
<DocPage
components={components}
examples={examples}
readme={SankeyReadme}
visxPackage="sankey"
/>
);
}
export default SankeyDocs;
19 changes: 19 additions & 0 deletions packages/visx-demo/src/pages/sankey.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import Sankey from '../sandboxes/visx-sankey/Example';
import packageJson from '../sandboxes/visx-sankey/package.json';
import Show from '../components/Show';
import TreemapSource from '!!raw-loader!../sandboxes/visx-sankey/Example';

function SankeyPage() {
return (
<Show
component={Sankey}
title="Sankey"
codeSandboxDirectoryName="visx-sankey"
packageJson={packageJson}
>
{TreemapSource}
</Show>
);
}
export default SankeyPage;
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import radarPackageJson from './visx-radar/package.json';
import responsivePackageJson from './visx-responsive/package.json';
import lineRadialPackageJson from './visx-shape-line-radial/package.json';
import piePackageJson from './visx-shape-pie/package.json';
import sankeyPackageJson from './visx-sankey/package.json';
import splitLinePathPackageJson from './visx-shape-splitlinepath/package.json';
import stackedAreasPackageJson from './visx-stacked-areas/package.json';
import statsPackageJson from './visx-stats/package.json';
Expand Down Expand Up @@ -78,6 +79,7 @@ const examples = [
polygonsPackageJson,
radarPackageJson,
responsivePackageJson,
sankeyPackageJson,
splitLinePathPackageJson,
stackedAreasPackageJson,
statsPackageJson,
Expand Down
189 changes: 189 additions & 0 deletions packages/visx-demo/src/sandboxes/visx-sankey/Example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import React, { useState } from 'react';
import {
Sankey,
sankeyCenter,
sankeyRight,
sankeyLeft,
sankeyJustify,
SankeyNode,
} from '@visx/sankey';
import { Group } from '@visx/group';
import { BarRounded, LinkHorizontal } from '@visx/shape';
import { useTooltip, TooltipWithBounds } from '@visx/tooltip';
import { localPoint } from '@visx/event';

import energy from './energy.json';

export const background = '#84dccf';
export const color = '#392f5a';

type NodeDatum = { name: string };
type LinkDatum = {};

const nodeAlignments = {
sankeyCenter,
sankeyJustify,
sankeyLeft,
sankeyRight,
} as const;

const defaultMargin = { top: 10, left: 10, right: 10, bottom: 10 };

export type SankeyDemoProps = {
width: number;
height: number;
showControls?: boolean;
margin?: { top: number; right: number; bottom: number; left: number };
};

export default function SankeyDemo({
width,
height,
showControls = true,
margin = defaultMargin,
}: SankeyDemoProps) {
const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } =
useTooltip();
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;

const [nodeAlignment, setTileMethod] = useState<keyof typeof nodeAlignments>('sankeyCenter');
const [nodePadding, setNodePadding] = useState(10);
const [nodeWidth, setNodeWidth] = useState(10);

if (width < 10) return null;

return (
<div>
<style>{`
.visx-sankey-link:hover {
stroke-opacity: 0.7;
}
.visx-sankey-node:hover {
filter: brightness(1.3);
}
.visx-sankey-demo-container {
background: ${background};
padding: ${margin.top}px ${margin.right}px ${margin.bottom}px ${margin.left}px;
border-radius: 5px;
position: relative;
}
.visx-sankey-demo-controls {
font-size: 12px;
}
`}</style>
{showControls && (
<div className="visx-sankey-demo-controls">
<label>
node alignment{' '}
<select
onClick={(e) => e.stopPropagation()}
onChange={(e) => setTileMethod(e.target.value as keyof typeof nodeAlignments)}
value={nodeAlignment}
>
{Object.keys(nodeAlignments).map((alignment) => (
<option key={alignment} value={alignment}>
{alignment}
</option>
))}
</select>
</label>{' '}
<label>
node padding{' '}
<input
type="number"
value={nodePadding}
onChange={(e) => setNodePadding(Number(e.target.value))}
/>
</label>{' '}
<label>
node width{' '}
<input
type="number"
value={nodeWidth}
onChange={(e) => setNodeWidth(Number(e.target.value))}
/>
</label>
</div>
)}
<div className="visx-sankey-demo-container">
<svg width={xMax} height={yMax}>
<Sankey<NodeDatum, LinkDatum>
root={energy}
nodeWidth={nodeWidth}
size={[xMax, yMax]}
nodePadding={nodePadding}
nodeAlign={nodeAlignments[nodeAlignment]}
>
{({ graph, createPath }) => (
<>
<Group>
{graph.links.map((link, i) => (
<LinkHorizontal
key={i}
className="visx-sankey-link"
data={link}
path={createPath}
fill="transparent"
stroke={color}
strokeWidth={link.width}
strokeOpacity={0.5}
onPointerMove={(event) => {
const coords = localPoint(
(event.target as SVGElement).ownerSVGElement,
event,
);
showTooltip({
tooltipData: `${
(link.source as SankeyNode<NodeDatum, LinkDatum>).name
} > ${(link.target as SankeyNode<NodeDatum, LinkDatum>).name} = ${
link.value
}`,
tooltipTop: (coords?.y ?? 0) + 10,
tooltipLeft: (coords?.x ?? 0) + 10,
});
}}
onMouseOut={hideTooltip}
/>
))}
</Group>
<Group>
{graph.nodes.map(({ y0, y1, x0, x1, name }, i) => (
<BarRounded
key={i}
className="visx-sankey-node"
width={x1 - x0}
height={y1 - y0}
x={x0}
y={y0}
radius={3}
all
fill={color}
onPointerMove={(event) => {
const coords = localPoint(
(event.target as SVGElement).ownerSVGElement,
event,
);
showTooltip({
tooltipData: name,
tooltipTop: (coords?.y ?? 0) + 10,
tooltipLeft: (coords?.x ?? 0) + 10,
});
}}
onMouseOut={hideTooltip}
/>
))}
</Group>
</>
)}
</Sankey>
</svg>
{tooltipOpen && (
<TooltipWithBounds key={Math.random()} top={tooltipTop} left={tooltipLeft}>
{tooltipData}
</TooltipWithBounds>
)}
</div>
</div>
);
}
1 change: 1 addition & 0 deletions packages/visx-demo/src/sandboxes/visx-sankey/energy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"nodes":[{"name":"Agricultural 'waste'"},{"name":"Bio-conversion"},{"name":"Liquid"},{"name":"Losses"},{"name":"Solid"},{"name":"Gas"},{"name":"Biofuel imports"},{"name":"Biomass imports"},{"name":"Coal imports"},{"name":"Coal"},{"name":"Coal reserves"},{"name":"District heating"},{"name":"Industry"},{"name":"Heating and cooling - commercial"},{"name":"Heating and cooling - homes"},{"name":"Electricity grid"},{"name":"Over generation / exports"},{"name":"H2 conversion"},{"name":"Road transport"},{"name":"Agriculture"},{"name":"Rail transport"},{"name":"Lighting & appliances - commercial"},{"name":"Lighting & appliances - homes"},{"name":"Gas imports"},{"name":"Ngas"},{"name":"Gas reserves"},{"name":"Thermal generation"},{"name":"Geothermal"},{"name":"H2"},{"name":"Hydro"},{"name":"International shipping"},{"name":"Domestic aviation"},{"name":"International aviation"},{"name":"National navigation"},{"name":"Marine algae"},{"name":"Nuclear"},{"name":"Oil imports"},{"name":"Oil"},{"name":"Oil reserves"},{"name":"Other waste"},{"name":"Pumped heat"},{"name":"Solar PV"},{"name":"Solar Thermal"},{"name":"Solar"},{"name":"Tidal"},{"name":"UK land based bioenergy"},{"name":"Wave"},{"name":"Wind"}],"links":[{"source":0,"target":1,"value":124.729},{"source":1,"target":2,"value":0.597},{"source":1,"target":3,"value":26.862},{"source":1,"target":4,"value":280.322},{"source":1,"target":5,"value":81.144},{"source":6,"target":2,"value":35},{"source":7,"target":4,"value":35},{"source":8,"target":9,"value":11.606},{"source":10,"target":9,"value":63.965},{"source":9,"target":4,"value":75.571},{"source":11,"target":12,"value":10.639},{"source":11,"target":13,"value":22.505},{"source":11,"target":14,"value":46.184},{"source":15,"target":16,"value":104.453},{"source":15,"target":14,"value":113.726},{"source":15,"target":17,"value":27.14},{"source":15,"target":12,"value":342.165},{"source":15,"target":18,"value":37.797},{"source":15,"target":19,"value":4.412},{"source":15,"target":13,"value":40.858},{"source":15,"target":3,"value":56.691},{"source":15,"target":20,"value":7.863},{"source":15,"target":21,"value":90.008},{"source":15,"target":22,"value":93.494},{"source":23,"target":24,"value":40.719},{"source":25,"target":24,"value":82.233},{"source":5,"target":13,"value":0.129},{"source":5,"target":3,"value":1.401},{"source":5,"target":26,"value":151.891},{"source":5,"target":19,"value":2.096},{"source":5,"target":12,"value":48.58},{"source":27,"target":15,"value":7.013},{"source":17,"target":28,"value":20.897},{"source":17,"target":3,"value":6.242},{"source":28,"target":18,"value":20.897},{"source":29,"target":15,"value":6.995},{"source":2,"target":12,"value":121.066},{"source":2,"target":30,"value":128.69},{"source":2,"target":18,"value":135.835},{"source":2,"target":31,"value":14.458},{"source":2,"target":32,"value":206.267},{"source":2,"target":19,"value":3.64},{"source":2,"target":33,"value":33.218},{"source":2,"target":20,"value":4.413},{"source":34,"target":1,"value":4.375},{"source":24,"target":5,"value":122.952},{"source":35,"target":26,"value":839.978},{"source":36,"target":37,"value":504.287},{"source":38,"target":37,"value":107.703},{"source":37,"target":2,"value":611.99},{"source":39,"target":4,"value":56.587},{"source":39,"target":1,"value":77.81},{"source":40,"target":14,"value":193.026},{"source":40,"target":13,"value":70.672},{"source":41,"target":15,"value":59.901},{"source":42,"target":14,"value":19.263},{"source":43,"target":42,"value":19.263},{"source":43,"target":41,"value":59.901},{"source":4,"target":19,"value":0.882},{"source":4,"target":26,"value":400.12},{"source":4,"target":12,"value":46.477},{"source":26,"target":15,"value":525.531},{"source":26,"target":3,"value":787.129},{"source":26,"target":11,"value":79.329},{"source":44,"target":15,"value":9.452},{"source":45,"target":1,"value":182.01},{"source":46,"target":15,"value":19.013},{"source":47,"target":15,"value":289.366}]}
12 changes: 12 additions & 0 deletions packages/visx-demo/src/sandboxes/visx-sankey/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
import ParentSize from '@visx/responsive/lib/components/ParentSize';

import Example from './Example';
import './sandbox-styles.css';

const root = createRoot(document.getElementById('root')!);

root.render(
<ParentSize>{({ width, height }) => <Example width={width} height={height} />}</ParentSize>,
);
29 changes: 29 additions & 0 deletions packages/visx-demo/src/sandboxes/visx-sankey/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@visx/demo-sankey",
"description": "Standalone visx sankey demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18" ,
"@visx/event": "latest",
"@visx/group": "latest",
"@visx/responsive": "latest",
"@visx/sankey": "latest",
"@visx/shape": "latest",
"@visx/tooltip": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"sankey"
]
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
html,
body,
#root {
height: 100%;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
'Open Sans', 'Helvetica Neue', sans-serif;
line-height: 2em;
}
1 change: 1 addition & 0 deletions packages/visx-demo/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export type VisxPackage =
| 'point'
| 'react-spring'
| 'responsive'
| 'sankey'
| 'scale'
| 'shape'
| 'stats'
Expand Down
3 changes: 3 additions & 0 deletions packages/visx-demo/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@
{
"path": "../visx-responsive"
},
{
"path": "../visx-sankey"
},
{
"path": "../visx-scale"
},
Expand Down
1 change: 1 addition & 0 deletions packages/visx-sankey/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
Loading
Loading