@@ -46,7 +46,26 @@ export default {
4646 isStackNormalized ( ) : boolean {
4747 const { config} = this ;
4848
49- return ! ! ( config . data_stack_normalize && config . data_groups . length ) ;
49+ return ! ! (
50+ ( config . data_stack_normalize === true ||
51+ isObjectType ( config . data_stack_normalize ) ) &&
52+ config . data_groups . length
53+ ) ;
54+ } ,
55+
56+ /**
57+ * Check if stack normalization should be applied per group
58+ * @returns {boolean }
59+ * @private
60+ */
61+ isStackNormalizedPerGroup ( ) : boolean {
62+ const { config} = this ;
63+
64+ return ! ! (
65+ isObjectType ( config . data_stack_normalize ) &&
66+ config . data_stack_normalize ?. perGroup &&
67+ config . data_groups . length
68+ ) ;
5069 } ,
5170
5271 /**
@@ -61,6 +80,26 @@ export default {
6180 return id ? groups . some ( v => v . indexOf ( id ) >= 0 && v . length > 1 ) : groups . length > 0 ;
6281 } ,
6382
83+ /**
84+ * Check if the given axis has any grouped data
85+ * @param {string } axisId Axis ID (e.g., "y", "y2")
86+ * @returns {boolean } true if axis has grouped data
87+ * @private
88+ */
89+ hasAxisGroupedData ( axisId : "y" | "y2" ) : boolean {
90+ const $$ = this ;
91+ const { axis} = $$ ;
92+ const targets = $$ . data . targets ;
93+
94+ // Get all data IDs that belong to this axis
95+ const axisDataIds = targets
96+ . filter ( t => axis . getId ( t . id ) === axisId )
97+ . map ( t => t . id ) ;
98+
99+ // Check if any of the axis data IDs are in groups
100+ return axisDataIds . some ( id => $$ . isGrouped ( id ) ) ;
101+ } ,
102+
64103 getXKey ( id ) {
65104 const $$ = this ;
66105 const { config} = $$ ;
@@ -325,18 +364,37 @@ export default {
325364
326365 /**
327366 * Get sum of data per index
367+ * @param {string } targetId Target ID to get total for (only for normalized stack per group)
328368 * @private
329369 * @returns {Array }
330370 */
331- getTotalPerIndex ( ) {
371+ getTotalPerIndex ( targetId ?: string ) {
332372 const $$ = this ;
333- const cacheKey = KEY . dataTotalPerIndex ;
373+ const { config} = $$ ;
374+ const cacheKey = targetId ? `${ KEY . dataTotalPerIndex } -${ targetId } ` : KEY . dataTotalPerIndex ;
334375 let sum = $$ . cache . get ( cacheKey ) ;
335376
336377 if ( ( $$ . config . data_groups . length || $$ . isStackNormalized ( ) ) && ! sum ) {
337378 sum = [ ] ;
338379
339- $$ . data . targets . forEach ( row => {
380+ // When normalize per group is enabled and targetId is provided,
381+ // only sum data within the same group
382+ let { targets} = $$ . data ;
383+
384+ if ( $$ . isStackNormalizedPerGroup ( ) && targetId ) {
385+ // Find which group the target belongs to
386+ const group = config . data_groups . find ( g => g . indexOf ( targetId ) >= 0 ) ;
387+
388+ if ( group ) {
389+ // Only sum targets in the same group
390+ targets = targets . filter ( t => group . indexOf ( t . id ) >= 0 ) ;
391+ } else {
392+ // If target is not in any group, return null to indicate no normalization
393+ return null ;
394+ }
395+ }
396+
397+ targets . forEach ( row => {
340398 row . values . forEach ( ( v , i ) => {
341399 if ( ! sum [ i ] ) {
342400 sum [ i ] = 0 ;
@@ -345,6 +403,8 @@ export default {
345403 sum [ i ] += ~ ~ v . value ;
346404 } ) ;
347405 } ) ;
406+
407+ $$ . cache . add ( cacheKey , sum ) ;
348408 }
349409
350410 return sum ;
@@ -489,7 +549,7 @@ export default {
489549 } ,
490550
491551 /**
492- * Add to the state target Ids
552+ * Add to thetarget Ids
493553 * @param {string } type State's prop name
494554 * @param {Array|string } targetIds Target ids array
495555 * @private
@@ -1014,16 +1074,39 @@ export default {
10141074 }
10151075 } else if ( type === "index" ) {
10161076 const dataValues = api . data . values . bind ( api ) ;
1017- let total = this . getTotalPerIndex ( ) ;
1077+ const { hiddenTargetIds } = state ;
10181078
1019- if ( state . hiddenTargetIds . length ) {
1020- let hiddenSum = dataValues ( state . hiddenTargetIds , false ) ;
1079+ // For normalized stack per group, get total per group
1080+ let total = this . getTotalPerIndex (
1081+ $$ . isStackNormalizedPerGroup ( ) ? d . id : undefined
1082+ ) ;
1083+
1084+ // If total is null, the data is not in any group - don't normalize
1085+ if ( total === null ) {
1086+ return ratio ;
1087+ }
10211088
1022- if ( hiddenSum . length ) {
1023- hiddenSum = hiddenSum
1024- . reduce ( ( acc , curr ) => acc . map ( ( v , i ) => ~ ~ v + curr [ i ] ) ) ;
1089+ if ( hiddenTargetIds . length ) {
1090+ // When normalized per group, only subtract hidden data from the same group
1091+ let hiddenIds = hiddenTargetIds ;
10251092
1026- total = total . map ( ( v , i ) => v - hiddenSum [ i ] ) ;
1093+ if ( $$ . isStackNormalizedPerGroup ( ) && d . id ) {
1094+ const group = config . data_groups . find ( g => g . indexOf ( d . id ) >= 0 ) ;
1095+ if ( group ) {
1096+ // Only consider hidden IDs in the same group
1097+ hiddenIds = hiddenIds . filter ( id => group . indexOf ( id ) >= 0 ) ;
1098+ }
1099+ }
1100+
1101+ if ( hiddenIds . length ) {
1102+ let hiddenSum = dataValues ( hiddenIds , false ) ;
1103+
1104+ if ( hiddenSum . length ) {
1105+ hiddenSum = hiddenSum
1106+ . reduce ( ( acc , curr ) => acc . map ( ( v , i ) => ~ ~ v + curr [ i ] ) ) ;
1107+
1108+ total = total . map ( ( v , i ) => v - hiddenSum [ i ] ) ;
1109+ }
10271110 }
10281111 }
10291112
0 commit comments