0% found this document useful (0 votes)
33 views

RM Chart Correct Code

This view renders donation data as charts for a user. It retrieves donation data, prepares data for monthly and yearly charts, generates the charts using Plotly, and provides options to filter the charts by month and year.

Uploaded by

bithorthaagam
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views

RM Chart Correct Code

This view renders donation data as charts for a user. It retrieves donation data, prepares data for monthly and yearly charts, generates the charts using Plotly, and provides options to filter the charts by month and year.

Uploaded by

bithorthaagam
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 8

# views.

py

from django.shortcuts import render


from django.contrib.auth.decorators import login_required
from main.models import Donation
import plotly.offline as opy
import plotly.graph_objs as go
import pandas as pd
from datetime import datetime
from calendar import month_name as calendar_month_name
import calendar
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.dateformat import DateFormat
from django.utils.formats import date_format

def render_chart(data, selected_month=None, selected_year=None,


current_month=True):
df = pd.DataFrame(data)
df['dates'] = pd.to_datetime(df['dates'])

# Sort the DataFrame by dates to ensure consistent ordering


df = df.sort_values(by='dates')

if selected_month is not None and selected_year is not None:


# Set the title based on the selected month and year
month_name = calendar.month_name[selected_month]
title = f'Collection Amount for {month_name} {selected_year}'
elif current_month:
# Set the title for the current month and year
current_month = datetime.now().month
current_year = datetime.now().year
month_name = calendar.month_name[current_month]
title = f'Collection Amount for {month_name} {current_year}'
else:
title = 'Collection Amount Over Time'

fig = go.Figure()

# Add trace for the line chart


fig.add_trace(go.Scatter(
x=df['dates'],
y=df['amounts'],
mode='lines+markers',
name='Collection Amount',
line=dict(color='#1f77b4', width=2), # Blue line
marker=dict(color='#1f77b4', size=8, line=dict(color='#ffffff', width=1)),
# Blue markers
))

# Update layout with the dynamically generated title


fig.update_layout(
title=title,
xaxis_title='Date',
yaxis_title='Amount',
template='plotly_white',
font=dict(family='Arial, sans-serif', size=12, color='#333'), # Darker
font color
margin=dict(l=60, r=60, t=80, b=60), # Increased margins
plot_bgcolor='#f5f5f5', # Light gray background color
paper_bgcolor='#f5f5f5', # Light gray paper background color
xaxis=dict(
showline=True,
showgrid=False,
showticklabels=True,
linecolor='#333',
linewidth=1,
ticks='outside',
tickfont=dict(family='Arial, sans-serif', size=10, color='#333'), #
Darker axis line and ticks
),
yaxis=dict(
showline=True,
showgrid=True,
showticklabels=True,
linecolor='#333',
linewidth=1,
ticks='outside',
tickfont=dict(family='Arial, sans-serif', size=10, color='#333') #
Darker axis line and ticks
),
)

plot_div = opy.plot(fig, auto_open=False, output_type='div')

return plot_div

def render_year_chart(data, selected_year=None):


# Prepare data for year-wise chart
year_data = {
'dates': [],
'amounts': []
}

# Group data by month and sum the amounts for each month
monthly_collection = {}
for donation in data:
month_year_key = donation['service_date'].strftime('%B-%Y')
if month_year_key not in monthly_collection:
monthly_collection[month_year_key] = 0
monthly_collection[month_year_key] += donation['amount']

# Convert the grouped data into lists for Plotly


for month_year, amount in monthly_collection.items():
year_data['dates'].append(month_year)
year_data['amounts'].append(amount)

# Define the order of months for correct ordering on the X-axis


ordered_months = [
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
]

# Sort the data based on the order of months


sorted_data = sorted(zip(year_data['dates'], year_data['amounts']), key=lambda
x: ordered_months.index(x[0].split('-')[0]))

# Unpack the sorted data only if it exists


if sorted_data:
sorted_dates, sorted_amounts = zip(*sorted_data)
else:
sorted_dates, sorted_amounts = [], []

fig = go.Figure()

# Add trace for the line chart only if there is data


if sorted_dates and sorted_amounts:
fig.add_trace(go.Scatter(
x=sorted_dates,
y=sorted_amounts,
mode='lines+markers',
name='Monthly Collection',
line=dict(color='#1f77b4', width=2), # Blue line
marker=dict(color='#1f77b4', size=8, line=dict(color='#ffffff',
width=1)), # Blue markers
))

