From f8f8af0e460abe404127564ad79036649dd3fab4 Mon Sep 17 00:00:00 2001 From: Nekori Date: Thu, 29 Apr 2021 20:16:12 +0200 Subject: [PATCH] Graphe ressources --- html/export_yaml_to_html.py | 10 +-- html/graphTemplate.html | 29 +++++--- html/graphTemplate.js | 139 ++++++++++++++++++++++++++---------- 3 files changed, 123 insertions(+), 55 deletions(-) diff --git a/html/export_yaml_to_html.py b/html/export_yaml_to_html.py index 0be95a9..104081e 100644 --- a/html/export_yaml_to_html.py +++ b/html/export_yaml_to_html.py @@ -248,13 +248,13 @@ for indexSem, sem in enumerate(ressources): defineSearchTerm(data, url, documents) template.stream(datas).dump(REPERTOIRE_HTML + "/" + url) - relations["nodes"].append({"id": data["code"]}) + relations["nodes"].append({"id": data["code"], "type": "Ressource"}) for sae in data["sae"]: - if not any(sae in node["id"] for node in relations["nodes"]): relations["nodes"].append({"id": sae}) + if not any(sae in node["id"] for node in relations["nodes"]): relations["nodes"].append({"id": sae, "type": "SAE"}) relations["links"].append({"source": data["code"], "target": sae, "type": "RessourceToSAE"}) for rt in data["acs"]: for ac in data["acs"][rt]: - if not any(ac in node["id"] for node in relations["nodes"]): relations["nodes"].append({"id": ac}) + if not any(ac in node["id"] for node in relations["nodes"]): relations["nodes"].append({"id": ac, "type": "AC"}) relations["links"].append({"source": data["code"], "target": ac, "type": "RessourceToAC"}) #Créer un fichier contenant la liste des ressources du semestre @@ -286,10 +286,10 @@ for indexSem, sem in enumerate(ressources): SAE_mobilise_AC[ac].append(sae.getInfo()) if not any(data["code"] in node["id"] for node in relations["nodes"]): - relations["nodes"].append({"id": data["code"]}) + relations["nodes"].append({"id": data["code"], "type": "SAE"}) for rt in data["acs"]: for ac in data["acs"][rt]: - if not any(ac in node["id"] for node in relations["nodes"]): relations["nodes"].append({"id": ac}) + if not any(ac in node["id"] for node in relations["nodes"]): relations["nodes"].append({"id": ac, "type": "AC"}) relations["links"].append({"source": data["code"], "target": ac, "type": "SAEToAC"}) for sae in exemples[sem]: diff --git a/html/graphTemplate.html b/html/graphTemplate.html index 3b2a3eb..5e32389 100644 --- a/html/graphTemplate.html +++ b/html/graphTemplate.html @@ -4,16 +4,23 @@ {% endblock %} {% block content %} - - + + {% endblock %} \ No newline at end of file diff --git a/html/graphTemplate.js b/html/graphTemplate.js index e341c62..51a3a61 100644 --- a/html/graphTemplate.js +++ b/html/graphTemplate.js @@ -1,60 +1,120 @@ drag = simulation => { - function dragstarted(event) { - if (!event.active) simulation.alphaTarget(0.3).restart(); - event.subject.fx = event.subject.x; - event.subject.fy = event.subject.y; + function dragstarted(d) { + if (!d3.event.active) simulation.alphaTarget(0.3).restart(); + d.fx = d.x; + d.fy = d.y; } - function dragged(event) { - event.subject.fx = event.x; - event.subject.fy = event.y; + function dragged(d) { + d.fx = d3.event.x; + d.fy = d3.event.y; } - function dragended(event) { - if (!event.active) simulation.alphaTarget(0); - event.subject.fx = null; - event.subject.fy = null; + function dragended(d) { + if (!d3.event.active) simulation.alphaTarget(0); + d.fx = null; + d.fy = null; } return d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended); - } +} -var svg = d3.select("svg"), - width = +svg.attr("width"), - height = +svg.attr("height"); +const graph = {{data}} +var nodes = graph["nodes"] +var links = graph["links"] -var simulation = d3.forceSimulation() - .force("charge", d3.forceManyBody().strength(-200)) - .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(40)) - .force("x", d3.forceX(width / 2)) - .force("y", d3.forceY(height / 2)) - .on("tick", ticked); +$("document").ready(function() { -var link = svg.selectAll(".link"), - node = svg.selectAll(".node"); + $(".categorie").click(function() { + nodes = [] + links = [] + if($("#Ressources").prop("checked")) {graph["nodes"].map(node => {if(node.type == "Ressource"){nodes.push(node);}})} + if($("#SAEs").prop("checked")) { + if (nodes.length != 0) {graph["links"].map(link => {if(link.type == "RessourceToSAE"){links.push(link);}})} + nodes.concat(graph["nodes"].map(node => {if(node.type == "SAE"){nodes.push(node);}})); + } + if($("#ACs").prop("checked")) { + if($("#Ressources").prop("checked")) {graph["links"].map(link => {if(link.type == "RessourceToAC"){links.push(link);}})} + if($("#SAEs").prop("checked")) {graph["links"].map(link => {if(link.type == "SAEToAC"){links.push(link);}})} + nodes.concat(graph["nodes"].map(node => {if(node.type == "AC"){nodes.push(node);}})); + } + + redraw() -graph = {{data}} + simulation.nodes(nodes); + simulation.force("links", d3.forceLink(links).id(node => node.id)); + simulation.alpha(1).restart(); + }); +function redraw() { + + $(".nodes").children().remove(); + + NODE.data(nodes) + .remove() + .enter().append("rect") + .attr("width", 40) + .attr("height", 20) + .attr("x", -20) + .attr("y", -10) + .attr("rx", 5) + .attr("ry", 5) + .attr("fill", function(d) { return color(d.type); }); + +} +}); + +const nodetypes = Array.from(new Set(nodes.map(node => node.type))) +const linktypes = Array.from(new Set(links.map(link => link.type))) + +const color = d3.scaleOrdinal(nodetypes.concat(linktypes),d3.schemeCategory10) + +var height = 800, width = 800; + +var svg = d3.select("svg") + .attr("viewBox", [0, 0, width, height]) + +var simulation = d3.forceSimulation(nodes) + .force("charge", d3.forceManyBody().strength(-400)) + .force("center", d3.forceCenter(width / 2, height / 2)) + .force("link", d3.forceLink(links).id(node => node.id)); + +var link = svg.append("g") + .attr("stroke-width", 1.5) + .attr("class","links") + .selectAll("line") + .data(links) + .join("line") + .attr("stroke", d => color(d.type)); -simulation.nodes(graph.nodes); -simulation.force("link").links(graph.links); +var NODE = svg.append("g") + .attr("stroke-width", 1) + .attr("stroke", "black") + .attr("class","nodes") + .selectAll("g") + .data(nodes) + .join("g") + .call(drag(simulation)); -link = link -.data(graph.links) -.enter().append("line") - .attr("class", "link"); +NODE.append("rect") + .attr("width", 40) + .attr("height", 20) + .attr("x", -20) + .attr("y", -10) + .attr("rx", 5) + .attr("ry", 5) + .attr("fill", function(d) { return color(d.type); }); -node = node -.data(graph.nodes) -.enter().append("circle") - .attr("class", "node") - .attr("r", 6) - .style("fill", function(d) { return d.id; }); +NODE.append("text") + .text(d => d.id) + .attr("dx", 15) + .attr("dy", 25) +simulation.on("tick", ticked); function ticked() { link.attr("x1", function(d) { return d.source.x; }) @@ -62,6 +122,7 @@ function ticked() { .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); - node.attr("cx", function(d) { return d.x; }) - .attr("cy", function(d) { return d.y; }); -} \ No newline at end of file + NODE + .attr("transform", d => `translate(${d.x},${d.y})`); +} +