소스 검색

feat(authors.html): update chart to use apexchart.

Christhoval Barba 1 년 전
부모
커밋
f6e1b8fe46
3개의 변경된 파일336개의 추가작업 그리고 247개의 파일을 삭제
  1. 3
    0
      chart.json
  2. 222
    200
      gitstats
  3. 111
    47
      gitstats.css

+ 3
- 0
chart.json 파일 보기

@@ -19,6 +19,9 @@
19 19
       "columnWidth": "55%",
20 20
       "endingShape": "rounded",
21 21
       "borderRadius": 2
22
+    },
23
+    "heatmap": {
24
+      "enableShades": false
22 25
     }
23 26
   },
24 27
   "dataLabels": {

+ 222
- 200
gitstats 파일 보기

@@ -45,7 +45,7 @@ conf = {
45 45
 	'max_domains': 10,
46 46
 	'max_ext_length': 10,
47 47
 	'style': 'gitstats.css',
48
-	'max_authors': 20,
48
+	'max_authors': 7,
49 49
 	'authors_top': 5,
50 50
 	'commit_begin': '',
51 51
 	'commit_end': 'HEAD',
@@ -923,9 +923,8 @@ class HTMLReportCreator(ReportCreator):
923 923
 
924 924
 		activity_content.append('<div class="grid grid-cols-12 gap-4 md:gap-6 2xl:gap-7.5">')
925 925
 
926
-		#activity_content.append('<h2>Last 30 days</h2>')
927
-
928
-		#activity_content.append('<h2>Last 12 months</h2>')
926
+		# Last 30 days
927
+		# Last 12 months
929 928
 
930 929
 		# Weekly activity
931 930
 		WEEKS = 32
@@ -938,24 +937,19 @@ class HTMLReportCreator(ReportCreator):
938 937
 			weeks.insert(0, stampcur.strftime('%Y-%W'))
939 938
 			stampcur -= deltaweek
940 939
 		
941
-		activity_per_weekly_serie = []
940
+		activity_per_weekly_series = [
941
+			{"name": "Commits", "color": "#1A56DB", "data": []},
942
+			{"name": "Percentage", "color": "#779EF1", "data": []},
943
+		]
942 944
 		for i in range(0, WEEKS):
943 945
 			commits = data.activity_by_year_week[weeks[i]] if weeks[i] in data.activity_by_year_week else 0
944
-			activity_per_weekly_serie.append({"x": f'{WEEKS-i}', "y": commits, "percentage": (100.0 * commits) / totalcommits})
946
+			activity_per_weekly_series[0]['data'].append({"x": f'{WEEKS-i}', "y": commits})
947
+			activity_per_weekly_series[1]['data'].append({"x": f'{WEEKS-i}', "y": f'{((100.0 * commits) / totalcommits):.2f}'})
945 948
 		
946
-		activity_per_weekly_config = chart_default_config.copy()
947
-
948
-		activity_per_weekly_config.update({"series": [{
949
-			"name": "Commits",
950
-			"color": "#1A56DB",
951
-			"data": activity_per_weekly_serie}]})
952
-
953
-		# current_config.update({"series": [{
954
-		# 	"name": "Organic",
955
-		# 	"color": "#1A56DB",
956
-		# 	"data": commits_per_days_values
957
-		# 	}]})
958
-		# current_config['xaxis']['categories'] = commits_per_days_labels
949
+		activity_per_weekly_config = {
950
+			**chart_default_config,
951
+			"series": activity_per_weekly_series
952
+		}
959 953
 
960 954
 		activity_content.append(activity_html.addChart(activity_per_weekly_config, name='chartWeeklyActivity', title=f'Weekly activity <span class="text-xs font-medium">Last {WEEKS} weeks</span>', className=""))
961 955
 		
@@ -963,202 +957,146 @@ class HTMLReportCreator(ReportCreator):
963 957
 		# Hour of Day
964 958
 		hour_of_day = data.getActivityByHourOfDay()
965 959
 
966
-		activity_per_hours_day_serie = []
960
+		activity_per_hours_day_series = [
961
+			{"name": "Commits", "color": "#1A56DB", "data": []},
962
+			{"name": "Percentage", "color": "#779EF1", "data": []},
963
+		]
967 964
 
968 965
 		for i in range(0, 24):
969 966
 			commits = hour_of_day[i] if i in hour_of_day else 0
970
-			activity_per_hours_day_serie.append({"x": f'{i}', "y": commits, "percentage": (100.0 * commits) / totalcommits})
971
-
972
-		activity_per_hours_day_config = chart_default_config.copy()
967
+			activity_per_hours_day_series[0]["data"].append({"x": f'{i}', "y": commits})
968
+			activity_per_hours_day_series[1]["data"].append({"x": f'{i}', "y": f'{((100.0 * commits) / totalcommits):.2f}'})
973 969
 
974
-		activity_per_hours_day_config.update({"series": [{
975
-			"name": "Commits",
976
-			"color": "#1A56DB",
977
-			"data": activity_per_hours_day_serie}]})
970
+		activity_per_hours_day_config = {
971
+			**chart_default_config, 
972
+			"series": activity_per_hours_day_series
973
+		}
978 974
 		
979 975
 		activity_content.append(activity_html.addChart(activity_per_hours_day_config, name='chartHourOfDay', title='Hour of Day', className=""))
980
-				
981
-		
982
-		# activity_content.append('<div><div class="card-body"><table><tr><th>Hour</th>')
983
-		# for i in range(0, 24):
984
-		# 	activity_content.append('<th>%d</th>' % i)
985
-		# activity_content.append('</tr>\n<tr><th>Commits</th>')
986
-		# fp = open(path + '/hour_of_day.dat', 'w')
987
-		# for i in range(0, 24):
988
-		# 	if i in hour_of_day:
989
-		# 		r = 127 + int((float(hour_of_day[i]) / data.activity_by_hour_of_day_busiest) * 128)
990
-		# 		activity_content.append('<td style="background-color: rgb(%d, 0, 0)">%d</td>' % (r, hour_of_day[i]))
991
-		# 		fp.write('%d %d\n' % (i, hour_of_day[i]))
992
-		# 	else:
993
-		# 		activity_content.append('<td>0</td>')
994
-		# 		fp.write('%d 0\n' % i)
995
-		# fp.close()
996
-		# activity_content.append('</tr>\n<tr><th>%</th>')
997
-
998
-		# for i in range(0, 24):
999
-		# 	if i in hour_of_day:
1000
-		# 		r = 127 + int((float(hour_of_day[i]) / data.activity_by_hour_of_day_busiest) * 128)
1001
-		# 		activity_content.append('<td style="background-color: rgb(%d, 0, 0)">%.2f</td>' % (r, (100.0 * hour_of_day[i]) / totalcommits))
1002
-		# 	else:
1003
-		# 		activity_content.append('<td>0.00</td>')
1004
-		# activity_content.append('</tr></table>')
1005 976
 
1006 977
 
1007 978
 		# Day of Week
1008
-		# activity_content.append(html_header(2, 'Day of Week'))
1009 979
 		day_of_week = data.getActivityByDayOfWeek()
1010
-		# activity_content.append('<div class="vtable"><table>')
1011
-		# activity_content.append('<tr><th>Day</th><th>Total (%)</th></tr>')
1012 980
 
1013
-		activity_per_day_week_serie =[]
981
+		activity_per_day_week_series = [
982
+			{"name": "Commits", "color": "#1A56DB", "data": []},
983
+			{"name": "Percentage", "color": "#779EF1", "data": []},
984
+		]
1014 985
 
1015 986
 		for d in range(0, 7):
1016 987
 			commits = day_of_week[d] if d in day_of_week else 0
1017
-			activity_per_day_week_serie.append({"x": WEEKDAYS[d], "y": commits, "percentage": (100.0 * commits) / totalcommits})
988
+			activity_per_day_week_series[0]["data"].append({"x": WEEKDAYS[d], "y": commits})
989
+			activity_per_day_week_series[1]["data"].append({"x": WEEKDAYS[d], "y": f'{((100.0 * commits) / totalcommits):.2f}'})
1018 990
 
1019
-			# activity_content.append('<tr>')
1020
-			# activity_content.append('<th>%s</th>' % (WEEKDAYS[d]))
1021
-			# if d in day_of_week:
1022
-			# 	activity_content.append('<td>%d (%.2f%%)</td>' % (day_of_week[d], (100.0 * day_of_week[d]) / totalcommits))
1023
-			# else:
1024
-			# 	activity_content.append('<td>0</td>')
1025
-			# activity_content.append('</tr>')
1026
-		# activity_content.append('</table></div>')
1027
-
1028
-		activity_per_day_week_config = chart_default_config.copy()
1029
-
1030
-		activity_per_day_week_config.update({"series": [{
1031
-			"name": "Commits",
1032
-			"color": "#1A56DB",
1033
-			"data": activity_per_day_week_serie}]})
991
+		activity_per_day_week_config = {
992
+			**chart_default_config,
993
+			"series": activity_per_day_week_series
994
+		}
1034 995
 		
1035 996
 		activity_content.append(activity_html.addChart(activity_per_day_week_config, name='chartDayofWeek', title='Day of Week', className="xl:col-span-4"))
1036 997
 
1037 998
 		# Hour of Week
1038
-		activity_hour_of_week__content= ['<table>']
1039
-
1040
-		activity_hour_of_week__content.append('<tr><th>Weekday</th>')
1041
-		for hour in range(0, 24):
1042
-			activity_hour_of_week__content.append('<th>%d</th>' % (hour))
1043
-		activity_hour_of_week__content.append('</tr>')
999
+		activity_hour_of_week_series = []
1044 1000
 
1045 1001
 		for weekday in range(0, 7):
1046
-			activity_hour_of_week__content.append('<tr><th>%s</th>' % (WEEKDAYS[weekday]))
1002
+			activity_hour_of_week_series.append({"name": WEEKDAYS[weekday], "data": []})
1047 1003
 			for hour in range(0, 24):
1048 1004
 				try:
1049 1005
 					commits = data.activity_by_hour_of_week[weekday][hour]
1050 1006
 				except KeyError:
1051 1007
 					commits = 0
1052
-				if commits != 0:
1053
-					activity_hour_of_week__content.append('<td')
1054
-					r = 127 + int((float(commits) / data.activity_by_hour_of_week_busiest) * 128)
1055
-					activity_hour_of_week__content.append(' style="background-color: rgb(%d, 0, 0)"' % r)
1056
-					activity_hour_of_week__content.append('>%d</td>' % commits)
1057
-				else:
1058
-					activity_hour_of_week__content.append('<td></td>')
1059
-			activity_hour_of_week__content.append('</tr>')
1060
-
1061
-		activity_hour_of_week__content.append('</table>')
1008
+				
1009
+				activity_hour_of_week_series[weekday]["data"].append({"x": f'{hour}', "y": commits})
1062 1010
 
1063
-		activity_content.append(activity_html.addCard(activity_hour_of_week__content, title='Hour of Week', className='xl:col-span-8'))
1011
+		activity_hour_of_week_series.reverse()
1064 1012
 
1013
+		activity_hour_of_week_config = {
1014
+			"series": activity_hour_of_week_series,
1015
+			"chart": {**chart_default_config["chart"], "type": 'heatmap'},
1016
+      		"dataLabels": chart_default_config["dataLabels"],
1017
+			"colors": ["#3C50E0"],
1018
+			"xaxis": chart_default_config["xaxis"],
1019
+			"yaxis": chart_default_config["yaxis"],
1020
+		}
1065 1021
 
1022
+		activity_content.append(activity_html.addChart(activity_hour_of_week_config, name='chartHourOfWeek', title='Hour of Week', className="xl:col-span-8"))
1023
+	
1066 1024
 		# Month of Year
1067
-		activity_per_month_of_year_serie = []
1068
-		# activity_content.append(html_header(2, 'Month of Year'))
1069
-		# activity_content.append('<div class="vtable"><table>')
1070
-		# activity_content.append('<tr><th>Month</th><th>Commits (%)</th></tr>')
1071
-		# fp = open (path + '/month_of_year.dat', 'w')
1025
+		activity_per_month_of_year_series = [
1026
+			{"name": "Commits", "color": "#1A56DB", "data": []},
1027
+			{"name": "Percentage", "color": "#779EF1", "data": []},
1028
+		]
1072 1029
 		for mm in range(1, 13):
1073 1030
 			commits = data.activity_by_month_of_year[mm] if mm in data.activity_by_month_of_year else 0
1074
-			# activity_content.append('<tr><td>%d</td><td>%d (%.2f %%)</td></tr>' % (mm, commits, (100.0 * commits) / data.getTotalCommits()))
1075
-			# fp.write('%d %d\n' % (mm, commits))
1076
-			activity_per_month_of_year_serie.append({"x": f'{mm}', "y": commits, "percentage": (100.0 * commits) /totalcommits})
1077
-		# fp.close()
1078
-		# activity_content.append('</table></div>')
1079
-		# activity_content.append('<img src="month_of_year.png" alt="Month of Year">')
1080
-
1081
-		activity_per_month_of_year_config = chart_default_config.copy()
1031
+			activity_per_month_of_year_series[0]["data"].append({"x": f'{mm}', "y": commits, "percentage": (100.0 * commits) /totalcommits})
1032
+			activity_per_month_of_year_series[1]["data"].append({"x": f'{mm}', "y": f'{((100.0 * commits) /totalcommits):.2f}'})
1082 1033
 
1083
-		activity_per_month_of_year_config.update({"series": [{
1084
-			"name": "Commits",
1085
-			"color": "#1A56DB",
1086
-			"data": activity_per_month_of_year_serie}]})
1034
+		activity_per_month_of_year_config = {
1035
+			**chart_default_config,
1036
+			"series": activity_per_month_of_year_series
1037
+		}
1087 1038
 
1088 1039
 		activity_content.append(activity_html.addChart(activity_per_month_of_year_config, name='chartMonthOfYear', title='Month of Year', className="xl:col-span-5"))
1089 1040
 
1090 1041
 
1091 1042
 		# Commits by year/month
1092 1043
 		activity_per_year_month_serie = []
1093
-		# activity_content.append(html_header(2, 'Commits by year/month'))
1094
-		# activity_content.append('<div class="vtable"><table><tr><th>Month</th><th>Commits</th><th>Lines added</th><th>Lines removed</th></tr>')
1095
-		# for yymm in reversed(sorted(data.commits_by_month.keys())):
1096
-			# activity_content.append('<tr><td>%s</td><td>%d</td><td>%d</td><td>%d</td></tr>' % (yymm, data.commits_by_month.get(yymm,0), data.lines_added_by_month.get(yymm,0), data.lines_removed_by_month.get(yymm,0)))
1097
-		# activity_content.append('</table></div>')
1098
-		# activity_content.append('<img src="commits_by_year_month.png" alt="Commits by year/month">')
1099
-		# fg = open(path + '/commits_by_year_month.dat', 'w')
1100 1044
 		for yymm in sorted(data.commits_by_month.keys()):
1101
-			# fg.write('%s %s\n' % (yymm, data.commits_by_month[yymm]))
1102 1045
 			activity_per_year_month_serie.append({"x": f'{yymm}', "y": data.commits_by_month.get(yymm,0), "lines_added": data.lines_added_by_month.get(yymm,0), "lines_removed": data.lines_removed_by_month.get(yymm,0), "percentage": (100.0 * data.commits_by_month.get(yymm,0)) /totalcommits})
1103
-		# fg.close()
1104 1046
 
1105
-		activity_per_year_month_config = chart_default_config.copy()
1047
+		activity_per_year_month_config = dict(chart_default_config)
1106 1048
 
1107
-		activity_per_year_month_config.update({"series": [{
1049
+		activity_per_year_month_config = {
1050
+			**chart_default_config,
1051
+			"series": [{
1108 1052
 			"name": "Commits",
1109 1053
 			"color": "#1A56DB",
1110
-			"data": activity_per_year_month_serie}]})
1111
-		
1112
-		activity_per_year_month_config["xaxis"]["labels"]["show"] = False
1054
+			"data": activity_per_year_month_serie}],
1055
+			"xaxis": {
1056
+				**chart_default_config["xaxis"], 
1057
+				"labels": {
1058
+					**activity_per_year_month_config["xaxis"]["labels"] , 
1059
+					"show" : False
1060
+					}}}
1113 1061
 
1114 1062
 		activity_content.append(activity_html.addChart(activity_per_year_month_config, name='chartCommitsByYearMonth', title='Commits by year/month', className="xl:col-span-7"))
1115 1063
 
1116 1064
 
1117 1065
 		# Commits by year
1118
-		activity_by_year_serie = []
1119
-		# activity_content.append(html_header(2, 'Commits by Year'))
1120
-		# activity_content.append('<div class="vtable"><table><tr><th>Year</th><th>Commits (% of all)</th><th>Lines added</th><th>Lines removed</th></tr>')
1121
-		# for yy in reversed(sorted(data.commits_by_year.keys())):
1122
-			# activity_content.append('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%d</td><td>%d</td></tr>' % (yy, data.commits_by_year.get(yy,0), (100.0 * data.commits_by_year.get(yy,0)) / data.getTotalCommits(), data.lines_added_by_year.get(yy,0), data.lines_removed_by_year.get(yy,0)))
1123
-		# activity_content.append('</table></div>')
1124
-		# activity_content.append('<img src="commits_by_year.png" alt="Commits by Year">')
1125
-		# fg = open(path + '/commits_by_year.dat', 'w')
1066
+		activity_by_year_series = [
1067
+			{"name": "Commits", "color": "#1A56DB", "data": []},
1068
+			{"name": "Lines Added", "color": "#23961B","data": []},
1069
+			{"name": "Lines Removed", "color": "#DB1A1A","data": []},
1070
+			{"name": "Percentage", "color": "#779EF1","data": []}]
1071
+		
1126 1072
 		for yy in sorted(data.commits_by_year.keys()):
1127
-			# fg.write('%d %d\n' % (yy, data.commits_by_year[yy]))
1128
-			activity_by_year_serie.append({"x": f'{yy}', "y": data.commits_by_year.get(yy,0), "lines_added": data.lines_added_by_year.get(yymm,0), "lines_removed": data.lines_removed_by_year.get(yymm,0), "percentage": (100.0 * data.commits_by_year.get(yy,0)) /totalcommits})
1129
-		# fg.close()
1073
+			activity_by_year_series[0]["data"].append({"x": f'{yy}', "y": data.commits_by_year.get(yy,0)})
1074
+			activity_by_year_series[1]["data"].append({"x": f'{yy}', "y": data.lines_added_by_year.get(yy,0)})
1075
+			activity_by_year_series[2]["data"].append({"x": f'{yy}', "y": data.lines_removed_by_year.get(yy,0)})
1076
+			activity_by_year_series[3]["data"].append({"x": f'{yy}', "y": f'{((100.0 * data.commits_by_year.get(yy,0)) /totalcommits):.2f}'})
1130 1077
 
1131
-		activity_by_year_config = chart_default_config.copy()
1132
-
1133
-		activity_by_year_config.update({"series": [{
1134
-			"name": "Commits",
1135
-			"color": "#1A56DB",
1136
-			"data": activity_by_year_serie}]})
1137
-		
1138
-		activity_by_year_config["xaxis"]["labels"]["show"] = True
1078
+		activity_by_year_config = {
1079
+			**chart_default_config,
1080
+			"series": activity_by_year_series
1081
+			}
1139 1082
 
1140 1083
 		activity_content.append(activity_html.addChart(activity_by_year_config, name='chartCommitsByYear', title='Commits by Year', className="xl:col-span-6"))
1141 1084
 
1142 1085
 		# Commits by timezone
1143
-		activity_by_timezone_serie = []
1144
-		# activity_content.append(html_header(2, 'Commits by Timezone'))
1145
-		# activity_content.append('<div><div class="card-body"><table><tr>')
1146
-		# activity_content.append('<th>Timezone</th><th>Commits</th>')
1147
-		# activity_content.append('</tr>')
1086
+		activity_by_timezone_series = [
1087
+			{"name": "Commits", "color": "#1A56DB", "data": []},
1088
+			{"name": "Percentage", "color": "#779EF1", "data": []},
1089
+		]
1148 1090
 		max_commits_on_tz = max(data.commits_by_timezone.values())
1149 1091
 		for i in sorted(data.commits_by_timezone.keys(), key = lambda n : int(n)):
1150 1092
 			commits = data.commits_by_timezone.get(i, 0)
1151
-			activity_by_timezone_serie.append({"x": f'{i}', "y": commits, "percentage": (100.0 * commits) /totalcommits})
1152
-			# r = 127 + int((float(commits) / max_commits_on_tz) * 128)
1153
-			# activity_content.append('<tr><th>%s</th><td style="background-color: rgb(%d, 0, 0)">%d</td></tr>' % (i, r, commits))
1154
-		# activity_content.append('</table></div>')
1093
+			activity_by_timezone_series[0]["data"].append({"x": f'{i}', "y": commits})
1094
+			activity_by_timezone_series[1]["data"].append({"x": f'{i}', "y": f'{((100.0 * commits) /totalcommits):.2f}'})
1155 1095
 
1156
-		activity_by_timezone_config = chart_default_config.copy()
1157
-
1158
-		activity_by_timezone_config.update({"series": [{
1159
-			"name": "Commits",
1160
-			"color": "#1A56DB",
1161
-			"data": activity_by_timezone_serie}]})
1096
+		activity_by_timezone_config = {
1097
+			**chart_default_config,
1098
+			"series": activity_by_timezone_series
1099
+		}
1162 1100
 
1163 1101
 		activity_content.append(activity_html.addChart(activity_by_timezone_config, name='chartCommitsByTimezone', title='Commits by Timezone', className="xl:col-span-6"))
1164 1102
 
@@ -1170,35 +1108,35 @@ class HTMLReportCreator(ReportCreator):
1170 1108
 		# authors.html
1171 1109
 		# Authors
1172 1110
 		authors_content = []
1111
+		authors_content.append('<div class="grid grid-cols-12 gap-4 md:gap-6 2xl:gap-7.5">')
1112
+		
1173 1113
 		authors_html = html.HTML(path=f'{path}/authors.html', title='Authors', version= getversion())
1174 1114
 
1175 1115
 		# Authors :: List of authors
1176
-		authors_content.append(html_header(2, 'List of Authors'))
1116
+		list_authors_content = []
1177 1117
 
1178
-		authors_content.append('<div><div class="card-body"><table class="authors sortable" id="authors">')
1179
-		authors_content.append('<tr><th>Author</th><th>Commits (%)</th><th>+ lines</th><th>- lines</th><th>First commit</th><th>Last commit</th><th class="unsortable">Age</th><th>Active days</th><th># by commits</th></tr>')
1118
+		list_authors_content.append('<div><div class="card-body"><table class="authors sortable" id="authors">')
1119
+		list_authors_content.append('<tr><th>Author</th><th>Commits (%)</th><th>+ lines</th><th>- lines</th><th>First commit</th><th>Last commit</th><th class="unsortable">Age</th><th>Active days</th><th># by commits</th></tr>')
1180 1120
 		for author in data.getAuthors(conf['max_authors']):
1181 1121
 			info = data.getAuthorInfo(author)
1182
-			authors_content.append('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%d</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%d</td></tr>' % (author, info['commits'], info['commits_frac'], info['lines_added'], info['lines_removed'], info['date_first'], info['date_last'], info['timedelta'], len(info['active_days']), info['place_by_commits']))
1183
-		authors_content.append('</table></div></div>')
1122
+			list_authors_content.append('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%d</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%d</td></tr>' % (author, info['commits'], info['commits_frac'], info['lines_added'], info['lines_removed'], info['date_first'], info['date_last'], info['timedelta'], len(info['active_days']), info['place_by_commits']))
1123
+		list_authors_content.append('</table></div></div>')
1184 1124
 
1185 1125
 		allauthors = data.getAuthors()
1186 1126
 		if len(allauthors) > conf['max_authors']:
1187 1127
 			rest = allauthors[conf['max_authors']:]
1188
-			authors_content.append('<p class="moreauthors">These didn\'t make it to the top: %s</p>' % ', '.join(rest))
1189
-
1190
-		authors_content.append(html_header(2, 'Cumulated Added Lines of Code per Author'))
1191
-		authors_content.append('<img src="lines_of_code_by_author.png" alt="Lines of code per Author">')
1192
-		if len(allauthors) > conf['max_authors']:
1193
-			authors_content.append('<p class="moreauthors">Only top %d authors shown</p>' % conf['max_authors'])
1128
+			list_authors_content.append('<p class="moreauthors">These didn\'t make it to the top: %s</p>' % ', '.join(rest))
1129
+		
1130
+		authors_content.append(authors_html.addCard(list_authors_content, title='List of Authors'))
1194 1131
 
1195
-		authors_content.append(html_header(2, 'Commits per Author'))
1196
-		authors_content.append('<img src="commits_by_author.png" alt="Commits per Author">')
1197
-		if len(allauthors) > conf['max_authors']:
1198
-			authors_content.append('<p class="moreauthors">Only top %d authors shown</p>' % conf['max_authors'])
1132
+		# Authors :: Commits
1133
+		author_disclaimer = ''
1134
+		max_authors = conf['max_authors']
1135
+		if len(allauthors) > max_authors:
1136
+			author_disclaimer =f'<span class="text-xs font-medium">Only top {max_authors} authors shown</span>'
1199 1137
 
1200
-		fgl = open(path + '/lines_of_code_by_author.dat', 'w')
1201
-		fgc = open(path + '/commits_by_author.dat', 'w')
1138
+		# fgl = open(path + '/lines_of_code_by_author.dat', 'w')
1139
+		# fgc = open(path + '/commits_by_author.dat', 'w')
1202 1140
 
1203 1141
 		lines_by_authors = {} # cumulated added lines by
1204 1142
 		# author. to save memory,
@@ -1211,56 +1149,133 @@ class HTMLReportCreator(ReportCreator):
1211 1149
 		# time. Be robust and keep the list in a variable.
1212 1150
 		commits_by_authors = {} # cumulated added lines by
1213 1151
 
1152
+		colors = [
1153
+		"#4B0082",
1154
+		"#2E8B57",
1155
+		"#7B68EE",
1156
+		"#BA55D3",
1157
+		"#DB7093",
1158
+		"#FFD700",
1159
+		"#006400",
1160
+		"#008080",
1161
+		"#191970",
1162
+		"#0000CD",
1163
+		"#CD5C5C",
1164
+		"#FAFAD2",
1165
+		"#7FFF00",
1166
+		"#9966CC",
1167
+		"#D2B48C",
1168
+		"#000080",
1169
+		"#AFEEEE",
1170
+		"#8B008B",
1171
+		"#008000",
1172
+		"#6A5ACD"]
1173
+
1174
+		authors_cumulated_commits_series = {}
1175
+		authors_commits_series = {}
1176
+
1214 1177
 		self.authors_to_plot = data.getAuthors(conf['max_authors'])
1215
-		for author in self.authors_to_plot:
1178
+		for idx, author in enumerate(self.authors_to_plot):
1216 1179
 			lines_by_authors[author] = 0
1217 1180
 			commits_by_authors[author] = 0
1181
+			authors_cumulated_commits_series[author]= {"name": author, "color": colors[idx], "data": []}
1182
+			authors_commits_series[author]= {"name": author, "color": colors[idx], "data": []}
1183
+
1218 1184
 		for stamp in sorted(data.changes_by_date_by_author.keys()):
1219
-			fgl.write('%d' % stamp)
1220
-			fgc.write('%d' % stamp)
1185
+			# fgl.write('%d' % stamp)
1186
+			# fgc.write('%d' % stamp)
1221 1187
 			for author in self.authors_to_plot:
1222 1188
 				if author in data.changes_by_date_by_author[stamp].keys():
1223 1189
 					lines_by_authors[author] = data.changes_by_date_by_author[stamp][author]['lines_added']
1224 1190
 					commits_by_authors[author] = data.changes_by_date_by_author[stamp][author]['commits']
1225
-				fgl.write(' %d' % lines_by_authors[author])
1226
-				fgc.write(' %d' % commits_by_authors[author])
1227
-			fgl.write('\n')
1228
-			fgc.write('\n')
1229
-		fgl.close()
1230
-		fgc.close()
1191
+				# fgl.write(' %d' % lines_by_authors[author])
1192
+				# fgc.write(' %d' % commits_by_authors[author])
1193
+				# authors_cumulated_commits_series[author]['data'].append({"x": stamp, "y": lines_by_authors[author]})
1194
+				
1195
+				authors_cumulated_commits_series[author]['data'].append(lines_by_authors[author])
1196
+				authors_commits_series[author]['data'].append(commits_by_authors[author])
1197
+
1198
+		# 	fgl.write('\n')
1199
+		# 	fgc.write('\n')
1200
+		# fgl.close()
1201
+		# fgc.close()
1202
+
1203
+		# Authors :: Cumulated added LoC per author
1204
+		authors_cumulated_commits_config = {
1205
+			**chart_default_config,
1206
+			"chart": {**chart_default_config["chart"], "type": 'line'},
1207
+			"series": list(authors_cumulated_commits_series.values()),
1208
+			"markers": {"size": 0,"hover": {"sizeOffset": 6}},
1209
+			"xaxis": {
1210
+				**chart_default_config["xaxis"], 
1211
+				"labels": {
1212
+					**chart_default_config["xaxis"]["labels"] , 
1213
+					"show" : False
1214
+					}}
1215
+		}
1216
+
1217
+		# authors_content.append(activity_html.addChart(authors_cumulated_commits_config, name='chartCumulatedAddedLoCAuthor', title=f'Cumulated Added LoC per Author {author_disclaimer}', className="xl:col-span-6"))
1218
+
1219
+		# Authors :: Commits per Author
1220
+		authors_commits_config = {
1221
+			**chart_default_config,
1222
+			"chart": {**chart_default_config["chart"], "type": 'line'},
1223
+			"series": list(authors_commits_series.values()),
1224
+			"markers": {"size": 0,"hover": {"sizeOffset": 6}},
1225
+			"xaxis": {
1226
+				**chart_default_config["xaxis"], 
1227
+				"labels": {
1228
+					**chart_default_config["xaxis"]["labels"] , 
1229
+					"show" : False
1230
+					}}
1231
+		}
1232
+
1233
+		# authors_content.append(activity_html.addChart(authors_commits_config, name='chartCommitsPerAuthor', title=f'Commits per Author {author_disclaimer}', className="xl:col-span-6"))
1234
+
1231 1235
 
1232 1236
 		# Authors :: Author of Month
1233
-		authors_content.append(html_header(2, 'Author of Month'))
1234
-		authors_content.append('<table class="sortable" id="aom">')
1235
-		authors_content.append('<tr><th>Month</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
1237
+		author_of_month_content = []
1238
+		author_of_month_content.append('<table class="sortable" id="aom">')
1239
+		author_of_month_content.append('<tr><th>Month</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
1236 1240
 		for yymm in reversed(sorted(data.author_of_month.keys())):
1237 1241
 			authordict = data.author_of_month[yymm]
1238 1242
 			authors = getkeyssortedbyvalues(authordict)
1239 1243
 			authors.reverse()
1240 1244
 			commits = data.author_of_month[yymm][authors[0]]
1241 1245
 			next = ', '.join(authors[1:conf['authors_top']+1])
1242
-			authors_content.append('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td><td>%s</td><td>%d</td></tr>' % (yymm, authors[0], commits, (100.0 * commits) / data.commits_by_month[yymm], data.commits_by_month[yymm], next, len(authors)))
1246
+			author_of_month_content.append('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td><td>%s</td><td>%d</td></tr>' % (yymm, authors[0], commits, (100.0 * commits) / data.commits_by_month[yymm], data.commits_by_month[yymm], next, len(authors)))
1247
+
1248
+		author_of_month_content.append('</table>')
1243 1249
 
1244
-		authors_content.append('</table>')
1250
+		authors_content.append(authors_html.addCard(author_of_month_content, title='Author of Month'))
1245 1251
 
1246
-		authors_content.append(html_header(2, 'Author of Year'))
1247
-		authors_content.append('<table class="sortable" id="aoy"><tr><th>Year</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
1252
+		# Authors :: Author of Year
1253
+		author_of_year_content = []
1254
+		author_of_year_content.append('<table class="sortable" id="aoy"><tr><th>Year</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
1248 1255
 		for yy in reversed(sorted(data.author_of_year.keys())):
1249 1256
 			authordict = data.author_of_year[yy]
1250 1257
 			authors = getkeyssortedbyvalues(authordict)
1251 1258
 			authors.reverse()
1252 1259
 			commits = data.author_of_year[yy][authors[0]]
1253 1260
 			next = ', '.join(authors[1:conf['authors_top']+1])
1254
-			authors_content.append('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td><td>%s</td><td>%d</td></tr>' % (yy, authors[0], commits, (100.0 * commits) / data.commits_by_year[yy], data.commits_by_year[yy], next, len(authors)))
1255
-		authors_content.append('</table>')
1261
+			author_of_year_content.append('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td><td>%s</td><td>%d</td></tr>' % (yy, authors[0], commits, (100.0 * commits) / data.commits_by_year[yy], data.commits_by_year[yy], next, len(authors)))
1262
+		author_of_year_content.append('</table>')
1256 1263
 
1257
-		# Domains
1258
-		authors_content.append(html_header(2, 'Commits by Domains'))
1264
+		authors_content.append(authors_html.addCard(author_of_year_content, title='Author of Year', className="xl:col-span-6"))
1265
+
1266
+		# Authors :: Domains
1259 1267
 		domains_by_commits = getkeyssortedbyvaluekey(data.domains, 'commits')
1260 1268
 		domains_by_commits.reverse() # most first
1261
-		authors_content.append('<div class="vtable"><table>')
1262
-		authors_content.append('<tr><th>Domains</th><th>Total (%)</th></tr>')
1263
-		fp = open(path + '/domains.dat', 'w')
1269
+
1270
+		authors_commits_by_domains_series = [{
1271
+			"name": "Commits",
1272
+			"color": "#1A56DB",
1273
+			"data": []
1274
+		},{
1275
+			"name": "Percentage",
1276
+			"color": "#8FB0F6",
1277
+			"data": []
1278
+		}]
1264 1279
 		n = 0
1265 1280
 		for domain in domains_by_commits:
1266 1281
 			if n == conf['max_domains']:
@@ -1268,11 +1283,18 @@ class HTMLReportCreator(ReportCreator):
1268 1283
 			commits = 0
1269 1284
 			n += 1
1270 1285
 			info = data.getDomainInfo(domain)
1271
-			fp.write('%s %d %d\n' % (domain, n , info['commits']))
1272
-			authors_content.append('<tr><th>%s</th><td>%d (%.2f%%)</td></tr>' % (domain, info['commits'], (100.0 * info['commits'] / totalcommits)))
1273
-		authors_content.append('</table></div>')
1274
-		authors_content.append('<img src="domains.png" alt="Commits by Domains">')
1275
-		fp.close()
1286
+			authors_commits_by_domains_series[0]['data'].append({"x": domain, "y": info['commits']})
1287
+			p = (100.0 * info['commits'] / totalcommits)
1288
+			authors_commits_by_domains_series[1]['data'].append({"x": domain, "y": f'{p:.2f}'})
1289
+
1290
+		authors_commits_by_domains_config = {
1291
+			**chart_default_config,
1292
+			"series": authors_commits_by_domains_series,
1293
+		}
1294
+
1295
+		authors_content.append(activity_html.addChart(authors_commits_by_domains_config, name='chartCommitsbyDomains', title='Commits by Domains', className="xl:col-span-6"))
1296
+
1297
+		authors_content.append('</div>')
1276 1298
 
1277 1299
 		authors_html.create(authors_content)
1278 1300
 

+ 111
- 47
gitstats.css 파일 보기

@@ -3,65 +3,65 @@
3 3
  */
4 4
 
5 5
 dt {
6
-	font-weight: bold;
7
-	float: left;
8
-	margin-right: 1em;
6
+  font-weight: bold;
7
+  float: left;
8
+  margin-right: 1em;
9 9
 }
10 10
 
11 11
 dt:after {
12
-	content: ': ';
12
+  content: ": ";
13 13
 }
14 14
 
15 15
 dd {
16
-	display: block;
17
-	clear: left;
16
+  display: block;
17
+  clear: left;
18 18
 }
19 19
 
20 20
 table {
21
-	border: 1px solid black;
22
-	border-collapse: collapse;
23
-	font-size: 80%;
24
-	margin-bottom: 1em;
21
+  border: 1px solid black;
22
+  border-collapse: collapse;
23
+  font-size: 80%;
24
+  margin-bottom: 1em;
25 25
 }
26 26
 
27 27
 table.noborders {
28
-	border: none;
28
+  border: none;
29 29
 }
30 30
 
31 31
 table.noborders td {
32
-	border: none;
32
+  border: none;
33 33
 }
34 34
 
35 35
 .vtable {
36
-	float: right;
37
-	clear: both;
36
+  float: right;
37
+  clear: both;
38 38
 }
39 39
 
40 40
 table.tags td {
41
-	vertical-align: top;
41
+  vertical-align: top;
42 42
 }
43 43
 
44 44
 td {
45
-	background-color: white;
45
+  background-color: white;
46 46
 }
47 47
 
48 48
 th {
49
-	background-color: #ddf;
49
+  background-color: #ddf;
50 50
 }
51 51
 
52 52
 th a {
53
-	text-decoration: none;
53
+  text-decoration: none;
54 54
 }
55 55
 
56 56
 tr:hover {
57
-	background-color: #ddf;
57
+  background-color: #ddf;
58 58
 }
59 59
 
60 60
 td {
61
-	border: 1px solid black;
62
-	padding: 0.2em;
63
-	padding-left: 0.3em;
64
-	padding-right: 0.2em;
61
+  border: 1px solid black;
62
+  padding: 0.2em;
63
+  padding-left: 0.3em;
64
+  padding-right: 0.2em;
65 65
 }
66 66
 
67 67
 /* Navigation bar; tabbed style */
@@ -96,47 +96,111 @@ td {
96 96
 } */
97 97
 
98 98
 main img {
99
-	border: 1px solid black;
100
-	padding: 0.5em;
101
-	background-color: white;
99
+  border: 1px solid black;
100
+  padding: 0.5em;
101
+  background-color: white;
102 102
 }
103 103
 
104 104
 th img {
105
-	border: 0px;
106
-	padding: 0px;
107
-	background-color: #ddf;
105
+  border: 0px;
106
+  padding: 0px;
107
+  background-color: #ddf;
108 108
 }
109 109
 
110
-h1 a, h2 a {
111
-	color: black;
112
-	text-decoration: none;
110
+h1 a,
111
+h2 a {
112
+  color: black;
113
+  text-decoration: none;
113 114
 }
114 115
 
115
-main  h1:hover a:after,
116
-main  h2:hover a:after {
117
-	content: '¶';
118
-	color: #555;
116
+main h1:hover a:after,
117
+main h2:hover a:after {
118
+  content: "¶";
119
+  color: #555;
119 120
 }
120 121
 
121 122
 main h1 {
122
-	font-size: x-large;
123
+  font-size: x-large;
123 124
 }
124 125
 
125
-main  h2 {
126
-	background-color: #564;
127
-	border: 1px solid black;
128
-	padding-left: 0.5em;
129
-	padding-right: 0.5em;
130
-	color: white;
131
-	font-size: large;
132
-	clear: both;
126
+main h2 {
127
+  background-color: #564;
128
+  border: 1px solid black;
129
+  padding-left: 0.5em;
130
+  padding-right: 0.5em;
131
+  color: white;
132
+  font-size: large;
133
+  clear: both;
133 134
 }
134 135
 
135 136
 main h2 a {
136
-	color: white;
137
+  color: white;
137 138
 }
138 139
 
139 140
 main .moreauthors {
140
-	font-size: 80%;
141
+  font-size: 80%;
141 142
 }
142 143
 
144
+.dark .apexcharts-canvas .apexcharts-legend-text {
145
+  color: #aeb7c0 !important;
146
+}
147
+.apexcharts-canvas .apexcharts-legend-text {
148
+  color: #64748b !important;
149
+}
150
+
151
+.dark .apexcharts-canvas .apexcharts-text {
152
+  fill: #aeb7c0 !important;
153
+}
154
+
155
+.apexcharts-canvas .apexcharts-text {
156
+  fill: #64748b !important;
157
+}
158
+
159
+.dark .apexcharts-canvas .apexcharts-xcrosshairs {
160
+  fill: #2e3a47 !important;
161
+}
162
+.apexcharts-canvas .apexcharts-xcrosshairs {
163
+  fill: #e2e8f0 !important;
164
+}
165
+
166
+
167
+.dark .apexcharts-canvas .apexcharts-gridline {
168
+  stroke: #2e3a47 !important;
169
+}
170
+.apexcharts-canvas .apexcharts-gridline {
171
+  stroke: #e2e8f0 !important;
172
+}
173
+
174
+.dark .apexcharts-canvas .apexcharts-series.apexcharts-pie-series path {
175
+  stroke: transparent !important;
176
+}
177
+
178
+.apexcharts-canvas .apexcharts-legend-series {
179
+  display: inline-flex;
180
+  gap: 0.375rem
181
+}
182
+
183
+/*
184
+.apexcharts-tooltip.apexcharts-theme-light {
185
+  @apply dark:!border-strokedark dark:!bg-boxdark;
186
+}
187
+.apexcharts-tooltip.apexcharts-theme-light .apexcharts-tooltip-title {
188
+  @apply dark:!border-strokedark dark:!bg-meta-4;
189
+}
190
+.apexcharts-xaxistooltip,
191
+.apexcharts-yaxistooltip {
192
+  @apply dark:!border-meta-4 dark:!bg-meta-4 dark:!text-bodydark1;
193
+}
194
+.apexcharts-xaxistooltip-bottom:after {
195
+  @apply !border-b-gray dark:!border-b-meta-4;
196
+}
197
+.apexcharts-xaxistooltip-bottom:before {
198
+  @apply !border-b-gray dark:!border-b-meta-4;
199
+}
200
+.apexcharts-xaxistooltip-bottom {
201
+  @apply !rounded !border-none !bg-gray !text-xs !font-medium !text-black dark:!text-white;
202
+}
203
+.apexcharts-tooltip-series-group {
204
+  @apply !pl-1.5;
205
+}
206
+*/