Commit b15e4db521e9b53ce00bb1db04b4142cd9fba600
1 parent
63ac6a6e
Exists in
master
and in
4 other branches
Tooltip on mouseover on bar
Showing
1 changed file
with
111 additions
and
111 deletions
Show diff stats
app/main/templates/agent.html
1 | 1 | {% extends "base_page.html" %} |
2 | 2 | |
3 | 3 | {% block more_heads %} |
4 | - <style type="text/css"> | |
5 | - #charge_chart { | |
6 | - background-color: #fAfAfA; | |
7 | - border: 1pt solid black; | |
8 | - display: inline-block; | |
9 | - } | |
10 | - rect.bar:hover { | |
11 | - fill: dimgrey; | |
12 | - } | |
13 | - rect.bar { | |
14 | - fill: rgb(127,127,159); | |
15 | - } | |
16 | - </style> | |
4 | +<style type="text/css"> | |
5 | + #charge_div { | |
6 | + background-color: #fAfAfA; | |
7 | + border: 1pt solid black; | |
8 | + display: inline-block; | |
9 | + } | |
10 | + | |
11 | + rect.bar:hover { | |
12 | + fill: dimgrey; | |
13 | + } | |
14 | + | |
15 | + rect.bar { | |
16 | + fill: rgb(127, 127, 159); | |
17 | + } | |
18 | + | |
19 | + .tooltip { | |
20 | + position: absolute; | |
21 | + opacity: 0.8; | |
22 | + z-index: 1000; | |
23 | + text-align: left; | |
24 | + border-radius: 4px; | |
25 | + -moz-border-radius: 4px; | |
26 | + -webkit-border-radius: 4px; | |
27 | + padding: 8px; | |
28 | + color: #fff; | |
29 | + background-color: #000; | |
30 | + font: 12px sans-serif; | |
31 | + max-width: 300px; | |
32 | + } | |
33 | + | |
34 | +</style> | |
17 | 35 | {% endblock %} |
18 | 36 | |
19 | 37 | {% block content %} |
20 | - <div id="charge_div"></div> | |
21 | - <svg height="500" id="charge_chart" width="900"></svg> | |
38 | +<div id="charge_div"></div> | |
22 | 39 | {% endblock %} |
23 | 40 | |
24 | 41 | |
25 | 42 | {% block more_scripts %} |
26 | - {% include 'd3js-includes.html' %} | |
27 | -<!-- <script>--> | |
28 | - | |
29 | -<!-- // Update…--> | |
30 | -<!-- d3.json("{{url_for('main.charge_agent', agent_id=agent.id)}}").then(data => {--> | |
31 | -<!-- var charge = d3.select("#charge_div")--> | |
32 | -<!-- .selectAll("p")--> | |
33 | -<!-- .data(data)--> | |
34 | -<!-- .text(function (d) {--> | |
35 | -<!-- return d;--> | |
36 | -<!-- });--> | |
37 | -<!-- // Enter…--> | |
38 | -<!-- charge.enter().append("p")--> | |
39 | -<!-- .text(function (d) {--> | |
40 | -<!-- return d.periode + ", " + d.charge;--> | |
41 | -<!-- });--> | |
42 | -<!-- })--> | |
43 | -<!-- </script>--> | |
44 | - <script> | |
45 | - | |
46 | - const margin = {top: 40, right: 40, bottom: 90, left: 120}, | |
47 | - width = 900 - margin.left - margin.right, | |
48 | - height = 500 - margin.top - margin.bottom; | |
49 | - | |
50 | - const x = d3.scaleBand() | |
51 | - .range([0, width]) | |
52 | - .padding(0.1); | |
53 | - | |
54 | - const y = d3.scaleLinear() | |
55 | - .range([height, 0]); | |
56 | - const svg = d3.select("#charge_chart").append("svg") | |
57 | - .attr("id", "svg") | |
58 | - .attr("width", width + margin.left + margin.right) | |
59 | - .attr("height", height + margin.top + margin.bottom) | |
60 | - .append("g") | |
61 | - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
62 | - | |
63 | - const div = d3.select("body").append("div") | |
64 | - .attr("class", "tooltip") | |
65 | - .style("opacity", 0); | |
66 | - | |
67 | - // On demande à D3JS de charger notre fichier | |
68 | - d3.json("{{url_for('main.charge_agent', agent_id=agent.id)}}").then(data => { | |
69 | - // Conversion des caractères en nombres | |
70 | - console.log(data) | |
71 | - data.forEach(d => d.charge = +d.charge); | |
72 | - | |
73 | - // Mise en relation du scale avec les données de notre fichier | |
74 | - // Pour l'axe X, c'est la liste des pays | |
75 | - // Pour l'axe Y, c'est le max des charge | |
76 | - x.domain(data.map(d => d.periode)); | |
77 | - y.domain([0, d3.max(data, d => d.charge)]); | |
78 | - | |
79 | - // Ajout de l'axe X au SVG | |
80 | - // Déplacement de l'axe horizontal et du futur texte (via la fonction translate) au bas du SVG | |
81 | - // Selection des noeuds text, positionnement puis rotation | |
82 | - svg.append("g") | |
83 | - .attr("transform", "translate(0," + height + ")") | |
84 | - .call(d3.axisBottom(x).tickSize(0)) | |
85 | - .selectAll("text") | |
86 | - .style("text-anchor", "end") | |
87 | - .attr("dx", "-.8em") | |
88 | - .attr("dy", ".15em") | |
89 | - .attr("transform", "rotate(-65)"); | |
90 | - | |
91 | - // Ajout de l'axe Y au SVG avec 6 éléments de légende en utilisant la fonction ticks (sinon D3JS en place autant qu'il peut). | |
92 | - svg.append("g") | |
93 | - .call(d3.axisLeft(y).ticks(6)); | |
94 | - | |
95 | - // Ajout des bars en utilisant les données de notre fichier data.tsv | |
96 | - // La largeur de la barre est déterminée par la fonction x | |
97 | - // La hauteur par la fonction y en tenant compte de la charge | |
98 | - // La gestion des events de la souris pour le popup | |
99 | - svg.selectAll(".bar") | |
100 | - .data(data) | |
101 | - .enter().append("rect") | |
102 | - .attr("class", "bar") | |
103 | - .attr("x", d => x(d.periode)) | |
104 | - .attr("width", x.bandwidth()) | |
105 | - .attr("y", d => y(d.charge)) | |
106 | - .attr("height", d => height - y(d.charge)) | |
107 | - // .on("mouseover", function (d) { | |
108 | - // div.transition() | |
109 | - // .duration(200) | |
110 | - // .style("opacity", .9); | |
111 | - // div.html("Population : " + d.charge) | |
112 | - // .style("left", (d3.event.pageX + 10) + "px") | |
113 | - // .style("top", (d3.event.pageY - 50) + "px"); | |
114 | - // }) | |
115 | - // .on("mouseout", function (d) { | |
116 | - // div.transition() | |
117 | - // .duration(500) | |
118 | - // .style("opacity", 0); | |
119 | - // }); | |
120 | - }); | |
121 | - </script> | |
43 | +{% include 'd3js-includes.html' %} | |
44 | +<script> | |
45 | + | |
46 | + const margin = {top: 40, right: 40, bottom: 90, left: 120}, | |
47 | + width = 900 - margin.left - margin.right, | |
48 | + height = 500 - margin.top - margin.bottom; | |
49 | + | |
50 | + const x = d3.scaleBand() | |
51 | + .range([0, width]) | |
52 | + .padding(0.1); | |
53 | + | |
54 | + const y = d3.scaleLinear() | |
55 | + .range([height, 0]); | |
56 | + | |
57 | + const svg = d3.select("#charge_div").append("svg") | |
58 | + .attr("id", "svg") | |
59 | + .attr("width", width + margin.left + margin.right) | |
60 | + .attr("height", height + margin.top + margin.bottom) | |
61 | + .append("g") | |
62 | + .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
63 | + | |
64 | + const div = d3.select("body").append("div") | |
65 | + .attr("class", "tooltip") | |
66 | + .style("opacity", 0); | |
67 | + | |
68 | + // On demande à D3JS de charger notre fichier | |
69 | + d3.json("{{url_for('main.charge_agent', agent_id=agent.id)}}").then(data => { | |
70 | + // Conversion des caractères en nombres | |
71 | + data.forEach(d => d.charge = +d.charge); | |
72 | + | |
73 | + // Mise en relation du scale avec les données de notre fichier | |
74 | + // Pour l'axe X, c'est la liste des pays | |
75 | + // Pour l'axe Y, c'est le max des charge | |
76 | + x.domain(data.map(d => d.periode)); | |
77 | + y.domain([0, d3.max(data, d => d.charge)]); | |
78 | + | |
79 | + // Ajout de l'axe X au SVG | |
80 | + // Déplacement de l'axe horizontal et du futur texte (via la fonction translate) au bas du SVG | |
81 | + // Selection des noeuds text, positionnement puis rotation | |
82 | + svg.append("g") | |
83 | + .attr("transform", "translate(0," + height + ")") | |
84 | + .call(d3.axisBottom(x).tickSize(10)) | |
85 | + .selectAll("text") | |
86 | + .style("text-anchor", "end") | |
87 | + .attr("dx", "-.8em") | |
88 | + .attr("dy", ".15em") | |
89 | + .attr("transform", "rotate(-65)"); | |
90 | + | |
91 | + // Ajout de l'axe Y au SVG avec 6 éléments de légende en utilisant la fonction ticks (sinon D3JS en place autant qu'il peut). | |
92 | + svg.append("g") | |
93 | + .call(d3.axisLeft(y).ticks(6)); | |
94 | + | |
95 | + // Ajout des bars en utilisant les données de notre fichier data.tsv | |
96 | + // La largeur de la barre est déterminée par la fonction x | |
97 | + // La hauteur par la fonction y en tenant compte de la charge | |
98 | + // La gestion des events de la souris pour le popup | |
99 | + svg.selectAll(".bar") | |
100 | + .data(data) | |
101 | + .enter().append("rect") | |
102 | + .attr("class", "bar") | |
103 | + .attr("x", d => x(d.periode)) | |
104 | + .attr("width", x.bandwidth()) | |
105 | + .attr("y", d => y(d.charge)) | |
106 | + .attr("height", d => height - y(d.charge)) | |
107 | + .on("mouseover", function (e, d) { | |
108 | + div.transition() | |
109 | + .duration(200) | |
110 | + .style("opacity", .9); | |
111 | + div.html("Charge: " + d.charge) | |
112 | + .style("left", (e.x + 10) + "px") | |
113 | + .style("top", (e.y - 50) + "px"); | |
114 | + }) | |
115 | + .on("mouseout", function (d) { | |
116 | + div.transition() | |
117 | + .duration(500) | |
118 | + .style("opacity", 0); | |
119 | + }); | |
120 | + }); | |
121 | +</script> | |
122 | 122 | {% endblock %} | ... | ... |