# Update layout
if selected_year is not None:
title = f'Monthly Collection for {selected_year}'
else:
current_year = datetime.now().year
title = f'Monthly Collection for {current_year}'

fig.update_layout(
title=title,
xaxis_title='Month',
yaxis_title='Amount',
template='plotly_white',
font=dict(family='Arial, sans-serif', size=12, color='#333'), # Darker
font color
margin=dict(l=60, r=60, t=80, b=60), # Increased margins
plot_bgcolor='#f5f5f5', # Light gray background color
paper_bgcolor='#f5f5f5', # Light gray paper background color
xaxis=dict(
showline=True,
showgrid=False,
showticklabels=True,
linecolor='#333',
linewidth=1,
ticks='outside',
tickfont=dict(family='Arial, sans-serif', size=10, color='#333'), #
Darker axis line and ticks
categoryorder='array', # Specify ordering for categorical axis
categoryarray=ordered_months # Order the months according to the
predefined list
),
yaxis=dict(
showline=True,
showgrid=True,
showticklabels=True,
linecolor='#333',
linewidth=1,
ticks='outside',
tickfont=dict(family='Arial, sans-serif', size=10, color='#333') #
Darker axis line and ticks
),
)

plot_div = opy.plot(fig, auto_open=False, output_type='div')

return plot_div

def month_name(month):
# Function to get the name of the month from its number
return datetime.strptime(str(month), '%m').strftime('%B')

@login_required
def chart_view(request):
# Get referral code associated with the logged-in user
referral_code = request.user.referral_code

# Fetch donations for the current month and current year


current_month = datetime.now().month
current_year = datetime.now().year
current_month_donations = Donation.objects.filter(referral_code=referral_code,
service_date__month=current_month)
current_year_donations = Donation.objects.filter(referral_code=referral_code,
service_date__year=current_year)

# Prepare data for month-wise chart (default to current month)


month_data = {
'dates': [donation.service_date for donation in current_month_donations if
donation.service_date],
'amounts': [donation.amount for donation in current_month_donations if
donation.service_date],
}

# If a month is selected from the dropdown, update the month_data accordingly


selected_month = int(request.GET.get('month', current_month))
selected_year = int(request.GET.get('year', current_year))
if selected_month != current_month or selected_year != current_year:
selected_month_donations =
Donation.objects.filter(referral_code=referral_code,
service_date__month=selected_month, service_date__year=selected_year)
month_data = {
'dates': [donation.service_date for donation in
selected_month_donations if donation.service_date],
'amounts': [donation.amount for donation in selected_month_donations if
donation.service_date],
}

# Generate month-wise chart div


month_chart_div = render_chart(month_data, selected_month=selected_month,
selected_year=selected_year, current_month=False)

# Prepare data for year-wise chart


selected_year_for_year_chart = int(request.GET.get('year_for_year_chart',
current_year))
year_data = []
for donation in current_year_donations:
year_data.append({
'service_date': donation.service_date,
'amount': donation.amount
})

# Generate year-wise chart div


year_chart_div = render_year_chart(year_data,
selected_year=selected_year_for_year_chart)

# Get list of months and years for dropdowns


months = [(i, calendar_month_name[i]) for i in range(1, 13)]
years = range(2021, current_year + 1)

# Get list of years specifically for render_year_chart dropdown


years_for_year_chart = range(2021, current_year + 1)

# Generate dynamic title for the month-wise chart


if selected_month != current_month or selected_year != current_year:
month_name = DateFormat(datetime(selected_year, selected_month,
1)).format('F')
month_chart_title = f'Daily Collection for {month_name} {selected_year}'
else:
month_name = DateFormat(datetime.now()).format('F')
month_chart_title = f'Daily Collection for {month_name} {current_year}'

# Initialize year_chart_title with a default value


year_chart_title = f'Monthly Collection for {current_year}'

# Handle filtering for year-wise chart


if request.method == 'GET' and 'year_for_year_chart' in request.GET:
selected_year_for_year_chart = int(request.GET.get('year_for_year_chart'))
if selected_year_for_year_chart != current_year:
year_data = []
for donation in Donation.objects.filter(referral_code=referral_code,
service_date__year=selected_year_for_year_chart):
year_data.append({
'service_date': donation.service_date,
'amount': donation.amount
})
year_chart_div = render_year_chart(year_data,
selected_year=selected_year_for_year_chart) # Pass selected year to the function
# Update year-wise chart title when filtered
year_chart_title = f'Monthly Collection for
{selected_year_for_year_chart}'

return render(request, 'referral/chart.html', {


'month_chart_div': month_chart_div,
'year_chart_div': year_chart_div,
'months': months,
'years': years,
'years_for_year_chart': years_for_year_chart,
'selected_month': selected_month,
'selected_year': selected_year,
'selected_year_for_year_chart': selected_year_for_year_chart,
'month_chart_title': month_chart_title,
'year_chart_title': year_chart_title,
})

{% extends 'referral/base.html' %}
{% block content %}
<style>
/* Custom CSS */
.chart-container {
border: 1px solid #dee2e6; /* Gray border */
border-radius: 5px; /* Rounded corners */
padding: 20px; /* Padding around the chart */
background-color: #fff; /* White background color */
margin-top: 20px; /* Add margin to separate from title */
}

.chart-container h2 {
color: #343a40; /* Dark text color */
margin-bottom: 20px; /* Bottom margin for heading */
}

/* Optional: Add more styling as needed */


</style>

<!-- Dropdown for selecting month and year -->


<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-4 mb-3">
<select id="month-dropdown" class="form-select">
{% for month in months %}
<option value="{{ month.0 }}" {% if month.0 == selected_month
%}selected{% endif %}>{{ month.1 }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4 mb-3">
<select id="year-dropdown" class="form-select">
{% for year in years %}
<option value="{{ year }}" {% if year == selected_year %}selected{% endif
%}>{{ year }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4 mb-3">
<button id="apply-filter-btn" class="btn btn-primary">Apply Filter</button>
</div>
</div>
</div>

<!-- Display month-wise chart -->


<hr>
<div class="container my-4">
<h2 class="text-center">{{ month_chart_title }}</h2> <!-- Display month-wise
chart title -->
<div id="month_chart_div" class="chart-container">
{{ month_chart_div|safe }}
</div>
</div>

<!-- Display year-wise chart -->


<hr>

<!-- Dropdown for selecting year for year-wise chart -->


<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-4 mb-3">
<select id="year-dropdown-year-chart" class="form-select">
{% for year in years_for_year_chart %}
<option value="{{ year }}" {% if year == selected_year_for_year_chart
%}selected{% endif %}>{{ year }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-2 mb-3">
<button id="filter-btn" class="btn btn-primary">Filter</button>
</div>
</div>
</div>

<!-- ... (existing HTML) ... -->

<hr>
<div class="container my-4">
<h2 class="text-center">{{ year_chart_title }}</h2> <!-- Display year-wise chart
title -->
<div id="year_chart_div" class="chart-container">
{{ year_chart_div|safe }}
</div>
</div>

<script>
// JavaScript code for handling dropdown selection and applying filters for
month-wise chart
document.getElementById('apply-filter-btn').addEventListener('click', function()
{
var selectedMonth = document.getElementById('month-dropdown').value;
var selectedYear = document.getElementById('year-dropdown').value;
window.location.href = '/referral/chart/?month=' + selectedMonth + '&year=' +
selectedYear;
});

// JavaScript code for handling dropdown selection for year-wise chart


document.getElementById('year-dropdown-year-chart').addEventListener('change',
function() {
var selectedYear = document.getElementById('year-dropdown-year-chart').value;
// Call function to update year-wise chart based on selected year
updateYearChart(selectedYear);
});

// Function to update year-wise chart based on selected year


function updateYearChart(selectedYear) {
// Make AJAX call to fetch data for year-wise chart based on selected year
// Update the chart with the fetched data
// Example:
// $.ajax({
// url: '/referral/chart/yearly/?year=' + selectedYear,
// success: function(data) {
// // Update year-wise chart with the fetched data
// },
// error: function(xhr, status, error) {
// console.error(error);
// }
// });
}

// JavaScript code for handling year-wise chart filter


document.getElementById('filter-btn').addEventListener('click', function() {
var selectedYear = document.getElementById('year-dropdown-year-chart').value;
window.location.href = '/referral/chart/?year_for_year_chart=' + selectedYear;
});
</script>

{% endblock %}

You might also like