11import { useMemo } from "react" ;
22
3- import { DataPointType , DimensionProp } from "../types" ;
3+ import { DataPointType , DimensionProp , DotsType } from "../types" ;
44import { COLOR_PALETTE , DEFAULT_COLUMNS , DEFAULT_ROWS } from "../constants" ;
5- import { isColorAlreadyUsed } from "../utils/utils" ;
5+ import {
6+ isColorAlreadyUsed ,
7+ isDecimal ,
8+ mergeAndSortById
9+ } from "../utils/utils" ;
610
711export const useDotMatrix = (
812 dataPoints : DataPointType [ ] ,
913 dimensions : DimensionProp
10- ) : [ DataPointType [ ] , number , number [ ] ] => {
11- const [ dotsToBeMapped , totalDots ] = useMemo ( ( ) => {
14+ ) : DotsType [ ] => {
15+ const [ dotsWithColor , totalDots ] = useMemo ( ( ) => {
1216 const dotMatrixData : DataPointType [ ] = [ ] ;
1317 let totalCount = 0 ;
1418 if ( dataPoints ) {
@@ -25,23 +29,71 @@ export const useDotMatrix = (
2529 dotMatrixData . push ( { ...point , color } ) ;
2630 } ) ;
2731 }
28- return [ dotMatrixData , totalCount ]
32+ return [ dotMatrixData , totalCount ] ;
2933 } , [ dataPoints ] ) ;
3034
31- // Calculates fractional part of a category based on the provided data points
32- // relative to the total number of dots and dimension
33- const fractionalDots : number [ ] = useMemo ( ( ) => {
34- const fractionalParts : Array < number > = [ ] ;
35+ //finding the number of dots to be rendered relative to the total number of dots and dimension
36+ const dots = useMemo ( ( ) => {
37+ const completeDots : number [ ] = [ ] ;
3538 if ( totalDots ) {
36- dotsToBeMapped ?. forEach ( ( point : DataPointType ) => {
39+ dotsWithColor ?. forEach ( ( point : DataPointType ) => {
3740 const { rows = DEFAULT_ROWS , columns = DEFAULT_COLUMNS } = dimensions ;
3841 const pointPercentage = point . count / totalDots ;
3942 const dotsCount = pointPercentage * rows * columns ;
40- const dotFraction = dotsCount - Math . floor ( dotsCount ) ;
41- fractionalParts ?. push ( dotFraction ) ;
43+ completeDots . push ( dotsCount ) ;
4244 } ) ;
4345 }
44- return fractionalParts ;
45- } , [ totalDots ] ) ;
46- return [ dotsToBeMapped , totalDots , fractionalDots ] ;
47- } ;
46+ return completeDots ;
47+ } , [ totalDots , dimensions . columns , dimensions . rows ] ) ;
48+
49+ const dotsToBeMapped = useMemo ( ( ) => {
50+ //Calculating the dots with gradient and subtracting the gradient part from the total number of dots
51+ const currentDots = [ ...dots ] ;
52+ const gradientDots : DotsType [ ] = [ ] ;
53+ for ( let i = 0 ; i < currentDots . length - 1 ; i ++ ) {
54+ if ( isDecimal ( currentDots [ i ] ) ) {
55+ const roundedCurrentDotCount = Math . floor ( currentDots [ i ] ) ;
56+ let remainingDecimal =
57+ 1 - ( currentDots [ i ] - roundedCurrentDotCount ) ;
58+ const gradientColors = [ dotsWithColor [ i ] . color ] ;
59+ const percentage = [ currentDots [ i ] - roundedCurrentDotCount ] ;
60+ let j = i + 1 ;
61+ while ( remainingDecimal !== 0 && j < currentDots . length ) {
62+ if ( currentDots [ j ] >= remainingDecimal ) {
63+ percentage . push ( remainingDecimal ) ;
64+ currentDots [ j ] = currentDots [ j ] - remainingDecimal ;
65+ remainingDecimal = 0 ;
66+ } else {
67+ remainingDecimal = remainingDecimal - dots [ j ] ;
68+ percentage . push ( currentDots [ j ] - Math . floor ( currentDots [ j ] ) ) ;
69+ currentDots [ j ] = 0 ;
70+ }
71+ currentDots [ i ] = roundedCurrentDotCount ;
72+ gradientColors . push ( dotsWithColor [ j ] . color ) ;
73+ j ++ ;
74+ }
75+ gradientDots . push ( {
76+ id : i ,
77+ count : 1 ,
78+ name : dotsWithColor [ i ] . name ,
79+ gradientColors : gradientColors ,
80+ gradientPercentage : percentage
81+ } ) ;
82+ }
83+ }
84+ //Calculating the remaining dots with single color
85+ const singleDots : DotsType [ ] = [ ] ;
86+ for ( let i = 0 ; i < currentDots . length ; i ++ ) {
87+ singleDots . push ( {
88+ id : i ,
89+ name : dotsWithColor [ i ] . name ,
90+ count : Math . round ( currentDots [ i ] ) ,
91+ color : dotsWithColor [ i ] . color
92+ } ) ;
93+ }
94+ //merging both arrays and sorting it with respect to id
95+ return mergeAndSortById ( gradientDots , singleDots ) ;
96+ } , [ dataPoints , dimensions . rows , dimensions . columns ] ) ;
97+
98+ return dotsToBeMapped ;
99+ } ;
0 commit comments