@@ -13,20 +13,22 @@ import {
1313} from 'recharts' ;
1414import type { SankeyData } from 'recharts/types/chart/Sankey' ;
1515
16- import { getColorScale } from '#components/reports/chart-theme' ;
1716import { Container } from '#components/reports/Container' ;
1817import { useFormat } from '#hooks/useFormat' ;
1918import { usePrivacyMode } from '#hooks/usePrivacyMode' ;
2019
2120type SankeyGraphNode = SankeyData [ 'nodes' ] [ number ] & {
22- hasChildren ?: boolean ;
23- isCollapsed ?: boolean ;
24- toBudget ?: number ;
25- isNegative ?: boolean ;
26- actualValue ?: number ;
21+ value : number ;
2722 percentageLabel ?: string ;
28- targetLinks ?: Array < Record < string , unknown > > ;
29- sourceLinks ?: Array < Record < string , unknown > > ;
23+ key : string ;
24+ color ?: string ;
25+ } ;
26+
27+ type SankeyLinkPayload = {
28+ source : SankeyGraphNode ;
29+ target : SankeyGraphNode ;
30+ value : number ;
31+ color ?: string ;
3032} ;
3133
3234type SankeyLinkProps = {
@@ -38,16 +40,10 @@ type SankeyLinkProps = {
3840 targetControlX : number ;
3941 linkWidth : number ;
4042 index : number ;
41- payload : {
42- source : SankeyGraphNode ;
43- target : SankeyGraphNode ;
44- value : number ;
45- isNegative ?: boolean ;
46- } ;
43+ payload : SankeyLinkPayload ;
4744 isHovered : boolean ;
4845 onMouseEnter : ( ) => void ;
4946 onMouseLeave : ( ) => void ;
50- color : string ;
5147} ;
5248
5349function SankeyLink ( {
@@ -62,9 +58,11 @@ function SankeyLink({
6258 isHovered,
6359 onMouseEnter,
6460 onMouseLeave,
65- color,
6661} : SankeyLinkProps ) {
67- const linkColor = payload . isNegative ? theme . errorText : color ;
62+ if ( payload . value <= 0 ) {
63+ return null ;
64+ }
65+ const linkColor = payload . color ?? theme . reportsGray ;
6866 const strokeWidth = linkWidth ;
6967 const strokeOpacity = isHovered ? 1 : 0.6 ;
7068
@@ -91,8 +89,8 @@ type SankeyNodeProps = {
9189 index : number ;
9290 payload : SankeyGraphNode ;
9391 containerWidth : number ;
94- containerHeight : number ;
9592 showPercentages ?: boolean ;
93+ color ?: string ;
9694} ;
9795function SankeyNode ( {
9896 x,
@@ -102,21 +100,17 @@ function SankeyNode({
102100 index : _index ,
103101 payload,
104102 containerWidth,
105- containerHeight,
106103 showPercentages,
107104} : SankeyNodeProps ) {
108105 const privacyMode = usePrivacyMode ( ) ;
109106 const format = useFormat ( ) ;
110- const isOut = x + width + 6 > containerWidth ;
111107
112- const fillColor = payload . isNegative ? theme . errorText : theme . reportsBlue ;
108+ if ( payload . value <= 0 ) {
109+ return null ;
110+ }
111+ const isOut = x + width + 6 > containerWidth ;
113112
114- const toBudget = payload . toBudget ?? 0 ;
115- const availableBelow = Math . max ( 0 , containerHeight - 25 - ( y + height ) ) ;
116- const proportionalHeight =
117- toBudget > 0 && payload . value ? height * ( toBudget / payload . value ) : 0 ;
118- const isClamped = proportionalHeight > availableBelow ;
119- const toBudgetHeight = Math . min ( proportionalHeight , availableBelow ) ;
113+ const fillColor = payload . color ?? theme . reportsBlue ;
120114
121115 const renderText = (
122116 text : string ,
@@ -142,27 +136,6 @@ function SankeyNode({
142136 return (
143137 < Layer >
144138 < Rectangle x = { x } y = { y } width = { width } height = { height } fill = { fillColor } />
145- { toBudgetHeight > 0 &&
146- ( isClamped ? (
147- < polygon
148- points = { `
149- ${ x } ,${ y + height }
150- ${ x + width } ,${ y + height }
151- ${ x + width } ,${ y + height + toBudgetHeight - 8 }
152- ${ x + width / 2 } ,${ y + height + toBudgetHeight }
153- ${ x } ,${ y + height + toBudgetHeight - 8 }
154- ` }
155- fill = { theme . toBudgetPositive }
156- />
157- ) : (
158- < Rectangle
159- x = { x }
160- y = { y + height }
161- width = { width }
162- height = { toBudgetHeight }
163- fill = { theme . toBudgetPositive }
164- />
165- ) ) }
166139 { renderText ( payload . name || '' , height / 2 ) }
167140 { renderText (
168141 showPercentages && payload . percentageLabel
@@ -173,24 +146,6 @@ function SankeyNode({
173146 0.5 ,
174147 privacyMode ? t ( 'Redacted Script' ) : undefined ,
175148 ) }
176- { toBudgetHeight > 0 &&
177- renderText (
178- format ( toBudget , 'financial' ) ,
179- toBudgetHeight / 2 + 13 ,
180- 11 ,
181- 0.5 ,
182- privacyMode ? t ( 'Redacted Script' ) : undefined ,
183- y + height ,
184- ) }
185- { toBudgetHeight > 0 &&
186- renderText (
187- t ( 'To budget' ) ,
188- toBudgetHeight / 2 ,
189- 13 ,
190- 1 ,
191- undefined ,
192- y + height ,
193- ) }
194149 </ Layer >
195150 ) ;
196151}
@@ -199,7 +154,6 @@ type SankeyGraphProps = {
199154 style ?: CSSProperties ;
200155 data : SankeyData ;
201156 showTooltip ?: boolean ;
202- collapsedNodes ?: string [ ] ;
203157 showPercentages ?: boolean ;
204158} ;
205159export function SankeyGraph ( {
@@ -212,19 +166,6 @@ export function SankeyGraph({
212166 const format = useFormat ( ) ;
213167 const [ hoveredLinkIndex , setHoveredLinkIndex ] = useState < number | null > ( null ) ;
214168
215- const colors = getColorScale ( 'qualitative' ) ;
216- const sourceColorMap = new Map (
217- [
218- ...new Set (
219- data . links
220- . filter ( l => ( l . source as number ) !== 0 )
221- . map ( l => data . nodes [ l . source as number ] ?. name ) ,
222- ) ,
223- ]
224- . filter ( Boolean )
225- . map ( ( name , i ) => [ name , colors [ i % colors . length ] ] ) ,
226- ) ;
227-
228169 return (
229170 < Container style = { style } >
230171 { ( width , height ) => (
@@ -235,7 +176,6 @@ export function SankeyGraph({
235176 < SankeyNode
236177 { ...props }
237178 containerWidth = { width }
238- containerHeight = { height }
239179 showPercentages = { showPercentages }
240180 />
241181 ) }
@@ -245,10 +185,6 @@ export function SankeyGraph({
245185 isHovered = { hoveredLinkIndex === props . index }
246186 onMouseEnter = { ( ) => setHoveredLinkIndex ( props . index ) }
247187 onMouseLeave = { ( ) => setHoveredLinkIndex ( null ) }
248- color = {
249- sourceColorMap . get ( props . payload . source . name ) ??
250- theme . reportsGray
251- }
252188 />
253189 ) }
254190 sort = { false }
0 commit comments