@@ -142,17 +142,45 @@ const getCSSProperty = (element: HTMLElement, propertyName: string): string => {
142142 return getComputedStyle ( element ) . getPropertyValue ( propertyName ) . trim ( ) ;
143143} ;
144144
145- const getAnimationConfig = ( ) : { duration : 0 } | undefined => {
145+ const shouldReduceMotion = ( ) : boolean => {
146146 const wrapper = document . querySelector ( '[data-tutor-theme]' ) || document . documentElement ;
147147 const motion = wrapper . getAttribute ( 'data-tutor-motion' ) ;
148+ return (
149+ motion === 'reduce' ||
150+ ( ( ! motion || motion === 'auto' ) && window . matchMedia ( '(prefers-reduced-motion: reduce)' ) . matches )
151+ ) ;
152+ } ;
148153
149- if ( motion === 'reduce' ) {
154+ const getAnimationConfig = ( ) : { duration : 0 } | undefined => {
155+ if ( shouldReduceMotion ( ) ) {
150156 return { duration : 0 } ;
151157 }
152- if ( ( ! motion || motion === 'auto' ) && window . matchMedia ( '(prefers-reduced-motion: reduce)' ) . matches ) {
158+ return undefined ;
159+ } ;
160+
161+ const getCompletionChartAnimation = ( ) : { duration : 0 } | Record < string , unknown > => {
162+ if ( shouldReduceMotion ( ) ) {
153163 return { duration : 0 } ;
154164 }
155- return undefined ;
165+
166+ return {
167+ base : { duration : 0 } ,
168+ x : {
169+ from : ( ctx : Record < string , unknown > ) => {
170+ const chart = ctx . chart as {
171+ scales : { x : { getPixelForValue : ( v : number ) => number } } ;
172+ data : { datasets : Array < { data : Array < number > } > } ;
173+ } ;
174+ const dataIndex = ctx . dataIndex as number ;
175+ const datasetIndex = ctx . datasetIndex as number ;
176+ let cumulative = 0 ;
177+ for ( let i = 0 ; i < datasetIndex ; i ++ ) {
178+ cumulative += chart . data . datasets [ i ] . data [ dataIndex ] || 0 ;
179+ }
180+ return chart . scales . x . getPixelForValue ( cumulative ) ;
181+ } ,
182+ } ,
183+ } ;
156184} ;
157185
158186const createChart = ( canvas : HTMLCanvasElement , config : ChartConfiguration ) : void => {
@@ -792,6 +820,9 @@ export const courseCompletionChart = (data: CourseCompletionChartData) => ({
792820 const chartColors = [ colors . enrolled , colors . completed , colors . in_progress , colors . inactive , colors . cancelled ] ;
793821 const dataKeys : CourseCompletionChartDataKey [ ] = [ 'enrolled' , 'completed' , 'in_progress' , 'inactive' , 'cancelled' ] ;
794822
823+ const lastNonZeroIndex = chartData . reduce ( ( last , value , i ) => ( value > 0 ? i : last ) , - 1 ) ;
824+ const firstNonZeroIndex = chartData . findIndex ( ( value ) => value > 0 ) ;
825+
795826 return {
796827 type : 'bar' ,
797828 data : {
@@ -801,20 +832,29 @@ export const courseCompletionChart = (data: CourseCompletionChartData) => ({
801832 backgroundColor : chartColors [ index ] ,
802833 barThickness : CHART_CONFIG . bar . thickness ,
803834 borderRadius : {
804- bottomLeft : index === 0 ? CHART_CONFIG . bar . borderRadius : 0 ,
805- topLeft : index === 0 ? CHART_CONFIG . bar . borderRadius : 0 ,
806- bottomRight : index === chartData . length - 1 ? CHART_CONFIG . bar . borderRadius : 0 ,
807- topRight : index === chartData . length - 1 ? CHART_CONFIG . bar . borderRadius : 0 ,
835+ bottomLeft : index === ( firstNonZeroIndex > - 1 ? firstNonZeroIndex : 0 ) ? CHART_CONFIG . bar . borderRadius : 0 ,
836+ topLeft : index === ( firstNonZeroIndex > - 1 ? firstNonZeroIndex : 0 ) ? CHART_CONFIG . bar . borderRadius : 0 ,
837+ bottomRight :
838+ index === ( lastNonZeroIndex > - 1 ? lastNonZeroIndex : chartData . length - 1 )
839+ ? CHART_CONFIG . bar . borderRadius
840+ : 0 ,
841+ topRight :
842+ index === ( lastNonZeroIndex > - 1 ? lastNonZeroIndex : chartData . length - 1 )
843+ ? CHART_CONFIG . bar . borderRadius
844+ : 0 ,
808845 } ,
809846 borderSkipped : false ,
810847 borderWidth : {
811- right : index === chartData . length - 1 ? 0 : CHART_CONFIG . bar . borderWidth ,
848+ right :
849+ index === ( lastNonZeroIndex > - 1 ? lastNonZeroIndex : chartData . length - 1 )
850+ ? 0
851+ : CHART_CONFIG . bar . borderWidth ,
812852 } ,
813853 borderColor : getCSSProperty ( this . $refs . canvas , '--tutor-surface-l1' ) ,
814854 } ) ) ,
815855 } ,
816856 options : {
817- animation : getAnimationConfig ( ) ,
857+ animation : getCompletionChartAnimation ( ) ,
818858 indexAxis : 'y' ,
819859 responsive : CHART_CONFIG . common . responsive ,
820860 maintainAspectRatio : false ,
0 commit comments