def update_student_phd_chart(dept): resp = table.query( KeyConditionExpression='PK = :pk AND SK BETWEEN :lower AND :upper', ExpressionAttributeValues={ ':pk': f'DEPT#{dept}', ':lower': 'DATA#STUDENTS#PHD#2005', ':upper': f'DATA#STUDENTS#PHD#{int(MAX_FISCAL_YEAR) + 1}$', }, ScanIndexForward=True, ) data = resp['Items'] if is_blank_grad(data): return [], {'display': 'none'} chart_data = [] x_axis = make_academic_year_range(0, MAX_YEAR_ID) # Categories determine filtering for the y-axis and obtaining a color categories = { 'cohort': 'Entering Cohort<br>(starting 2009/10)', 'existing': 'Existing Students', } for cat in categories.keys(): y_axis = [item.get(cat) for item in data] chart_data.append( go.Bar( name=categories.get(cat), x=x_axis, y=y_axis, text=[i if len(i) > 1 else f' {i} ' for i in y_axis ], # pad single-digit numbers to prevent rotation textposition='inside', hovertext=[f'{categories.get(cat)}: {i}' for i in y_axis], hoverinfo='text', marker=dict( color=students_grad_colors.get(cat), line=dict(color='floralwhite', width=1), ))) if dept not in ['AS', 'HUM', 'NS', 'SS']: # Do not add selectivity/yield for aggregates for cat in ('selectivity', 'yield'): y_axis_selectivity = [ round(float(item.get(cat)) * 100) if item.get(cat) is not None else None for item in data ] hover_labels = [ f'{i}%' if i is not None else None for i in y_axis_selectivity ] text_labels = make_text_labels(hover_labels) chart_data.append( go.Scatter( name=f'{cat.title()}', x=x_axis, y=y_axis_selectivity, mode='lines+markers+text', text=text_labels, textposition='top center', textfont=dict(color=students_grad_colors.get(cat), ), hovertext=hover_labels, hoverinfo='text', marker=dict(color=students_grad_colors.get(cat), ), yaxis='y2')) chart_layout = go.Layout( barmode='stack', xaxis=axes(), yaxis=axes(title='Number of Students', ), yaxis2=axes( title='% Selectivity or Yield', overlaying='y', side='right', rangemode='tozero', showgrid=False, ), legend={ 'traceorder': 'normal', 'x': 1.05 }, # By default x is 1.02 which will make it overlap with the 2nd y-axis margin=margin(l=55), ) else: chart_layout = go.Layout( barmode='stack', xaxis=axes(), yaxis=axes(title='Number of Students', ), legend={ 'traceorder': 'normal', 'x': 1.05 }, # By default x is 1.02 which will make it overlap with the 2nd y-axis margin=margin(l=55), ) return { 'data': chart_data, 'layout': chart_layout }, { 'display': 'inline' }
def update_student_sps_chart(dept): resp = table.query( KeyConditionExpression='PK = :pk AND SK BETWEEN :lower AND :upper', ExpressionAttributeValues={ ':pk': f'DEPT#{dept}', ':lower': 'DATA#STUDENTS#SPS#2005', ':upper': f'DATA#STUDENTS#SPS#{int(MAX_FISCAL_YEAR) + 1}$', }, ScanIndexForward=True, ) data = resp['Items'] if is_blank_grad(data): return [], {'display': 'none'} chart_data = [] x_axis = make_academic_year_range(0, MAX_YEAR_ID) # Categories determine filtering for the y-axis and obtaining a color categories = { 'cohort': 'Entering Cohort<br>(starting 2009/10)', 'existing': 'Existing Students', } for cat in categories.keys(): y_axis = [item.get(cat) for item in data] chart_data.append( go.Bar( name=categories.get(cat), x=x_axis, y=y_axis, text=[i if len(i) > 1 else f' {i} ' for i in y_axis ], # pad single-digit numbers to prevent rotation textposition='inside', hovertext=[f'{categories.get(cat)}: {i}' for i in y_axis], hoverinfo='text', marker=dict( color=students_grad_colors.get(cat), line=dict(color='floralwhite', width=1), ))) chart_layout = go.Layout( barmode='stack', xaxis=axes(), yaxis=axes(title='Number of Students', ), legend={ 'traceorder': 'normal', 'x': 1.05 }, # By default x is 1.02 which will make it overlap with the 2nd y-axis margin=margin(l=55), ) return { 'data': chart_data, 'layout': chart_layout }, { 'display': 'inline' }