@@ -104,6 +104,25 @@ const calculateNormalLayoutHeight = (totalLangs) => {
104
104
return 45 + ( totalLangs + 1 ) * 40 ;
105
105
} ;
106
106
107
+ /**
108
+ * Calculates height for the pie layout.
109
+ *
110
+ * @param {number } totalLangs Total number of languages.
111
+ * @returns {number } Card height.
112
+ */
113
+ const calculatePieLayoutHeight = ( totalLangs ) => {
114
+ return 215 + Math . max ( totalLangs - 5 , 0 ) * 32 ;
115
+ } ;
116
+
117
+ /**
118
+ * Calculates the center translation needed to keep the doughnut chart centred.
119
+ * @param {number } totalLangs Total number of languages.
120
+ * @returns {number } Doughnut center translation.
121
+ */
122
+ const doughnutCenterTranslation = ( totalLangs ) => {
123
+ return - 45 + Math . max ( totalLangs - 5 , 0 ) * 16 ;
124
+ } ;
125
+
107
126
/**
108
127
* Trim top languages to lang_count while also hiding certain languages.
109
128
*
@@ -334,7 +353,6 @@ const createDoughnutPaths = (cx, cy, radius, percentages) => {
334
353
const paths = [ ] ;
335
354
let startAngle = 0 ;
336
355
let endAngle = 0 ;
337
- let doughnutPercent = 0 ;
338
356
339
357
const totalPercent = percentages . reduce ( ( acc , curr ) => acc + curr , 0 ) ;
340
358
for ( let i = 0 ; i < percentages . length ; i ++ ) {
@@ -343,7 +361,6 @@ const createDoughnutPaths = (cx, cy, radius, percentages) => {
343
361
let percent = parseFloat (
344
362
( ( percentages [ i ] / totalPercent ) * 100 ) . toFixed ( 2 ) ,
345
363
) ;
346
- doughnutPercent += percent ;
347
364
348
365
endAngle = 3.6 * percent + startAngle ;
349
366
const startPoint = polarToCartesian ( cx , cy , radius , endAngle - 90 ) ; // rotate doughnut 90 degrees counter-clockwise.
@@ -386,9 +403,12 @@ const renderDoughnutLayout = (langs, width, totalLanguageSize) => {
386
403
langsPercents ,
387
404
) ;
388
405
389
- const doughnutPaths = langPaths
390
- . map ( ( section , i ) => {
391
- const output = `
406
+ const doughnutPaths =
407
+ langs . length === 1
408
+ ? `<circle cx="${ centerX } " cy="${ centerY } " r="${ radius } " stroke="${ colors [ 0 ] } " fill="none" stroke-width="${ strokeWidth } " data-testid="lang-doughnut" size="100"/>`
409
+ : langPaths
410
+ . map ( ( section , i ) => {
411
+ const output = `
392
412
<g>
393
413
<path
394
414
data-testid="lang-doughnut"
@@ -401,9 +421,9 @@ const renderDoughnutLayout = (langs, width, totalLanguageSize) => {
401
421
</g>
402
422
` ;
403
423
404
- return output ;
405
- } )
406
- . join ( "" ) ;
424
+ return output ;
425
+ } )
426
+ . join ( "" ) ;
407
427
408
428
const donut = `<svg width="${ width } " height="${ width } ">${ doughnutPaths } </svg>` ;
409
429
@@ -413,7 +433,7 @@ const renderDoughnutLayout = (langs, width, totalLanguageSize) => {
413
433
${ createDoughnutLanguagesNode ( { langs, totalSize : totalLanguageSize } ) }
414
434
</g>
415
435
416
- <g transform="translate(125, -45 )">
436
+ <g transform="translate(125, ${ doughnutCenterTranslation ( langs . length ) } )">
417
437
${ donut }
418
438
</g>
419
439
</g>
@@ -469,7 +489,7 @@ const renderTopLanguages = (topLangs, options = {}) => {
469
489
height = calculateCompactLayoutHeight ( langs . length ) ;
470
490
finalLayout = renderCompactLayout ( langs , width , totalLanguageSize ) ;
471
491
} else if ( layout ?. toLowerCase ( ) === "pie" ) {
472
- height = height - 60 ; // padding
492
+ height = calculatePieLayoutHeight ( langs . length ) ;
473
493
width = width + 50 ; // padding
474
494
finalLayout = renderDoughnutLayout ( langs , width , totalLanguageSize ) ;
475
495
} else {
@@ -516,6 +536,8 @@ export {
516
536
cartesianToPolar ,
517
537
calculateCompactLayoutHeight ,
518
538
calculateNormalLayoutHeight ,
539
+ calculatePieLayoutHeight ,
540
+ doughnutCenterTranslation ,
519
541
trimTopLanguages ,
520
542
renderTopLanguages ,
521
543
MIN_CARD_WIDTH ,
0 commit comments