11import {
2- IChartElement ,
32 IGetIntervalAndYPointsReturnType ,
4- ITransaction ,
5- IUseWaterfallChartReturnType
3+ ITransaction
64} from '../types/types' ;
75
8- export const useWaterfallChart = (
9- transactions : Array < ITransaction > ,
10- chartHeight : number ,
11- yAxisPixelsPerUnit : number ,
12- showFinalSummary : boolean
13- ) : IUseWaterfallChartReturnType => {
14- const largestCumulativeVal = getLargestCumulativeSum ( transactions ) ; // this will be the highest y point in the graph
15- const smallestCumulativeVal = getSmallestCumulativeSum ( transactions ) ;
16- let chartElements : Array < IChartElement > = [ ] ;
17-
18- const maxLabelsCount = Math . ceil ( chartHeight / yAxisPixelsPerUnit ) ;
19-
20- let yAxisPoints : Array < number > = [ ] ;
21- let yAxisScale = 0 ;
22- let lowestYAxisValue = 0 ;
23- let yValueForZeroLine = 0 ;
24-
25- if ( chartHeight && chartHeight > 0 ) {
26- const InterValAndYPoints = getIntervalAndYPoints ( smallestCumulativeVal , largestCumulativeVal , maxLabelsCount ) ;
27- yAxisPoints = InterValAndYPoints ?. yAxisPoints ;
28- yAxisScale = InterValAndYPoints ?. yAxisScale ;
29- lowestYAxisValue = InterValAndYPoints ?. yAxisPoints [ 0 ] ;
30- // yAxisScale is the number of Y units per 30px
31- // lowestYAxisValue is the yAxisValue for origin (0, 0)
32-
33- yValueForZeroLine = chartHeight - ( Math . abs ( lowestYAxisValue ) / yAxisScale ) * yAxisPixelsPerUnit ;
34- let cumulativeSum = 0 ;
35-
36- chartElements = transactions . map ( ( transaction ) => {
37- const { label, value } = transaction ;
38- let yVal = 0 ;
39- const barHeight = ( value / yAxisScale ) * yAxisPixelsPerUnit ;
40- const offsetHeight = ( cumulativeSum / yAxisScale ) * yAxisPixelsPerUnit ;
41- // minimum distance from zero line to the floating bar for the transaction
42- if ( value < 0 ) {
43- yVal = yValueForZeroLine - offsetHeight ;
44- } else yVal = yValueForZeroLine - ( offsetHeight + barHeight ) ;
45-
46- cumulativeSum += value ;
47-
48- return { name : label , value, yVal, cumulativeSum, barHeight : Math . abs ( barHeight ) } ;
49- } ) ;
50- }
51-
52- const calculateBarWidth = ( chartWidth : number ) : number => {
53- let barWidth = 0 ;
54- if ( chartWidth && transactions ?. length > 0 ) {
55- if ( showFinalSummary ) barWidth = chartWidth / ( 2 * transactions ?. length + 2 ) ;
56- else barWidth = chartWidth / ( 2 * transactions ?. length + 1 ) ;
57- }
58- return barWidth ;
59- } ;
60-
61- return { chartElements, yValueForZeroLine, yAxisPoints, yAxisScale, calculateBarWidth } ;
62- } ;
63-
64- function getLargestCumulativeSum ( arr : Array < ITransaction > ) : number {
6+ export function getLargestCumulativeSum ( arr : Array < ITransaction > ) : number {
657 let maxSum = arr [ 0 ] ?. value ; // Initialize maxSum and currentSum with the first element of the array
668 let currentSum = arr [ 0 ] ?. value ;
679
@@ -74,7 +16,7 @@ function getLargestCumulativeSum(arr: Array<ITransaction>): number {
7416 return maxSum ;
7517}
7618
77- function getSmallestCumulativeSum ( arr : Array < ITransaction > ) : number {
19+ export function getSmallestCumulativeSum ( arr : Array < ITransaction > ) : number {
7820 let minSum = arr [ 0 ] ?. value ; // Initialize minSum and currentSum with the first element of the array
7921 let currentSum = arr [ 0 ] ?. value ;
8022
@@ -89,15 +31,15 @@ function getSmallestCumulativeSum(arr: Array<ITransaction>): number {
8931 return minSum ;
9032}
9133
92- function roundMinVal ( minVal : number , range : number ) : number {
34+ export function roundMinVal ( minVal : number , range : number ) : number {
9335 return Math . floor ( minVal / range ) * range ;
9436}
9537
9638function roundMaxVal ( maxVal : number , range : number ) : number {
9739 return Math . ceil ( maxVal / range ) * range ;
9840}
9941
100- function getIntervalAndYPoints (
42+ export function getIntervalAndYPoints (
10143 minVal : number ,
10244 maxVal : number ,
10345 maxLabelsCount : number
@@ -129,7 +71,7 @@ function getIntervalAndYPoints(
12971 return { yAxisScale, yAxisPoints } ;
13072}
13173
132- function checkIfScaleSufficient ( scale : number , maxLabelsCount : number , valueRange : number ) : boolean {
74+ export function checkIfScaleSufficient ( scale : number , maxLabelsCount : number , valueRange : number ) : boolean {
13375 if ( maxLabelsCount === 0 ) return true ; // to stop the while loop from checking for sufficient scale with zero maxLabelsCount
13476 if ( scale * maxLabelsCount >= valueRange ) return true ;
13577 return false ;
0 commit comments