@@ -107,7 +107,7 @@ function defineC3(){
107
107
'horizontal-bar' ,
108
108
'horizontal-line' ,
109
109
'horizontal-step' ,
110
- 'horizontal-spline'
110
+ 'horizontal-spline' ,
111
111
] ;
112
112
113
113
const getPaddings = ( element , paddingName ) => {
@@ -185,6 +185,24 @@ function defineC3(){
185
185
render : function ( ) {
186
186
const options = getDefaultOptions . call ( this ) ;
187
187
188
+ // 100% for charts
189
+ const sumArray = calculateSumForPercents ( this . dataset . matrix ) ;
190
+ let oldMatrix = [ ] ;
191
+ if ( options . stacking === 'percent' && ( type === 'bar' || type === 'horizontal-bar' || type === 'area' || type === 'area-step' || type === 'area-spline' ) ) {
192
+ oldMatrix = this . dataset . matrix ;
193
+ this . dataset . matrix = [ this . dataset . matrix [ 0 ] , ...calculatePercents ( this . dataset . matrix , sumArray ) ] ;
194
+ options . axis = {
195
+ y : {
196
+ padding : {
197
+ top : 0 ,
198
+ } ,
199
+ tick : {
200
+ format : d => `${ d } %` ,
201
+ } ,
202
+ } ,
203
+ } ;
204
+ }
205
+
188
206
if ( ! ! this . config . clearOnRender && options . data . columns . length > 0 ) {
189
207
options . data . columns . splice ( 1 ) ;
190
208
}
@@ -282,13 +300,13 @@ function defineC3(){
282
300
if ( results && results . length > 1 ) {
283
301
const partialResultsRegion = {
284
302
axis : 'x' ,
285
- start : new Date ( results [ results . length - 2 ] ) ,
303
+ start : new Date ( results [ results . length - 2 ] ) ,
286
304
class : options . partialIntervalIndicator . className
287
305
} ;
288
306
options . regions = [ ...( options . regions || [ ] ) , partialResultsRegion ] ;
289
307
}
290
308
}
291
-
309
+
292
310
if (
293
311
! ( options . tooltip && options . tooltip . show === false )
294
312
&&
@@ -297,6 +315,7 @@ function defineC3(){
297
315
&& options . legend . tooltip
298
316
&& options . legend . tooltip . show )
299
317
) ) {
318
+
300
319
// Apply custom tooltip
301
320
options . tooltip = {
302
321
contents : c3TooltipContents ,
@@ -307,6 +326,18 @@ function defineC3(){
307
326
if ( this . config . tooltip && this . config . tooltip . format && this . config . tooltip . format . value )
308
327
{
309
328
valueFormatted = this . config . tooltip . format . value . call ( this , valueFormatted , ratio , id , index ) ;
329
+ // Restore value from percents calculation for stacking 100% charts
330
+ if ( options . stacking === 'percent' && ( type === 'bar' || type === 'horizontal-bar' || type === 'area'
331
+ || type === 'area-step' || type === 'area-spline' ) ) {
332
+ valueFormatted = parseFloat ( ( ( valueFormatted / 100 ) * sumArray [ index ] ) . toFixed ( 2 ) ) ;
333
+ }
334
+ return valueFormatted ;
335
+ }
336
+ // Restore value from percents calculation for stacking 100% charts
337
+ if ( options . stacking === 'percent' && ( type === 'bar' || type === 'horizontal-bar' || type === 'area'
338
+ || type === 'area-step' || type === 'area-spline' ) ) {
339
+ valueFormatted = ( ( valueFormatted / 100 ) * sumArray [ index ] ) . toFixed ( 2 ) ;
340
+ return parseFloat ( valueFormatted ) ;
310
341
}
311
342
return valueFormatted ;
312
343
}
@@ -422,3 +453,30 @@ function bindResizeListener(fn){
422
453
window . attachEvent ( 'onresize' , fn ) ;
423
454
}
424
455
}
456
+
457
+ function calculateSumForPercents ( matrix ) {
458
+ const sumArray = [ ] ;
459
+ matrix . slice ( 1 ) . forEach ( ( d , i ) => {
460
+ d . forEach ( ( e ) => {
461
+ if ( typeof e === 'number' ) {
462
+ if ( ! sumArray [ i ] ) {
463
+ sumArray [ i ] = e ;
464
+ return sumArray [ i ] ;
465
+ }
466
+ sumArray [ i ] += e ;
467
+ }
468
+ return sumArray [ i ] ;
469
+ } ) ;
470
+ } ) ;
471
+ return sumArray ;
472
+ }
473
+
474
+ function calculatePercents ( matrix , sumArray ) {
475
+ const newValues = matrix . slice ( 1 ) . map ( ( d , i ) => d . map ( ( e ) => {
476
+ if ( typeof e === 'number' ) {
477
+ return ( e / sumArray [ i ] ) * 100 ;
478
+ }
479
+ return e ;
480
+ } ) ) ;
481
+ return newValues ;
482
+ }
0 commit comments