Revert "On rajoute le graphe des résultats"
This reverts commit bd8ba6c327
.
This commit is contained in:
parent
bd8ba6c327
commit
942a8d852f
6 changed files with 8 additions and 104 deletions
|
@ -1,10 +1,9 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<div class="panel-block">
|
<div class="panel-block">
|
||||||
<div class="columns is-centered is-fullwidth is-vcentered">
|
<div class="columns is-centered is-fullwidth">
|
||||||
{# Tableau des duels #}
|
<div class="column">
|
||||||
<div class="column is-narrow">
|
<table class="table is-bordered is-striped">
|
||||||
<table class="table is-bordered is-striped is-centered">
|
|
||||||
<thead>
|
<thead>
|
||||||
<th class="has-text-centered">
|
<th class="has-text-centered">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
|
@ -45,16 +44,9 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# Graphe #}
|
|
||||||
<div class="column is-narrow">
|
|
||||||
<figure class="image">
|
|
||||||
{{ graph|safe }}
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-block">
|
<div class="panel-block">
|
||||||
<i>{% trans "La matrice des résultats montre les points d'avance, l'option gagnante est affichée sur la colonne et la perdante sur la ligne. Le graphe représente les duels entre les options, le nombre de votes d'avance est précisé sur l'arête." %}</i>
|
<i>{% trans "La matrice des résultats montre les points d'avance, l'option gagnante est affichée sur la colonne et la perdante sur la ligne. " %}</i>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,8 +3,6 @@ import io
|
||||||
|
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from matplotlib.colors import ListedColormap
|
|
||||||
from matplotlib.figure import Figure
|
|
||||||
from networkx.algorithms.dag import ancestors, descendants
|
from networkx.algorithms.dag import ancestors, descendants
|
||||||
|
|
||||||
from django.contrib.auth.hashers import make_password
|
from django.contrib.auth.hashers import make_password
|
||||||
|
@ -247,31 +245,14 @@ class ResultsData:
|
||||||
return render_to_string("elections/results/select.html")
|
return render_to_string("elections/results/select.html")
|
||||||
|
|
||||||
def rank(question):
|
def rank(question):
|
||||||
"""
|
"""On récupère la matrice des résultats et on l'affiche"""
|
||||||
On récupère la matrice des résultats et on l'affiche, ainsi que le graphe des duels
|
duels = question.duels.all()
|
||||||
"""
|
|
||||||
duels = question.duels.select_related("winner", "loser").all()
|
|
||||||
options = list(question.options.all())
|
options = list(question.options.all())
|
||||||
n = len(options)
|
n = len(options)
|
||||||
|
|
||||||
# Initialisation
|
|
||||||
_matrix = np.zeros((n, n), dtype=int)
|
_matrix = np.zeros((n, n), dtype=int)
|
||||||
matrix = np.zeros((n, n), dtype=tuple)
|
matrix = np.zeros((n, n), dtype=tuple)
|
||||||
|
|
||||||
G = nx.DiGraph()
|
|
||||||
G.add_nodes_from(options)
|
|
||||||
graph = io.StringIO()
|
|
||||||
e_labels = {}
|
|
||||||
max_votes = 1
|
|
||||||
|
|
||||||
# Création de la liste des couleurs pour les arêtes
|
|
||||||
values = np.ones((128, 4))
|
|
||||||
values[:, 0] = np.linspace(29, 72, 128) / 256
|
|
||||||
values[:, 1] = np.linspace(39, 199, 128) / 256
|
|
||||||
values[:, 2] = np.linspace(58, 116, 128) / 256
|
|
||||||
cmap = ListedColormap(values)
|
|
||||||
|
|
||||||
# On récupère les données
|
|
||||||
for d in duels:
|
for d in duels:
|
||||||
i, j = options.index(d.loser), options.index(d.winner)
|
i, j = options.index(d.loser), options.index(d.winner)
|
||||||
_matrix[i, j] = d.amount
|
_matrix[i, j] = d.amount
|
||||||
|
@ -280,13 +261,6 @@ class ResultsData:
|
||||||
for j in range(n):
|
for j in range(n):
|
||||||
if _matrix[i, j] > _matrix[j, i]:
|
if _matrix[i, j] > _matrix[j, i]:
|
||||||
matrix[i, j] = (_matrix[i, j], "is-success")
|
matrix[i, j] = (_matrix[i, j], "is-success")
|
||||||
|
|
||||||
# On rajoute un arête sur le graphe
|
|
||||||
nb_votes = _matrix[i, j] - _matrix[j, i]
|
|
||||||
max_votes = max(nb_votes, max_votes)
|
|
||||||
G.add_edge(options[j], options[i], weight=nb_votes)
|
|
||||||
e_labels[(options[j], options[i])] = nb_votes
|
|
||||||
|
|
||||||
elif _matrix[i, j] < _matrix[j, i]:
|
elif _matrix[i, j] < _matrix[j, i]:
|
||||||
matrix[i, j] = (_matrix[i, j], "is-danger")
|
matrix[i, j] = (_matrix[i, j], "is-danger")
|
||||||
else:
|
else:
|
||||||
|
@ -294,52 +268,9 @@ class ResultsData:
|
||||||
|
|
||||||
matrix = zip(matrix.tolist(), options)
|
matrix = zip(matrix.tolist(), options)
|
||||||
|
|
||||||
# On dessine le graphe
|
|
||||||
fig = Figure()
|
|
||||||
ax = fig.gca()
|
|
||||||
|
|
||||||
n_labels = {o: o.abbreviation or (i + 1) for i, o in enumerate(options)}
|
|
||||||
|
|
||||||
# Calcul des couleurs des arêtes
|
|
||||||
e_list = G.edges()
|
|
||||||
w_list = nx.get_edge_attributes(G, "weight")
|
|
||||||
e_colors = [w_list[e] / max_votes for e in e_list]
|
|
||||||
|
|
||||||
# Affichage du graphe
|
|
||||||
g_pos = nx.spring_layout(G)
|
|
||||||
nx.draw_networkx_nodes(G, g_pos, node_color="#1d273a", node_size=1500, ax=ax)
|
|
||||||
nx.draw_networkx_edges(
|
|
||||||
G,
|
|
||||||
g_pos,
|
|
||||||
arrowstyle="->",
|
|
||||||
arrowsize=30,
|
|
||||||
edge_color=e_colors,
|
|
||||||
edge_cmap=cmap,
|
|
||||||
width=3,
|
|
||||||
connectionstyle="arc3,rad=0.1",
|
|
||||||
min_target_margin=18,
|
|
||||||
ax=ax,
|
|
||||||
)
|
|
||||||
nx.draw_networkx_labels(G, g_pos, font_color="#f1f4f8", labels=n_labels, ax=ax)
|
|
||||||
nx.draw_networkx_edge_labels(
|
|
||||||
G,
|
|
||||||
g_pos,
|
|
||||||
edge_labels=e_labels,
|
|
||||||
ax=ax,
|
|
||||||
rotate=False,
|
|
||||||
bbox={"fc": "#f1f4f8", "ec": "#1d273a", "boxstyle": "round,pad=0.6"},
|
|
||||||
)
|
|
||||||
|
|
||||||
fig.savefig(graph, format="svg")
|
|
||||||
|
|
||||||
return render_to_string(
|
return render_to_string(
|
||||||
"elections/results/rank.html",
|
"elections/results/rank.html",
|
||||||
{
|
{"q": question, "matrix": matrix, "options": options},
|
||||||
"q": question,
|
|
||||||
"matrix": matrix,
|
|
||||||
"options": options,
|
|
||||||
"graph": graph.getvalue(),
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,4 @@ django-translated-fields==0.11.1
|
||||||
authens>=0.1b2
|
authens>=0.1b2
|
||||||
numpy
|
numpy
|
||||||
networkx
|
networkx
|
||||||
matplotlib
|
|
||||||
python-csv
|
python-csv
|
||||||
|
|
|
@ -10589,13 +10589,4 @@ body {
|
||||||
white-space: unset;
|
white-space: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table.is-centered {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.columns.is-fullwidth {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=main.css.map */
|
/*# sourceMappingURL=main.css.map */
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -36,12 +36,3 @@ body
|
||||||
height: auto
|
height: auto
|
||||||
min-height: 2em
|
min-height: 2em
|
||||||
white-space: unset
|
white-space: unset
|
||||||
|
|
||||||
// Centered tables
|
|
||||||
.table.is-centered
|
|
||||||
margin-left: auto
|
|
||||||
margin-right: auto
|
|
||||||
|
|
||||||
// Fullwidth columns
|
|
||||||
.columns.is-fullwidth
|
|
||||||
width: 100%
|
|
||||||
|
|
Loading…
Reference in a new issue