Update opolka/ScoDoc from ScoDoc/ScoDoc #2

Merged
opolka merged 1272 commits from ScoDoc/ScoDoc:master into master 2024-05-27 09:11:04 +02:00
2 changed files with 416 additions and 331 deletions
Showing only changes of commit 7b62ab8784 - Show all commits

View File

@ -7,25 +7,39 @@ $(function () {
display_itemsuivis(false); display_itemsuivis(false);
}); });
function display_itemsuivis(active) { function display_itemsuivis(active) {
var etudid = $('div#fichedebouche').data("etudid"); var etudid = $("div#fichedebouche").data("etudid");
var readonly = $('div#fichedebouche').data('readonly'); // present ro interface var readonly = $("div#fichedebouche").data("readonly"); // present ro interface
if (!readonly) { if (!readonly) {
$('#adddebouchelink').off("click").click(function (e) { $("#adddebouchelink")
.off("click")
.click(function (e) {
e.preventDefault(); e.preventDefault();
$.post(SCO_URL + "/itemsuivi_create", { etudid: etudid, format: 'json' }).done(item_insert_new); $.post(SCO_URL + "/itemsuivi_create", {
etudid: etudid,
fmt: "json",
}).done(item_insert_new);
return false; return false;
}); });
} }
// add existing items // add existing items
$.get(SCO_URL + "/itemsuivi_list_etud", { etudid: etudid, format: 'json' }, function (L) { $.get(
SCO_URL + "/itemsuivi_list_etud",
{ etudid: etudid, fmt: "json" },
function (L) {
for (var i in L) { for (var i in L) {
item_insert(L[i]['itemsuivi_id'], L[i]['item_date'], L[i]['situation'], L[i]['tags'], readonly); item_insert(
L[i]["itemsuivi_id"],
L[i]["item_date"],
L[i]["situation"],
L[i]["tags"],
readonly
);
} }
}); }
);
$("div#fichedebouche").accordion({ $("div#fichedebouche").accordion({
heightStyle: "content", heightStyle: "content",
@ -35,99 +49,115 @@ function display_itemsuivis(active) {
} }
function item_insert_new(it) { function item_insert_new(it) {
item_insert(it.itemsuivi_id, it.item_date, it.situation, '', false); item_insert(it.itemsuivi_id, it.item_date, it.situation, "", false);
} }
function item_insert(itemsuivi_id, item_date, situation, tags, readonly) { function item_insert(itemsuivi_id, item_date, situation, tags, readonly) {
if (item_date === undefined) if (item_date === undefined) item_date = Date2DMY(new Date());
item_date = Date2DMY(new Date()); if (situation === undefined) situation = "";
if (situation === undefined) if (tags === undefined) tags = "";
situation = '';
if (tags === undefined)
tags = '';
var nodes = item_nodes(itemsuivi_id, item_date, situation, tags, readonly); var nodes = item_nodes(itemsuivi_id, item_date, situation, tags, readonly);
// insert just before last li: // insert just before last li:
if ($('ul.listdebouches li.adddebouche').length > 0) { if ($("ul.listdebouches li.adddebouche").length > 0) {
$('ul.listdebouches').children(':last').before(nodes); $("ul.listdebouches").children(":last").before(nodes);
} else { } else {
// mode readonly, pas de li "ajouter" // mode readonly, pas de li "ajouter"
$('ul.listdebouches').append(nodes); $("ul.listdebouches").append(nodes);
} }
}; }
function item_nodes(itemsuivi_id, item_date, situation, tags, readonly) { function item_nodes(itemsuivi_id, item_date, situation, tags, readonly) {
// console.log('item_nodes: itemsuivi_id=' + itemsuivi_id); // console.log('item_nodes: itemsuivi_id=' + itemsuivi_id);
var sel_mois = 'Situation à la date du <input type="text" class="itemsuividatepicker" size="10" value="' + item_date + '"/><span class="itemsuivi_suppress" onclick="itemsuivi_suppress(\'' + itemsuivi_id + '\')"><img width="10" height="9" border="0" title="" alt="supprimer cet item" src="/ScoDoc/static/icons/delete_small_img.png"/></span>'; var sel_mois =
'Situation à la date du <input type="text" class="itemsuividatepicker" size="10" value="' +
item_date +
'"/><span class="itemsuivi_suppress" onclick="itemsuivi_suppress(\'' +
itemsuivi_id +
'\')"><img width="10" height="9" border="0" title="" alt="supprimer cet item" src="/ScoDoc/static/icons/delete_small_img.png"/></span>';
var h = sel_mois; var h = sel_mois;
// situation // situation
h += '<div class="itemsituation editable" data-type="textarea" data-url="itemsuivi_set_situation" data-placeholder="<em>décrire situation...</em>" data-object="' + itemsuivi_id + '">' + situation + '</div>'; h +=
'<div class="itemsituation editable" data-type="textarea" data-url="itemsuivi_set_situation" data-placeholder="<em>décrire situation...</em>" data-object="' +
itemsuivi_id +
'">' +
situation +
"</div>";
// tags: // tags:
h += '<div class="itemsuivi_tag_edit"><textarea class="itemsuivi_tag_editor">' + tags + '</textarea></div>'; h +=
'<div class="itemsuivi_tag_edit"><textarea class="itemsuivi_tag_editor">' +
tags +
"</textarea></div>";
var nodes = $($.parseHTML('<li class="itemsuivi">' + h + '</li>')); var nodes = $($.parseHTML('<li class="itemsuivi">' + h + "</li>"));
var dp = nodes.find('.itemsuividatepicker'); var dp = nodes.find(".itemsuividatepicker");
dp.blur(function (e) { dp.blur(function (e) {
var date = this.value; var date = this.value;
// console.log('selected text: ' + date); // console.log('selected text: ' + date);
$.post(SCO_URL + "/itemsuivi_set_date", { item_date: date, itemsuivi_id: itemsuivi_id }); $.post(SCO_URL + "/itemsuivi_set_date", {
item_date: date,
itemsuivi_id: itemsuivi_id,
});
}); });
dp.datepicker({ dp.datepicker({
onSelect: function (date, instance) { onSelect: function (date, instance) {
// console.log('selected: ' + date + 'for itemsuivi_id ' + itemsuivi_id); // console.log('selected: ' + date + 'for itemsuivi_id ' + itemsuivi_id);
$.post(SCO_URL + "/itemsuivi_set_date", { item_date: date, itemsuivi_id: itemsuivi_id }); $.post(SCO_URL + "/itemsuivi_set_date", {
}, item_date: date,
showOn: 'button', itemsuivi_id: itemsuivi_id,
buttonImage: '/ScoDoc/static/icons/calendar_img.png',
buttonImageOnly: true,
dateFormat: 'dd/mm/yy',
duration: 'fast',
disabled: readonly
}); });
dp.datepicker('option', $.extend({ showMonthAfterYear: false }, },
$.datepicker.regional['fr'])); showOn: "button",
buttonImage: "/ScoDoc/static/icons/calendar_img.png",
buttonImageOnly: true,
dateFormat: "dd/mm/yy",
duration: "fast",
disabled: readonly,
});
dp.datepicker(
"option",
$.extend({ showMonthAfterYear: false }, $.datepicker.regional["fr"])
);
if (readonly) { if (readonly) {
// show tags read-only // show tags read-only
readOnlyTags(nodes.find('.itemsuivi_tag_editor')); readOnlyTags(nodes.find(".itemsuivi_tag_editor"));
} } else {
else {
// bind tag editor // bind tag editor
nodes.find('.itemsuivi_tag_editor').tagEditor({ nodes.find(".itemsuivi_tag_editor").tagEditor({
initialTags: '', initialTags: "",
placeholder: 'Tags...', placeholder: "Tags...",
onChange: function (field, editor, tags) { onChange: function (field, editor, tags) {
$.post('itemsuivi_tag_set', $.post("itemsuivi_tag_set", {
{
itemsuivi_id: itemsuivi_id, itemsuivi_id: itemsuivi_id,
taglist: tags.join() taglist: tags.join(),
}); });
}, },
autocomplete: { autocomplete: {
delay: 200, // ms before suggest delay: 200, // ms before suggest
position: { collision: 'flip' }, // automatic menu position up/down position: { collision: "flip" }, // automatic menu position up/down
source: "itemsuivi_tag_search" source: "itemsuivi_tag_search",
}, },
}); });
// bind inplace editor // bind inplace editor
nodes.find('div.itemsituation').jinplace(); nodes.find("div.itemsituation").jinplace();
} }
return nodes; return nodes;
}; }
function Date2DMY(date) { function Date2DMY(date) {
var year = date.getFullYear(); var year = date.getFullYear();
var month = (1 + date.getMonth()).toString(); var month = (1 + date.getMonth()).toString();
month = month.length > 1 ? month : '0' + month; month = month.length > 1 ? month : "0" + month;
var day = date.getDate().toString(); var day = date.getDate().toString();
day = day.length > 1 ? day : '0' + day; day = day.length > 1 ? day : "0" + day;
return day + '/' + month + '/' + year; return day + "/" + month + "/" + year;
} }
function itemsuivi_suppress(itemsuivi_id) { function itemsuivi_suppress(itemsuivi_id) {

View File

@ -11,7 +11,6 @@ $().ready(function () {
get_notes_and_draw(formsemestre_id, etudid); get_notes_and_draw(formsemestre_id, etudid);
}); });
var WIDTH = 460; // taille du canvas SVG var WIDTH = 460; // taille du canvas SVG
var HEIGHT = WIDTH; var HEIGHT = WIDTH;
var CX = WIDTH / 2; // coordonnees centre du cercle var CX = WIDTH / 2; // coordonnees centre du cercle
@ -33,18 +32,23 @@ function get_notes_and_draw(formsemestre_id, etudid) {
'moy' : 16 }, 'moy' : 16 },
]; ];
*/ */
var query = SCO_URL + "/Notes/formsemestre_bulletinetud?formsemestre_id=" + formsemestre_id + "&etudid=" + etudid + "&format=json&version=selectedevals&force_publishing=1" var query =
SCO_URL +
"/Notes/formsemestre_bulletinetud?formsemestre_id=" +
formsemestre_id +
"&etudid=" +
etudid +
"&fmt=json&version=selectedevals&force_publishing=1";
$.get(query, '', function (bul) { $.get(query, "", function (bul) {
var notes = []; var notes = [];
bul.ue.forEach( bul.ue.forEach(function (ue, i, ues) {
function (ue, i, ues) { ue["module"].forEach(function (m, i) {
ue['module'].forEach(function (m, i) {
notes.push({ notes.push({
'code': m['code'], code: m["code"],
'titre': m['titre'], titre: m["titre"],
'note': m['note']['value'], note: m["note"]["value"],
'moy': m['note']['moy'] moy: m["note"]["moy"],
}); });
}); });
}); });
@ -55,50 +59,62 @@ function get_notes_and_draw(formsemestre_id, etudid) {
function draw_radar(notes) { function draw_radar(notes) {
/* Calcul coordonnées des éléments */ /* Calcul coordonnées des éléments */
var nmod = notes.length; var nmod = notes.length;
var angle = 2 * Math.PI / nmod; var angle = (2 * Math.PI) / nmod;
for (var i = 0; i < notes.length; i++) { for (var i = 0; i < notes.length; i++) {
var d = notes[i]; var d = notes[i];
var cx = Math.sin(i * angle); var cx = Math.sin(i * angle);
var cy = - Math.cos(i * angle); var cy = -Math.cos(i * angle);
d["x_v"] = CX + RR * d.note / 20 * cx; d["x_v"] = CX + ((RR * d.note) / 20) * cx;
d["y_v"] = CY + RR * d.note / 20 * cy; d["y_v"] = CY + ((RR * d.note) / 20) * cy;
d["x_moy"] = CX + RR * d.moy / 20 * cx; d["x_moy"] = CX + ((RR * d.moy) / 20) * cx;
d["y_moy"] = CY + RR * d.moy / 20 * cy; d["y_moy"] = CY + ((RR * d.moy) / 20) * cy;
d["x_20"] = CX + RR * cx; d["x_20"] = CX + RR * cx;
d["y_20"] = CY + RR * cy; d["y_20"] = CY + RR * cy;
d["x_label"] = CX + (RR + 25) * cx - 10 d["x_label"] = CX + (RR + 25) * cx - 10;
d["y_label"] = CY + (RR + 25) * cy + 10; d["y_label"] = CY + (RR + 25) * cy + 10;
d["tics"] = []; d["tics"] = [];
// Coords des tics sur chaque axe // Coords des tics sur chaque axe
for (var j = 0; j < NB_TICS; j++) { for (var j = 0; j < NB_TICS; j++) {
var r = R_TICS[j] / 20 * RR; var r = (R_TICS[j] / 20) * RR;
d["tics"][j] = { "x": CX + r * cx, "y": CY + r * cy }; d["tics"][j] = { x: CX + r * cx, y: CY + r * cy };
} }
} }
var notes_circ = notes.slice(0); var notes_circ = notes.slice(0);
notes_circ.push(notes[0]) notes_circ.push(notes[0]);
var notes_circ_valid = notes_circ.filter(function (e, i, a) { return e.note != 'NA' && e.note != '-'; }); var notes_circ_valid = notes_circ.filter(function (e, i, a) {
var notes_valid = notes.filter(function (e, i, a) { return e.note != 'NA' && e.note != '-'; }) return e.note != "NA" && e.note != "-";
});
var notes_valid = notes.filter(function (e, i, a) {
return e.note != "NA" && e.note != "-";
});
/* Crée l'élément SVG */ /* Crée l'élément SVG */
g = d3.select("#radar_bulletin").append("svg") g = d3
.select("#radar_bulletin")
.append("svg")
.attr("class", "radar") .attr("class", "radar")
.attr("width", WIDTH + 100) .attr("width", WIDTH + 100)
.attr("height", HEIGHT); .attr("height", HEIGHT);
/* Centre */ /* Centre */
g.append("circle").attr("cy", CY) g.append("circle")
.attr("cy", CY)
.attr("cx", CX) .attr("cx", CX)
.attr("r", 2) .attr("r", 2)
.attr("class", "radar_center_mark"); .attr("class", "radar_center_mark");
/* Lignes "tics" */ /* Lignes "tics" */
for (var j = 0; j < NB_TICS; j++) { for (var j = 0; j < NB_TICS; j++) {
var ligne_tics = d3.svg.line() var ligne_tics = d3.svg
.x(function (d) { return d["tics"][j]["x"]; }) .line()
.y(function (d) { return d["tics"][j]["y"]; }); .x(function (d) {
return d["tics"][j]["x"];
})
.y(function (d) {
return d["tics"][j]["y"];
});
g.append("svg:path") g.append("svg:path")
.attr("class", "radar_disk_tic") .attr("class", "radar_disk_tic")
.attr("id", "radar_disk_tic_" + R_TICS[j]) .attr("id", "radar_disk_tic_" + R_TICS[j])
@ -108,26 +124,40 @@ function draw_radar(notes) {
/* Lignes radiales pour chaque module */ /* Lignes radiales pour chaque module */
g.selectAll("radar_rad") g.selectAll("radar_rad")
.data(notes) .data(notes)
.enter().append("line") .enter()
.append("line")
.attr("x1", CX) .attr("x1", CX)
.attr("y1", CY) .attr("y1", CY)
.attr("x2", function (d) { return d["x_20"]; }) .attr("x2", function (d) {
.attr("y2", function (d) { return d["y_20"]; }) return d["x_20"];
})
.attr("y2", function (d) {
return d["y_20"];
})
.attr("class", "radarrad"); .attr("class", "radarrad");
/* Lignes entre notes */ /* Lignes entre notes */
var ligne = d3.svg.line() var ligne = d3.svg
.x(function (d) { return d["x_v"]; }) .line()
.y(function (d) { return d["y_v"]; }); .x(function (d) {
return d["x_v"];
})
.y(function (d) {
return d["y_v"];
});
g.append("svg:path") g.append("svg:path")
.attr("class", "radarnoteslines") .attr("class", "radarnoteslines")
.attr("d", ligne(notes_circ_valid)); .attr("d", ligne(notes_circ_valid));
var ligne_moy = d3.svg.line() var ligne_moy = d3.svg
.x(function (d) { return d["x_moy"]; }) .line()
.y(function (d) { return d["y_moy"]; }) .x(function (d) {
return d["x_moy"];
})
.y(function (d) {
return d["y_moy"];
});
g.append("svg:path") g.append("svg:path")
.attr("class", "radarmoylines") .attr("class", "radarmoylines")
@ -136,81 +166,96 @@ function draw_radar(notes) {
/* Points (notes) */ /* Points (notes) */
g.selectAll("circle1") g.selectAll("circle1")
.data(notes_valid) .data(notes_valid)
.enter().append("circle") .enter()
.attr("cx", function (d) { return d["x_v"]; }) .append("circle")
.attr("cy", function (d) { return d["y_v"]; }) .attr("cx", function (d) {
.attr("r", function (x, i) { return 3; }) return d["x_v"];
})
.attr("cy", function (d) {
return d["y_v"];
})
.attr("r", function (x, i) {
return 3;
})
.style("stroke-width", 1) .style("stroke-width", 1)
.style("stroke", "black") .style("stroke", "black")
.style("fill", "blue") .style("fill", "blue")
.on("mouseover", function (d) { .on("mouseover", function (d) {
var rwidth = 310; var rwidth = 310;
var x = d["x_v"]; var x = d["x_v"];
if ((x - CX) < 0) { if (x - CX < 0) {
x = x + 5; x = x + 5;
if (x + rwidth + 12 > WIDTH) { if (x + rwidth + 12 > WIDTH) {
x = WIDTH - rwidth - 12; x = WIDTH - rwidth - 12;
} }
} } else {
else { if (x - CX > 0) {
if ((x - CX) > 0) {
x = x - rwidth - 5; x = x - rwidth - 5;
if (x < 12) { if (x < 12) {
x = 12; x = 12;
} }
} } else {
else {
x = CX - rwidth / 2; x = CX - rwidth / 2;
} }
} }
var yrect = d["y_v"]; var yrect = d["y_v"];
var ytext = d["y_v"]; var ytext = d["y_v"];
if ((yrect - CY) > 0) { if (yrect - CY > 0) {
yrect = yrect - 5 - 20; yrect = yrect - 5 - 20;
ytext = ytext - 5 - 20 + 16; ytext = ytext - 5 - 20 + 16;
} } else {
else {
yrect = yrect + 5; yrect = yrect + 5;
ytext = ytext + 5 + 16; ytext = ytext + 5 + 16;
} }
var r = g.append("rect") var r = g
.attr('class', 'radartip') .append("rect")
.attr("class", "radartip")
.attr("x", x) .attr("x", x)
.attr("y", yrect); .attr("y", yrect);
var txt = g.append("text").text("Note: " + d.note + "/20, moyenne promo: " + d.moy + "/20") var txt = g
.attr('class', 'radartip') .append("text")
.text("Note: " + d.note + "/20, moyenne promo: " + d.moy + "/20")
.attr("class", "radartip")
.attr("x", x + 5) .attr("x", x + 5)
.attr("y", ytext); .attr("y", ytext);
r.attr("width", rwidth).attr("height", 20); r.attr("width", rwidth).attr("height", 20);
}) })
.on("mouseout", function (d) { .on("mouseout", function (d) {
d3.selectAll(".radartip").remove() d3.selectAll(".radartip").remove();
}); });
/* Valeurs des notes */ /* Valeurs des notes */
g.selectAll("notes_labels") g.selectAll("notes_labels")
.data(notes_valid) .data(notes_valid)
.enter().append("text") .enter()
.text(function (d) { return d["note"]; }) .append("text")
.text(function (d) {
return d["note"];
})
.attr("x", function (d) { .attr("x", function (d) {
return d["x_v"]; return d["x_v"];
}) })
.attr("y", function (d) { .attr("y", function (d) {
if (d["y_v"] > CY) if (d["y_v"] > CY) return d["y_v"] + 16;
return d["y_v"] + 16; else return d["y_v"] - 8;
else
return d["y_v"] - 8;
}) })
.attr("class", "note_label"); .attr("class", "note_label");
/* Petits points sur les moyennes */ /* Petits points sur les moyennes */
g.selectAll("circle2") g.selectAll("circle2")
.data(notes_valid) .data(notes_valid)
.enter().append("circle") .enter()
.attr("cx", function (d) { return d["x_moy"]; }) .append("circle")
.attr("cy", function (d) { return d["y_moy"]; }) .attr("cx", function (d) {
.attr("r", function (x, i) { return 2; }) return d["x_moy"];
})
.attr("cy", function (d) {
return d["y_moy"];
})
.attr("r", function (x, i) {
return 2;
})
.style("stroke-width", 0) .style("stroke-width", 0)
.style("stroke", "black") .style("stroke", "black")
.style("fill", "rgb(20,90,50)"); .style("fill", "rgb(20,90,50)");
@ -218,64 +263,74 @@ function draw_radar(notes) {
/* Valeurs sur axe */ /* Valeurs sur axe */
g.selectAll("textaxis") g.selectAll("textaxis")
.data(R_AXIS_TICS) .data(R_AXIS_TICS)
.enter().append("text") .enter()
.append("text")
.text(String) .text(String)
.attr("x", CX - 10) .attr("x", CX - 10)
.attr("y", function (x, i) { return CY - x * RR / 20 + 6; }) .attr("y", function (x, i) {
return CY - (x * RR) / 20 + 6;
})
.attr("class", "textaxis"); .attr("class", "textaxis");
/* Noms des modules */ /* Noms des modules */
g.selectAll("text_modules") g.selectAll("text_modules")
.data(notes) .data(notes)
.enter().append("text") .enter()
.text(function (d) { return d['code']; }) .append("text")
.attr("x", function (d) { return d['x_label']; }) .text(function (d) {
.attr("y", function (d) { return d['y_label']; }) return d["code"];
})
.attr("x", function (d) {
return d["x_label"];
})
.attr("y", function (d) {
return d["y_label"];
})
.attr("dx", 0) .attr("dx", 0)
.attr("dy", 0) .attr("dy", 0)
.on("mouseover", function (d) { .on("mouseover", function (d) {
var x = d["x_label"]; var x = d["x_label"];
var yrect = d["y_label"]; var yrect = d["y_label"];
var ytext = d["y_label"]; var ytext = d["y_label"];
var titre = d['titre'].replace("&apos;", "'").substring(0, 64); var titre = d["titre"].replace("&apos;", "'").substring(0, 64);
var rwidth = titre.length * 9; // rough estimate of string width in pixels var rwidth = titre.length * 9; // rough estimate of string width in pixels
if ((x - CX) < 0) { if (x - CX < 0) {
x = x + 5; x = x + 5;
if (x + rwidth + 12 > WIDTH) { if (x + rwidth + 12 > WIDTH) {
x = WIDTH - rwidth - 12; x = WIDTH - rwidth - 12;
} }
} } else {
else { if (x - CX > 0) {
if ((x - CX) > 0) {
x = x - rwidth - 5; x = x - rwidth - 5;
if (x < 12) { if (x < 12) {
x = 12; x = 12;
} }
} } else {
else {
x = CX - rwidth / 2; x = CX - rwidth / 2;
} }
} }
if ((yrect - CY) > 0) { if (yrect - CY > 0) {
yrect = yrect - 5 - 20; yrect = yrect - 5 - 20;
ytext = ytext - 5 - 20 + 16; ytext = ytext - 5 - 20 + 16;
} } else {
else {
yrect = yrect + 5; yrect = yrect + 5;
ytext = ytext + 5 + 16; ytext = ytext + 5 + 16;
} }
var r = g.append("rect") var r = g
.attr('class', 'radartip') .append("rect")
.attr("class", "radartip")
.attr("x", x) .attr("x", x)
.attr("y", yrect) .attr("y", yrect)
.attr("height", 20) .attr("height", 20)
.attr("width", rwidth); .attr("width", rwidth);
var txt = g.append("text").text(titre) var txt = g
.attr('class', 'radartip') .append("text")
.text(titre)
.attr("class", "radartip")
.attr("x", x + 5) .attr("x", x + 5)
.attr("y", ytext); .attr("y", ytext);
}) })
.on("mouseout", function (d) { .on("mouseout", function (d) {
d3.selectAll(".radartip").remove() d3.selectAll(".radartip").remove();
}); });
} }