1+ import json
2+
3+ global model
4+
5+ sql = model .SqlContent ('BudgetCumulativeGivingYoY' )
6+
7+ # Initialize data structure to store percentages by year and week
8+ weeks = range (1 , 54 ) # Assuming there are 52 weeks
9+ years = []
10+ d = [] # Will store data for each year, where each entry is a list of 52 weeks
11+
12+ # Retrieve the data from the database
13+ dbd = model .SqlListDynamicData (sql )
14+
15+ # Process the data and dynamically build the year-week-percentage matrix
16+ year_index_map = {}
17+ for row in dbd :
18+ # If it's a new year, initialize a new entry in the data matrix
19+ if row .Year not in year_index_map :
20+ year_index_map [row .Year ] = len (years ) # Assign a new column index for this year
21+ years .append (row .Year ) # Track the year
22+ d .append ([None ] * 53 ) # Initialize 52 weeks with 'None' for this year
23+
24+ # Get the column index for the current year
25+ year_col = year_index_map [row .Year ]
26+
27+ # Assign the percentage value for the corresponding week (row.Week - 1)
28+ if 1 <= row .Week <= 53 : # Ensure the week is within a valid range (1-52)
29+ d [year_col ][row .Week - 1 ] = row .Percentage
30+ if row .Week > 53 :
31+ d [year_col ][52 ] = row .Percentage
32+
33+ # Generate Google Chart script
34+ print """<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>"""
35+ print "<script>"
36+ print "google.charts.load('current', {'packages':['corechart']});"
37+ print "google.charts.setOnLoadCallback(drawChart);"
38+ print "function drawChart() {"
39+ print "var data = new google.visualization.DataTable();"
40+
41+ # Define columns: the first column is for the weeks, followed by one column per year
42+ print "data.addColumn('number', 'Week');"
43+ for y in years :
44+ print "data.addColumn('number', '{}');" .format (y )
45+
46+ # Add rows for each week (1 to 52), with percentages for each year
47+ print "data.addRows("
48+ rows = []
49+ for week in range (53 ): # Loop through 52 weeks
50+ row_data = [week + 1 ] # Start with the week number
51+ for year_index in range (len (years )):
52+ # Ensure the data is JSON serializable: float or None
53+ value = d [year_index ][week ] if d [year_index ][week ] is not None else None
54+ row_data .append (float (value / 100 ) if value is not None else None ) # Force float if it's not None
55+ rows .append (row_data )
56+
57+ # Use json.dumps to correctly serialize Python None as JavaScript null
58+ print json .dumps (rows )
59+ print ");"
60+
61+ # Generate colors and widths
62+ colors = ["'#ccc'" ] * (len (years ) - 2 ) + ["'#000'" , "'#00f'" ]
63+ widths = ['1' ] * (len (years ) - 2 ) + ['5' , '5' ]
64+
65+
66+ # Set chart options
67+ print """
68+ var options = {
69+ title: 'Cumulative Giving as Percentage of Budget',
70+ curveType: 'function',
71+ hAxis: {title: 'Week'},
72+ vAxis: {
73+ title: 'Percentage of Budget',
74+ viewWindow: {min: 0, max: 1.09},
75+ format: 'percent'
76+ },
77+ series: {"""
78+ for i in range (len (years )- 2 ):
79+ print str (i ) + ": { lineWidth: 1 },"
80+ print """},
81+ legend: 'none', // Hide legend
82+ colors: [""" + ", " .join (colors ) + """],
83+ lineWidth: 5
84+ };
85+ """
86+
87+ # Draw the chart
88+ print """
89+ var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
90+ chart.draw(data, options);
91+ }
92+ </script>
93+
94+ <div id="curve_chart" style="width: 100%; height: 10in"></div>
95+ """
0 commit comments