Skip to content

Instantly share code, notes, and snippets.

@naxxateux
Created August 12, 2013 11:53
Show Gist options
  • Save naxxateux/6210223 to your computer and use it in GitHub Desktop.
Save naxxateux/6210223 to your computer and use it in GitHub Desktop.
RPL teams & countries visualization (slopegraph?)
Name Color
Австралия #e1a7aa
Азербайджан #91b9da
Ангола #d7af88
Аргентина #5fc98c
Армения #91b9da
Белоруссия #91b9da
Бельгия #91b9da
Болгария #91b9da
Босния и Герцеговина #91b9da
Бразилия #5fc98c
Буркина-Фасо #d7af88
Венгрия #91b9da
Венесуэла #5fc98c
Габон #d7af88
Гаити #d37f7d
Гана #d7af88
Германия #91b9da
Греция #91b9da
Грузия #91b9da
ДР Конго #d7af88
Замбия #d7af88
Израиль #91b9da
Иран #e1a7aa
Ирландия #91b9da
Испания #91b9da
Италия #91b9da
Камерун #d7af88
Колумбия #5fc98c
Конго #d7af88
Коста-Рика #d37f7d
Кот-д'Ивуар #d7af88
Латвия #91b9da
Литва #91b9da
Марокко #d7af88
Молдавия #91b9da
Нигерия #d7af88
Парагвай #5fc98c
Польша #91b9da
Португалия #91b9da
Румыния #91b9da
Сенегал #d7af88
Сербия #91b9da
Словакия #91b9da
Турция #91b9da
Узбекистан #e1a7aa
Украина #91b9da
Уругвай #5fc98c
Финляндия #91b9da
Франция #91b9da
Хорватия #91b9da
Черногория #91b9da
Чехия #91b9da
Чили #5fc98c
Швейцария #91b9da
Швеция #91b9da
Эквадор #5fc98c
Эстония #91b9da
ЮАР #d7af88
Южная Корея #e1a7aa
Ямайка #d37f7d
Япония #e1a7aa
<!DOCTYPE html>
<meta charset="utf-8">
<html lang="en">
<head>
<link rel="stylesheet" href="slopegraph.css">
<link rel="stylesheet" href="layout.css">
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="http://d3js.org/queue.v1.min.js"></script>
<script type="text/javascript" src="http://d3js.org/topojson.v0.min.js"></script>
<title></title>
</head>
<body>
<header>
<h1>
Foreign legion
</h1>
</header>
<section>
<div id="chart" align="center"></div>
</section>
<aside>
This interactive feature visualizes the connections between different countries and Russian Football Premier League teams. Click on a team or country circle to see specific connections. Under every team name you can find the percent of foreigners in team squad.
</aside>
<footer>
Built with <a href="http://www.d3js.org">d3.js</a>
</footer>
<script type="text/javascript">
// Global variables
var teamsData;
var countriesData;
var TeamsCountriesMatrix;
var teamQuantityArray = [];
var countryQuantityArray = [];
var nOfTeams;
var nOfCountries;
var countriesSectionHeight = 1700;
var countriesSectionPadding = {left: 125};
var countryNamePadding = {right: 30};
var teamsSectionHeight = 800;
var teamsSectionPadding = {left: 700};
var teamNamePadding = {left: 30};
var teamBarPadding = {top: 12, left: 30};
var teamBarHeight = 4;
var teamBarWidth = 100;
var teamBarDividerWidth = 1;
var teamPercentPadding = {top: (teamBarHeight + 3)};
var quantityCircleInitialRadius = 7;
var lineInitialWidth = 0.5;
var teamCircleHoverOpacity = 0.7;
var teamCircleDefaultOpacity = 0.5;
var teamCircleFadedOpacity = 0.1;
var teamBarHoverOpacity = 0.7;
var teamBarDefaultOpacity = 0.5;
var teamBarFadedOpacity = 0.1;
var teamTextDefaultOpacity = 1;
var teamTextFadedOpacity = 0.1;
var countryCircleHoverOpacity = 0.7;
var countryCircleDefaultOpacity = 0.5;
var countryCircleFadedOpacity = 0.1;
var countryTextDefaultOpacity = 1;
var countryTextFadedOpacity = 0.1;
var lineDefaultOpacity = 1;
var lineFadedOpacity = 0.1;
var lastClickedCountryIndex = 0;
var isCountryClicked = false;
var lastClickedTeamIndex = 0;
var isHoverActionsBlocked = false;
var fadingDuration = 0;
var radiusChangingDuration = 500;
var margin = {top: 20, right: 20, bottom: 20, left: 20};
var width = teamsSectionPadding.left + teamBarPadding.left + teamBarWidth - margin.left;
var height = countriesSectionHeight - margin.top;
// Utilities
function getRowSum(data, index) {
var sum = 0;
for (var i = 0; i < data[index].length; i++) {
sum += data[index][i];
}
return sum;
}
function getColSum(data, index) {
var sum = 0;
for (var i = 0; i < data.length; i++) {
sum += data[i][index];
}
return sum;
}
function getDocumentScrollTop() {
return window.document.body.scrollTop;
}
// Main unit
d3.csv("Teams.csv", function(error, data) {
if (error) {
console.log(error);
} else {
teamsData = data;
d3.csv("Countries.csv", function(error, data) {
if (error) {
console.log(error);
} else {
countriesData = data;
d3.text("Teams-Countries.csv", function(error, data) {
if (error) {
console.log(error);
} else {
TeamsCountriesMatrix = d3.csv.parseRows(data).map(function(row) {
return row.map(function(value) {
return +value;
});
});
// Fill quantity arrays
nOfTeams = teamsData.length;
nOfCountries = countriesData.length;
for (var i = 0; i < nOfTeams; i++) {
teamQuantityArray[i] = getRowSum(TeamsCountriesMatrix, i);
}
for (var i = 0; i < nOfCountries; i++) {
countryQuantityArray[i] = getColSum(TeamsCountriesMatrix, i);
}
// Returns an event handler for countries fading
function fadeCountries(isFadeFlagOn, index) {
var fadedCountries = SVG.selectAll(".country")
.filter(function(d, i) { return i != index; });
// Block hover actions if it's necessary
if (isFadeFlagOn) {
isHoverActionsBlocked = true;
} else {
isHoverActionsBlocked = false;
}
// Countries
fadedCountries.select(".country-name")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? countryTextFadedOpacity : countryTextDefaultOpacity; });
fadedCountries.select(".country-quantity-block")
.style("cursor", function() {return isFadeFlagOn ? "default" : "pointer"; });
fadedCountries.select(".country-quantity-block .country-quantity")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? countryCircleFadedOpacity : countryCircleDefaultOpacity; });
fadedCountries.select(".country-quantity-block .quantity")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? countryTextFadedOpacity : countryTextDefaultOpacity; });
// Teams
for (var i = 0; i < nOfTeams; i++) {
if (TeamsCountriesMatrix[i][index] === 0) {
// Teams NOT connected with current country
var fadedTeam = d3.select("#team-id-" + i);
fadedTeam.select(".team-name")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? teamTextFadedOpacity : teamTextDefaultOpacity; });
fadedTeam.select(".team-quantity-block .team-quantity")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? teamCircleFadedOpacity : teamCircleDefaultOpacity; });
fadedTeam.select(".team-quantity-block .quantity")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? teamTextFadedOpacity : teamTextDefaultOpacity; });
} else {
// Teams connected with current country
var activeTeam = d3.select("#team-id-" + i);
activeTeam.select(".team-quantity-block .quantity-background")
.transition()
.duration(radiusChangingDuration)
.attr("r", function() { return isFadeFlagOn ? (quantityCircleInitialRadius + TeamsCountriesMatrix[i][index]) : (quantityCircleInitialRadius + teamQuantityArray[i]); });
activeTeam.select(".team-quantity-block .team-quantity")
.transition()
.duration(radiusChangingDuration)
.attr("r", function() { return isFadeFlagOn ? (quantityCircleInitialRadius + TeamsCountriesMatrix[i][index]) : (quantityCircleInitialRadius + teamQuantityArray[i]); });
activeTeam.select(".team-quantity-block .quantity")
.transition()
.duration(fadingDuration)
.text(function() {return isFadeFlagOn ? TeamsCountriesMatrix[i][index] : teamQuantityArray[i]; });
}
// Team bar blocks for ALL teams
d3.select("#team-id-" + i).select(".team-bar-block")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? teamBarFadedOpacity : teamBarDefaultOpacity; });
// Team cursors for ALL teams
d3.select("#team-id-" + i).select(".team-quantity-block")
.style("cursor", function() {return isFadeFlagOn ? "default" : "pointer"; });
}
// Lines
d3.select(".lines").selectAll("line")
.filter(function(d, i) { return +d3.select(this).attr("id").replace("line-id-", "") != index; })
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? lineFadedOpacity : lineDefaultOpacity; });
}
// Returns an event handler for teams fading
function fadeTeams(isFadeFlagOn, index) {
var fadedTeams = SVG.selectAll(".team")
.filter(function(d, i) { return i != index; });
// Block hover actions if it's necessary
if (isFadeFlagOn) {
isHoverActionsBlocked = true;
} else {
isHoverActionsBlocked = false;
}
// Teams
fadedTeams.select(".team-name")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? teamTextFadedOpacity : teamTextDefaultOpacity; });
fadedTeams.select(".team-quantity-block")
.style("cursor", function() {return isFadeFlagOn ? "default" : "pointer"; });
fadedTeams.select(".team-quantity-block .team-quantity")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? teamCircleFadedOpacity : teamCircleDefaultOpacity; });
fadedTeams.select(".team-quantity-block .quantity")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? teamTextFadedOpacity : teamTextDefaultOpacity; });
// Countries
for (var i = 0; i < nOfCountries; i++) {
if (TeamsCountriesMatrix[index][i] === 0) {
// Teams NOT connected with current country
var fadedCountry = d3.select("#country-id-" + i);
fadedCountry.select(".country-name")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? countryTextFadedOpacity : countryTextDefaultOpacity; });
fadedCountry.select(".country-quantity-block .country-quantity")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? countryCircleFadedOpacity : countryCircleDefaultOpacity; });
fadedCountry.select(".country-quantity-block .quantity")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? countryTextFadedOpacity : countryTextDefaultOpacity; });
} else {
// Countries connected with current team
var activeCountry = d3.select("#country-id-" + i);
activeCountry.select(".country-quantity-block .quantity-background")
.transition()
.duration(radiusChangingDuration)
.attr("r", function() { return isFadeFlagOn ? (quantityCircleInitialRadius + TeamsCountriesMatrix[index][i]) : (quantityCircleInitialRadius + countryQuantityArray[i]); });
activeCountry.select(".country-quantity-block .country-quantity")
.transition()
.duration(radiusChangingDuration)
.attr("r", function() { return isFadeFlagOn ? (quantityCircleInitialRadius + TeamsCountriesMatrix[index][i]) : (quantityCircleInitialRadius + countryQuantityArray[i]); });
activeCountry.select(".country-quantity-block .quantity")
.transition()
.duration(fadingDuration)
.text(function() {return isFadeFlagOn ? TeamsCountriesMatrix[index][i] : countryQuantityArray[i]; });
}
// Team bar blocks for ALL teams
d3.select("#team-id-" + i).select(".team-bar-block")
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? teamBarFadedOpacity : teamBarDefaultOpacity; });
// Team cursors for ALL countries
d3.select("#country-id-" + i).select(".country-quantity-block")
.style("cursor", function() {return isFadeFlagOn ? "default" : "pointer"; });
}
// Lines
d3.select(".lines").selectAll("line")
.filter(function(d, i) { return +d3.select(this).attr("class").replace("line-", "") != index; })
.transition()
.duration(fadingDuration)
.style("opacity", function() {return isFadeFlagOn ? lineFadedOpacity : lineDefaultOpacity; });
}
// Draw initial SVG
var SVG = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Create scales for country & team blocks
var teamBlockYScale = d3.scale.linear()
.domain([0, nOfTeams])
.range([0, teamsSectionHeight]);
var countryBlockYScale = d3.scale.linear()
.domain([0, nOfCountries])
.range([0, countriesSectionHeight]);
// Draw lines
var lines = SVG.append("g")
.attr("class", "lines");
for (var i = 0; i < nOfTeams; i++) {
var y1 = teamBlockYScale(i);
for (var j = 0; j < nOfCountries; j++) {
if (TeamsCountriesMatrix[i][j] > 0) {
lines.append("line")
.attr("class", "line-" + i)
.attr("id", "line-id-" + j)
.attr("x1", teamsSectionPadding.left)
.attr("y1", y1)
.attr("x2", countriesSectionPadding.left)
.attr("y2", countryBlockYScale(j))
.style("opacity", lineDefaultOpacity)
.style("stroke", countriesData[j].Color)
.style("stroke-width", lineInitialWidth * TeamsCountriesMatrix[i][j]);
}
}
}
// Draw team blocks
var teams = SVG.append("g")
.attr("class", "teams")
.selectAll("g")
.data(teamsData)
.enter()
.append("g")
.attr("class", "team")
.attr("id", function(d, i) { return ("team-id-" + i); })
.attr("transform", function(d, i) { return ("translate(" + teamsSectionPadding.left + "," + teamBlockYScale(i) + ")"); });
teams.append("text")
.attr("class", "team-name")
.attr("x", teamNamePadding.left)
.style("opacity", teamTextDefaultOpacity)
.text(function(d) { return d.Name; });
var teamQuantityBlock = teams.append("g")
.attr("class", "team-quantity-block")
.style("cursor", "pointer")
.on("mouseover", function() {
if (!isHoverActionsBlocked) {
d3.select(this).select(".team-quantity")
.style("opacity", teamCircleHoverOpacity)
}
})
.on("mouseout", function() {
if (!isHoverActionsBlocked) {
d3.select(this).select(".team-quantity")
.style("opacity", teamCircleDefaultOpacity);
}
})
.on("click", function(d, i) {
if (!isCountryClicked) {
fadeTeams(true, i);
lastClickedTeamIndex = i + 1;
isCountryClicked = true;
} else if (i === lastClickedTeamIndex - 1) {
fadeTeams(false, i);
lastClickedTeamIndex = 0;
isCountryClicked = false;
}
});
teamQuantityBlock.append("circle")
.attr("class", "team-quantity-border")
.attr("r", function(d, i) { return (quantityCircleInitialRadius + teamQuantityArray[i]); });
teamQuantityBlock.append("circle")
.attr("class", "quantity-background")
.attr("r", function(d, i) { return (quantityCircleInitialRadius + teamQuantityArray[i]); });
teamQuantityBlock.append("circle")
.attr("class", "team-quantity")
.attr("r", function(d, i) { return (quantityCircleInitialRadius + teamQuantityArray[i]); })
.style("opacity", teamCircleDefaultOpacity);
teamQuantityBlock.append("text")
.attr("class", "quantity")
.style("opacity", teamTextDefaultOpacity)
.text(function(d, i) { return teamQuantityArray[i]; });
var teamBarBlock = teams.append("g")
.attr("class", "team-bar-block")
.style("opacity", teamBarDefaultOpacity)
.attr("transform", function() { return ("translate(" + teamBarPadding.left + "," + teamBarPadding.top + ")"); })
.on("mouseover", function(d, i) {
if (!isHoverActionsBlocked) {
var percent = teamQuantityArray[i] * teamBarWidth / d.Quantity;
d3.select(this)
.style("opacity", teamBarHoverOpacity);
d3.select(this).append("text")
.attr("class", "percent")
.attr("y", teamPercentPadding.top)
.text(function() { return (percent + " %"); });
}
})
.on("mouseout", function() {
if (!isHoverActionsBlocked) {
d3.select(this)
.style("opacity", teamBarDefaultOpacity);
d3.select(".percent").remove();
}
});
teamBarBlock.append("rect")
.attr("class", "team-bar-background")
.attr("width", teamBarWidth)
.attr("height", teamBarHeight);
teamBarBlock.append("rect")
.attr("class", "team-bar")
.attr("width", function(d, i) { return (teamQuantityArray[i] * teamBarWidth / d.Quantity); })
.attr("height", teamBarHeight);
teamBarBlock.append("rect")
.attr("class", "team-bar-divider")
.attr("x", teamBarWidth/2 - teamBarDividerWidth)
.attr("width", teamBarDividerWidth)
.attr("height", teamBarHeight);
// Draw country blocks
var countries = SVG.append("g")
.attr("class", "countries")
.selectAll("g")
.data(countriesData)
.enter()
.append("g")
.attr("class", "country")
.attr("id", function(d, i) { return ("country-id-" + i); })
.attr("transform", function(d, i) { return ("translate(" + countriesSectionPadding.left + "," + countryBlockYScale(i) + ")"); });
countries.append("text")
.attr("class", "country-name")
.attr("x", (-countryNamePadding.right))
.style("opacity", countryTextDefaultOpacity)
.text(function(d) { return d.Name; });
var countryQuantityBlock = countries.append("g")
.attr("class", "country-quantity-block")
.style("cursor", "pointer")
.on("mouseover", function() {
if (!isHoverActionsBlocked) {
d3.select(this).select(".country-quantity")
.style("opacity", countryCircleHoverOpacity);
}
})
.on("mouseout", function() {
if (!isHoverActionsBlocked) {
d3.select(this).select(".country-quantity")
.style("opacity", countryCircleDefaultOpacity);
}
})
.on("click", function(d, i) {
if (!isCountryClicked) {
fadeCountries(true, i);
lastClickedCountryIndex = i + 1;
isCountryClicked = true;
} else if (i === lastClickedCountryIndex - 1) {
fadeCountries(false, i);
lastClickedCountryIndex = 0;
isCountryClicked = false;
}
});
countryQuantityBlock.append("circle")
.attr("class", "country-quantity-border")
.attr("r", function(d, i) { return (quantityCircleInitialRadius + countryQuantityArray[i]); })
.style("fill", function(d) { return d.Color; });
countryQuantityBlock.append("circle")
.attr("class", "quantity-background")
.attr("r", function(d, i) { return (quantityCircleInitialRadius + countryQuantityArray[i]); });
countryQuantityBlock.append("circle")
.attr("class", "country-quantity")
.attr("r", function(d, i) { return (quantityCircleInitialRadius + countryQuantityArray[i]); })
.style("opacity", countryCircleDefaultOpacity)
.style("fill", function(d) { return d.Color; });
countryQuantityBlock.append("text")
.attr("class", "quantity")
.style("opacity", countryTextDefaultOpacity)
.text(function(d, i) { return countryQuantityArray[i]; });
}
});
}
});
}
});
</script>
</body>
</html>
body {
background: #fcfcfa;
font-family: "Trebuchet MS", serif;
margin: auto auto auto auto;
width: 1130px;
}
header {
font-size: 20pt;
margin: 20px 20px 20px 20px;
}
section {
float: left;
width: 850px;
margin: 20px 20px 20px 20px;
}
aside {
font-size: 10pt;
float: right;
width: 200px;
margin: 20px 20px 20px 20px;
}
footer {
font-size: 8pt;
clear: both;
margin: 20px 20px 20px 20px;
}
body {
background-color: #ffffff;
}
text {
font-family: Arial, sans-serif;
dominant-baseline: middle;
}
text.team-name {
font-size: 11px;
text-anchor: start;
}
text.country-name {
font-size: 11px;
text-anchor: end;
}
text.quantity {
font-size: 12px;
text-anchor: middle;
}
text.percent {
dominant-baseline: hanging;
font-size: 10px;
text-anchor: start;
}
rect.svg-background {
fill: #ffffff;
opacity: 0;
}
rect.team-bar {
fill: #308391;
}
rect.team-bar-background {
fill: #d4d9f0;
}
rect.team-bar-divider {
fill: #ffffff;
}
circle.team-quantity-border {
fill-opacity: 0.1;
fill: #308391;
}
circle.country-quantity-border {
fill-opacity: 0.1;
}
circle.quantity-background {
fill: #ffffff;
}
circle.team-quantity {
fill: #308391;
}
0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 2 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 1 0 2 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0
1 0 0 1 1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 2 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 2 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 2 0 0 2 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 3 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1 0 0 2 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 4 0 0 0 1 0 0 0 0 1 0 0 0 2 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 1 0 0 0 2 0 0 0 0 0 1 0 0 0 0 0
0 0 1 0 0 2 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 1 2 0 1 0 0 0 0 0 1 1 0 0
0 1 0 1 0 2 0 0 0 0 0 0 1 0 0 0 0 0 2 0 0 1 1 0 2 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 2 1 0 0 0 0 2 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 2 0 0 0 0 0 1
Name Quantity
Амкар 50
Анжи 50
Волга 50
Динамо 50
Зенит 50
Краснодар 50
Крылья Советов 50
Кубань 50
Локомотив 50
Ростов 50
Рубин 50
Спартак 50
Терек 50
Томь 50
Урал 50
ЦСКА 50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment