📜 ⬆️ ⬇️

SVG standings

I decided to make an interactive standings schedule for the football championship of Russia. Here is this:

image

The choice of tools was simple:

As a result, the choice naturally fell on a bunch of SVG + JavaScript (which, however, excluded IE from the list of supported browsers).

So let's go.
')
First of all, in the JavaScript section, we define the parameters of the tournament and the appearance of the table:

var nTeams = 16, nTours = (nTeams - 1) * 2, nToursPlayed = nTours;
var vPad = 30, vIndent = 0, hPad = 20, hIndent = 65;


Hooray. Now you can draw - to start the tournament grid. We define the commands and coordinates (M - MoveTo, H - Horizontal line, V - Vertical line, small letters mean that the coordinates are relative):

// Grid - horizontal lines
path = "M " + (hPad + hIndent) + " " + (vPad + vIndent);
for (i = 0; i < nTeams; i++)
{
path += "h " + width + " m -" + width + " " + vPad;
}

// Grid path - vertical lines
path += " M " + (hPad*2 + hIndent) + " " + (vPad + vIndent);
for (i = 0; i < nTours; i++)
{
path += "v " + height + " m " + hPad + " -" + height;
}


Now you need to do something with these coordinates. Everything is very simple - we create the “path” object defined by this line and add it to the document:

grid = svgDocument.createElementNS(svgns, "path");
grid.setAttributeNS(null, "d", path);
grid.setAttributeNS(null, "class", "grid");
svgDocument.documentElement.appendChild(grid);


Now with the filling. What to do with the data? To push in an array. How many elements are in an array? By the number of teams. What is each element of the array? The name of the team, the color of the team and then in order - a place in the corresponding round, for example:

[".", "#1E90FF", 4, 2, 4, 2, 3, 1, 4, 5, 3, 3, 3, 4, 6, 7, 7, 8, 11, 9, 9, 9, 9, 9, 10, 10, 12, 9, 9, 9, 10, 10]

And now we go around all the elements of the array, first putting down labels with the names of the teams, then drawing a progress chart:

// Create text labels - teams
for (i = 0; i < nTeams; i++)
{
label = svgDocument.createElementNS(svgns, "text");
label.setAttributeNS(null, "x", 0);
label.setAttributeNS(null, "y", vPad * (i + 1) + 4 + vIndent);
label.appendChild(document.createTextNode(tournamentData[i][0]));
svgDocument.documentElement.appendChild(label);
}

// Create team tracks
for (i = 0; i < nTeams; i++)
{
path = "M " + (hPad + hIndent) + " " + (vPad * (i + 1) + vIndent);

for (j = 0; j < nToursPlayed; j++)
{
path += " L " + (hPad * (j + 2) + hIndent) + " " + (vPad * tournamentData[i][j+2] + vIndent);
}
path += " L " + (hPad * (nTours + 1) + hIndent) + " " + (vPad * tournamentData[i][nToursPlayed+1] + vIndent);

teamTrack = svgDocument.createElementNS(svgns, "path");
teamTrack.setAttributeNS(null, "d", path);
teamTrack.setAttributeNS(null, "fill", "none");
teamTrack.setAttributeNS(null, "stroke", tournamentData[i][1]);
teamTrack.setAttributeNS(null, "stroke-width", 2);
teamTrack.setAttributeNS(null, "stroke-linejoin", "round");
teamTrack.setAttributeNS(null, "stroke-linecap", "round");
svgDocument.documentElement.appendChild(teamTrack);
}


What time to draw? Yes, at the moment of loading - all this code is entered into the makeShape function, called when the document is loaded:

<svg onload="makeShape(evt)" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

image

Not bad. But it's difficult to track the progress of one team. It would be great to single out one graph by clicking on the mouse. Wanted - done:

function highlight(evt, i)
{
var svgDocument = evt.target.ownerDocument;
var element = svgDocument.getElementById("track" + i);

// Trigger highligtning
if (element.getAttributeNS(null, "stroke-width") == "2")
element.setAttributeNS(null, "stroke-width", 10);
else
element.setAttributeNS(null, "stroke-width", 2);
}


Now we add a call to this function by clicking on the graph (and at the same time we assign id to the graph):

teamTrack.setAttributeNS(null, "id", "track" + i);
teamTrack.setAttributeNS(null, "onclick", "highlight(evt, " + i + ")");


image

Happened. :) You can see the result here , and take the code here . :)

Source: https://habr.com/ru/post/88500/


All Articles