@@ -588,31 +588,35 @@ export class SubmissionsService {
588588 }
589589
590590 async generateChartImage ( data : any ) : Promise < string > {
591- const { Chart } = await loadChart ( [
592- 'BarController' , 'DoughnutController' , 'BarElement' , 'ArcElement' , 'LinearScale' , 'CategoryScale' , 'Legend' , 'Tooltip' , 'Title'
593- ] ) ;
594- const { canvas, ctx } = createChartCanvas ( 300 , 400 ) ;
595591 const isBar = data . chartType === 'bar' ;
596592 const isRatingScale = data . isRatingScale || false ;
593+ const { Chart } = await loadChart ( isBar
594+ ? [ 'BarController' , 'BarElement' , 'LinearScale' , 'CategoryScale' , 'Legend' , 'Tooltip' , 'Title' ]
595+ : [ 'DoughnutController' , 'ArcElement' , 'Legend' , 'Tooltip' , 'Title' ]
596+ ) ;
597+ const { canvas, ctx } = createChartCanvas ( 300 , 400 ) ;
597598
598599 if ( ! ctx ) {
599600 return '' ;
600601 }
601602 const hasData = Array . isArray ( data . data ) && data . data . some ( ( value : number ) => Number ( value ) > 0 ) ;
602603
603604 if ( ! hasData ) {
604- renderNoDataPlaceholder ( ctx , canvas , 'No data available' ) ;
605+ return renderNoDataPlaceholder ( ctx , canvas , 'No data available' ) ;
605606 }
606607
607608 const maxCount = Math . max ( ...data . data ) ;
609+ const axisTitleFont = { size : 12 , weight : 'bold' as const } ;
610+ const xAxisText = isRatingScale ? $localize `Rating` : $localize `Choice` ;
611+ const yAxisText = isRatingScale ? $localize `Number of responses` : $localize `% of responders` ;
612+ const backgroundColor = data . labels . map ( ( _ , i ) => CHART_COLORS [ i % CHART_COLORS . length ] ) ;
608613 const chartConfig : ChartConfiguration < 'bar' | 'doughnut' , number [ ] , string > = {
609614 type : isBar ? 'bar' : 'doughnut' ,
610615 data : {
611616 labels : data . labels ,
612617 datasets : [ {
613618 data : data . data ,
614- label : isRatingScale ? 'selection/choices(1-9)' : ( isBar ? '% of responders/selection' : undefined ) ,
615- backgroundColor : CHART_COLORS
619+ backgroundColor
616620 } ]
617621 } ,
618622 options : {
@@ -621,19 +625,24 @@ export class SubmissionsService {
621625 indexAxis : 'x' ,
622626 plugins : {
623627 legend : {
624- display : true ,
628+ display : ! isBar ,
625629 labels : {
626- boxWidth : isBar ? 0 : 50 ,
627- boxHeight : isBar ? 0 : 20
630+ boxWidth : 50 ,
631+ boxHeight : 20
628632 }
629633 }
630634 } ,
631635 scales : isBar ? {
636+ x : {
637+ type : 'category' ,
638+ title : { display : true , text : xAxisText , font : axisTitleFont }
639+ } ,
632640 y : {
633641 type : 'linear' ,
634642 beginAtZero : true ,
635643 max : isRatingScale ? maxCount > 0 ? Math . ceil ( maxCount / 10 ) * 10 : 10 : 100 ,
636- ticks : { precision : 0 , stepSize : 2 }
644+ ticks : { precision : 0 } ,
645+ title : { display : true , text : yAxisText , font : axisTitleFont }
637646 }
638647 } : { } ,
639648 animation : false
@@ -644,11 +653,16 @@ export class SubmissionsService {
644653 try {
645654 chart . update ( ) ;
646655
656+ ctx . fillStyle = '#000000' ;
657+ ctx . textAlign = 'center' ;
658+ ctx . textBaseline = 'middle' ;
659+ ctx . font = '12px sans-serif' ;
660+
647661 if ( isBar && data . userCounts ) {
648662 chart . getDatasetMeta ( 0 ) . data . forEach ( ( bar , index ) => {
649663 const count = data . userCounts [ index ] ;
650664 if ( count > 0 ) {
651- ctx . fillText ( `${ count } ` , bar . x - 2.5 , bar . y ) ;
665+ ctx . fillText ( `${ count } ` , bar . x , bar . y - 6 ) ;
652666 }
653667 } ) ;
654668 } else {
@@ -658,7 +672,7 @@ export class SubmissionsService {
658672 const percentage = total > 0 ? ( ( count / total ) * 100 ) . toFixed ( 1 ) : '0' ;
659673 if ( count > 0 ) {
660674 const pos = element . tooltipPosition ( ) ;
661- ctx . fillText ( `${ count } (${ percentage } %)` , pos . x - 15 , pos . y ) ;
675+ ctx . fillText ( `${ count } (${ percentage } %)` , pos . x , pos . y ) ;
662676 }
663677 } ) ;
664678 }
0 commit comments