summaryrefslogtreecommitdiff
path: root/codeforces-rating-cmp/main.js
blob: fe3bd5d5e1537b7a48ba17f057d3100b849547cb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
var users=new Array;
var animating=false;
var curTsL=0,curTsR=0;
var tarTsL=4294967296,tarTsR=0;
var curRtL=0,curRtR=0;
var tarRtL=9999,tarRtR=0;
var ctx;
var w,h;
var ratings=[0,1200,1400,1600,1900,2200,2300,2400,2600,2900,9999];
var ratingbg=["rgba(128,128,128,0.6)","rgba(0,255,0,0.6)","rgba(3,168,158,0.6)","rgba(0,0,255,0.6)","rgba(160,0,160,0.6)","rgba(255,140,0,0.6)","rgba(255,140,0,0.6)","rgba(255,0,0,0.6)","rgba(224,0,0,0.6)","rgba(204,0,0,0.6)"];
function init()
{
	ctx=document.getElementById("cvs").getContext("2d");
	w=document.getElementById("cvs").width;
	h=document.getElementById("cvs").height;
}
function min(a,b){return a<b?a:b;}
function max(a,b){return a>b?a:b;}
function randomColor(a)
{
	var h=Math.floor(Math.random()*30)*12;
	return "hsla("+h+",90%,45%,"+a+")";
}
function add()
{
	if(animating)return;
	var req=new XMLHttpRequest();
	req.onload=function(){
		var r=JSON.parse(req.responseText);
		if(r.status!=="OK")return;
		if(!Array.isArray(r.result)||r.result.length==0)return;
		r.maxr=0;r.minr=9999;r.maxt=0;r.mint=4294967296;r.selected=false;
		r.color=randomColor(0.8);r.pendingremove=false;r.bold=false;
		if(tarTsL==0)tarTsL=4294967296;
		for(var i=0;i<r.result.length;++i)
		{
			r.result[i].drawRating=0;
			r.maxr=max(r.maxr,r.result[i].newRating+200);
			r.minr=min(r.minr,r.result[i].newRating-200);
			r.maxt=max(r.maxt,r.result[i].ratingUpdateTimeSeconds);
			r.mint=min(r.mint,r.result[i].ratingUpdateTimeSeconds);
		}
		tarRtL=min(tarRtL,r.minr);tarRtR=max(tarRtR,r.maxr);
		tarTsL=min(tarTsL,r.mint);tarTsR=max(tarTsR,r.maxt);
		users.push(r);
		var o=document.createElement("div");
		o.userid=users.length-1;
		o.textContent=document.getElementById("name").value;
		o.classList.add("s");
		o.style.backgroundColor=r.color;
		o.onclick=function(){this.classList.toggle("selected");}
		o.onmouseenter=function(){highlight(this.userid,true);}
		o.onmouseleave=function(){highlight(this.userid,false);}
		document.getElementById("users").appendChild(o);
		animating=true;
		window.requestAnimationFrame(update);
	}
	req.open("GET","http://codeforces.com/api/user.rating?handle="+document.getElementById("name").value);
	req.send();
}
function remove()
{
	if(animating)return;
	for(var i=0;i<document.getElementById("users").childNodes.length;++i)
		if(document.getElementById("users").childNodes[i].classList.contains("selected"))
		users[i].pendingremove=true;
	for(var i=0;i<document.getElementById("users").childNodes.length;++i)
		if(document.getElementById("users").childNodes[i].classList.contains("selected"))
		{document.getElementById("users").removeChild(document.getElementById("users").childNodes[i]);--i;}		
	tarRtL=9999,tarRtR=0;
	tarTsL=4294967296,tarTsR=0;
	for(var i=0;i<users.length;++i)
	{
		if(users[i].pendingremove)continue;
		tarRtL=min(tarRtL,users[i].minr);tarRtR=max(tarRtR,users[i].maxr);
		tarTsL=min(tarTsL,users[i].mint);tarTsR=max(tarTsR,users[i].maxt);
	}
	if(tarRtL>tarRtR)tarRtR=1900,tarRtL=1000;
	if(tarTsL>tarTsR)tarTsL=tarTsR=0;
	animating=true;
	window.requestAnimationFrame(update);
}
function morph(a,b,s)
{
	var ret=a;if(Math.abs(a-b)>s)
	ret+=s*(b-a)/Math.abs(a-b);
	else ret=b;return ret;
}
function interpolate(a,b,c,d,x)
{
	var A=(d-c)/(b-a),B=c-a*A;
	return A*x+B;
}
function highlight(n,s)
{
	users[n].bold=s;window.requestAnimationFrame(update);
}
function update()
{
	var f=false;
	if(curTsL===0&&curTsR===0)
	{curTsL=tarTsL;curTsR=tarTsR;f=(tarTsL||tarTsR);}
	else
	{
		f|=Math.abs(curTsL-tarTsL)>432000;
		f|=Math.abs(curTsR-tarTsR)>432000;
		curTsL=morph(curTsL,tarTsL,max(Math.abs(curTsL-tarTsL)/5,432000));
		curTsR=morph(curTsR,tarTsR,max(Math.abs(curTsR-tarTsR)/5,432000));
	}
	if(curRtL===0&&curRtR===0)
	{curRtL=tarRtL;curRtR=tarRtR;f=true;}
	else
	{
		f|=Math.abs(curRtL-tarRtL)>10;
		f|=Math.abs(curRtR-tarRtR)>10;
		curRtL=morph(curRtL,tarRtL,max(Math.abs(curRtL-tarRtL)/5,10));
		curRtR=morph(curRtR,tarRtR,max(Math.abs(curRtR-tarRtR)/5,10));
	}
	ctx.clearRect(0,0,w,h);
	for(var i=0;i<ratings.length-1;++i)
	{
		ctx.fillStyle=ratingbg[i];
		ctx.fillRect(0,interpolate(curRtL,curRtR,h,0,ratings[i+1]),w,interpolate(curRtL,curRtR,h,0,ratings[i])-interpolate(curRtL,curRtR,h,0,ratings[i+1]));
	}
	for(var i=0;i<users.length;++i)
	{
		if(users[i].pendingremove)
		{
			var j;
			for(j=users[i].result.length-1;j>=0;--j)
			{
				if(users[i].result[j].drawRating<tarRtL){users[i].result[j].drawRating=0;f=true;}
				else if(users[i].result[j].drawRating-(max(tarRtR,users[i].result[j].newRating)-tarRtL)/20>tarRtL){users[i].result[j].drawRating-=(max(tarRtR,users[i].result[j].newRating)-tarRtL)/20;f=true;}
				else{users[i].result[j].drawRating=0;}
				if(users[i].result[j].drawRating>users[i].result[j].newRating*0.8)break;
			}
			if(j==-1){users.splice(i,1);--i;continue;}
			for(j=users[i].result.length-1;j>=0;--j)
			if(users[i].result[j].ratingUpdateTimeSeconds<tarTsL&&users[i].result[j].drawRating===0){users.splice(i,1);--i;j=-2;break;}
			if(j==-2)continue;
		}
		else for(var j=0;j<users[i].result.length;++j)
		{
			if(users[i].result[j].drawRating<tarRtL){users[i].result[j].drawRating=tarRtL;f=true;break;}
			else if(users[i].result[j].drawRating+(tarRtR-tarRtL)/30<users[i].result[j].newRating){users[i].result[j].drawRating+=(tarRtR-tarRtL)/30;f=true;
				if(users[i].result[j].drawRating<users[i].result[j].newRating*0.6)break;}
			else users[i].result[j].drawRating=users[i].result[j].newRating;
		}
		ctx.strokeStyle=users[i].color;
		ctx.lineWidth=users[i].bold?4:2;
		ctx.beginPath();
		ctx.moveTo(interpolate(curTsL,curTsR,0,w,users[i].result[0].ratingUpdateTimeSeconds),
		min(interpolate(curRtL,curRtR,h,0,users[i].result[0].drawRating),h+10));
		for(var j=1;j<users[i].result.length;++j)
		ctx.lineTo(interpolate(curTsL,curTsR,0,w,users[i].result[j].ratingUpdateTimeSeconds),
		min(interpolate(curRtL,curRtR,h,0,users[i].result[j].drawRating),h+10));
		ctx.stroke();
		ctx.fillStyle=users[i].color;
		for(var j=0;j<users[i].result.length;++j)
		{
			ctx.beginPath();
			ctx.arc(interpolate(curTsL,curTsR,0,w,users[i].result[j].ratingUpdateTimeSeconds),
			min(interpolate(curRtL,curRtR,h,0,users[i].result[j].drawRating),h+10),users[i].bold?5:3,0,2*Math.PI);
			ctx.fill();
		}
	}
	if(f)window.requestAnimationFrame(update);else animating=false;
}