Commit 8daea46ba517f150ab42aba006bd7d12c281f2c8

Authored by Antoine Goutenoir
1 parent 566355a9
Exists in master

fix: interactive cursor

flaskr/static/css/common/main.css
@@ -95,6 +95,10 @@ span.required-asterisk { @@ -95,6 +95,10 @@ span.required-asterisk {
95 top: 2px; 95 top: 2px;
96 } 96 }
97 97
  98 +.no-pointer-events {
  99 + pointer-events: none;
  100 +}
  101 +
98 102
99 /** TWEAKS *******************************************************************/ 103 /** TWEAKS *******************************************************************/
100 104
flaskr/static/js/plots/emissions-per-distance.js
1 -  
2 -function draw_emissions_per_distance(divId, csvUrl) {  
3 - // let divId = "emissions_per_distance_histogram";  
4 - 1 +function draw_emissions_per_distance(divSelector, csvUrl) {
5 // set the dimensions and margins of the graph 2 // set the dimensions and margins of the graph
6 - let margin = {top: 30, right: 62, bottom: 62, left: 72}, 3 + let margin = {top: 42, right: 88, bottom: 62, left: 98},
7 width = 960 - margin.left - margin.right, 4 width = 960 - margin.left - margin.right,
8 height = 540 - margin.top - margin.bottom; 5 height = 540 - margin.top - margin.bottom;
9 6
  7 + const sliceThickness = 500.0;
  8 +
  9 +
10 function getTicks(maxValue, interval, startValue = 0) { 10 function getTicks(maxValue, interval, startValue = 0) {
11 let range = []; 11 let range = [];
12 for (let i = startValue; i <= maxValue; i += interval) { 12 for (let i = startValue; i <= maxValue; i += interval) {
@@ -29,76 +29,88 @@ function draw_emissions_per_distance(divId, csvUrl) { @@ -29,76 +29,88 @@ function draw_emissions_per_distance(divId, csvUrl) {
29 return getTicks(maxemissionsPercent, 2); 29 return getTicks(maxemissionsPercent, 2);
30 } 30 }
31 31
32 - function getAttendeeOnRight(sliceId, attendeeNumberPerGroup) {  
33 - let attendeeSum = 0; 32 + function getAttendeesAmountOnRight(sliceId, attendeeNumberPerGroup) {
  33 + let attendeesAmount = 0;
34 let sliceInt = Math.floor(sliceId); 34 let sliceInt = Math.floor(sliceId);
35 let sliceFloat = sliceId - sliceInt; 35 let sliceFloat = sliceId - sliceInt;
36 for (let i = sliceInt; i < attendeeNumberPerGroup.length; i++) { 36 for (let i = sliceInt; i < attendeeNumberPerGroup.length; i++) {
37 - attendeeSum += attendeeNumberPerGroup[i] * (1 - sliceFloat); 37 + attendeesAmount += attendeeNumberPerGroup[i] * (1 - sliceFloat);
38 sliceFloat = 0; 38 sliceFloat = 0;
39 } 39 }
40 - return attendeeSum; 40 + return attendeesAmount;
41 41
42 } 42 }
43 43
44 - function setupCursorBoxes(event, attendeeSum, attendeeNumberPerGroup, xScale, box, vertical, rightArea) { 44 + function setupCursorBoxes(event, attendeeSum, attendeeNumberPerGroup, xScale, tooltip, vertical, rightArea) {
45 const x = d3.pointer(event)[0]; 45 const x = d3.pointer(event)[0];
46 const y = d3.pointer(event)[1]; 46 const y = d3.pointer(event)[1];
47 // var y = d3.event.pageY - document.getElementById(<id-of-your-svg>).getBoundingClientRect().y + 10 47 // var y = d3.event.pageY - document.getElementById(<id-of-your-svg>).getBoundingClientRect().y + 10
48 // x += 5; 48 // x += 5;
  49 +
  50 + // console.log("Mouse move", x, y);
  51 +
49 vertical.style("left", x + "px"); 52 vertical.style("left", x + "px");
50 rightArea.style("left", x + "px"); 53 rightArea.style("left", x + "px");
51 - box.style("left", (x + 10) + "px");  
52 - box.style("top", (y - 20) + "px");  
53 - let sliceId = xScale.invert(x - d3.selectAll("g.yl.axis")._groups[0][0].getBoundingClientRect().right) / 500; 54 + tooltip.style("left", (x + 10) + "px");
  55 + tooltip.style("top", (y - 20) + "px");
  56 +
  57 + // let sliceId = xScale.invert(x - d3.selectAll("g.yl.axis")._groups[0][0].getBoundingClientRect().right) / 500;
  58 +
  59 + let sliceId = xScale.invert(x - margin.left) / sliceThickness;
  60 +
  61 + console.log(`Slice ${sliceId} under the mouse.`);
  62 +
54 // let sliceId = xScale.invert(x * 1.025 - d3.selectAll("g.yl.axis")._groups[0][0].getBoundingClientRect().x- margin.left)/500 +1; 63 // let sliceId = xScale.invert(x * 1.025 - d3.selectAll("g.yl.axis")._groups[0][0].getBoundingClientRect().x- margin.left)/500 +1;
55 - let attendeePercent = (getAttendeeOnRight(sliceId, attendeeNumberPerGroup) / attendeeSum * 100.0).toFixed(1);  
56 - if (x > d3.selectAll("g.yr.axis")._groups[0][0].getBoundingClientRect().x ||  
57 - x < d3.selectAll("g.yl.axis")._groups[0][0].getBoundingClientRect().right) { 64 + let attendeePercent = (getAttendeesAmountOnRight(sliceId, attendeeNumberPerGroup) / attendeeSum * 100.0).toFixed(1);
  65 + if (
  66 + x < margin.left
  67 + ||
  68 + x > width + margin.left
  69 + ) {
58 rightArea.style("width", 0); 70 rightArea.style("width", 0);
59 vertical.style("width", 0); 71 vertical.style("width", 0);
60 - box.style("display", "none"); 72 + tooltip.style("display", "none");
61 } 73 }
62 else { 74 else {
63 rightArea.style("width", d3.selectAll("g.yr.axis")._groups[0][0].getBoundingClientRect().x - x); 75 rightArea.style("width", d3.selectAll("g.yr.axis")._groups[0][0].getBoundingClientRect().x - x);
64 vertical.style("width", "2px"); 76 vertical.style("width", "2px");
65 - box.style("display", "inherit"); 77 + tooltip.style("display", "inherit");
66 } 78 }
67 - box.text(attendeePercent + " % of attendees");  
68 - box.text(attendeePercent + " % of attendees"); 79 + tooltip.text(attendeePercent + " % of attendees");
69 // console.log(d3.selectAll("g.x.axis")._groups[0][0]); 80 // console.log(d3.selectAll("g.x.axis")._groups[0][0]);
70 // console.log(d3.selectAll("g.x.axis")._groups[0][0].getBoundingClientRect().x); 81 // console.log(d3.selectAll("g.x.axis")._groups[0][0].getBoundingClientRect().x);
71 } 82 }
72 83
73 function addVerticalLineAndListenCursor(xScale, attendeeNumberPerGroup, attendeeSum) { 84 function addVerticalLineAndListenCursor(xScale, attendeeNumberPerGroup, attendeeSum) {
74 - let vertical = d3.select("#" + divId) 85 + let verticalRuler = d3.select(divSelector)
75 .append("div") 86 .append("div")
76 - .attr("class", "remove") 87 + // .attr("class", "remove")
77 .style("position", "absolute") 88 .style("position", "absolute")
78 .style("z-index", "19") 89 .style("z-index", "19")
79 .style("width", "2px") 90 .style("width", "2px")
80 .style("height", (height) + "px") 91 .style("height", (height) + "px")
81 .style("top", (10 + margin.top) + "px") 92 .style("top", (10 + margin.top) + "px")
82 .style("bottom", "30px") 93 .style("bottom", "30px")
83 - .style("left", "0px") 94 + .style("left", "-10px")
84 .style("background", "#000"); 95 .style("background", "#000");
85 96
86 - let rightArea = d3.select("#" + divId) 97 + let rightArea = d3.select(divSelector)
87 .append("div") 98 .append("div")
88 - .attr("class", "remove") 99 + // .attr("class", "remove")
89 .style("position", "absolute") 100 .style("position", "absolute")
90 .style("z-index", "-50") 101 .style("z-index", "-50")
91 - .style("width", "2000px") 102 + .style("width", "0px")
  103 + // .style("width", "2000px")
92 .style("height", (height) + "px") 104 .style("height", (height) + "px")
93 .style("top", (10 + margin.top) + "px") 105 .style("top", (10 + margin.top) + "px")
94 .style("bottom", "30px") 106 .style("bottom", "30px")
95 .style("left", "0px") 107 .style("left", "0px")
96 .style("background", "rgba(60, 200, 60, 0.3)"); 108 .style("background", "rgba(60, 200, 60, 0.3)");
97 109
98 -  
99 - let box = d3.select("#" + divId) 110 + let tooltip = d3.select(divSelector)
100 .append("div") 111 .append("div")
101 - .attr("class", "remove") 112 + .attr("class", "no-pointer-events")
  113 + .style("display", "none")
102 .style("position", "absolute") 114 .style("position", "absolute")
103 .style("z-index", "20") 115 .style("z-index", "20")
104 .style("width", "150px") 116 .style("width", "150px")
@@ -109,12 +121,12 @@ function draw_emissions_per_distance(divId, csvUrl) { @@ -109,12 +121,12 @@ function draw_emissions_per_distance(divId, csvUrl) {
109 .style("border", "1px solid grey") 121 .style("border", "1px solid grey")
110 .style("background", "rgba(255, 255, 255, 0.7)"); 122 .style("background", "rgba(255, 255, 255, 0.7)");
111 123
112 - d3.select("#" + divId) 124 + d3.select(divSelector + " svg")
113 .on("mousemove", function (event) { 125 .on("mousemove", function (event) {
114 - setupCursorBoxes(event, attendeeSum, attendeeNumberPerGroup, xScale, box, vertical, rightArea); 126 + setupCursorBoxes(event, attendeeSum, attendeeNumberPerGroup, xScale, tooltip, verticalRuler, rightArea);
115 }) 127 })
116 .on("mouseover", function (event) { 128 .on("mouseover", function (event) {
117 - setupCursorBoxes(event, attendeeSum, attendeeNumberPerGroup, xScale, box, vertical, rightArea); 129 + setupCursorBoxes(event, attendeeSum, attendeeNumberPerGroup, xScale, tooltip, verticalRuler, rightArea);
118 }); 130 });
119 } 131 }
120 132
@@ -122,9 +134,9 @@ function draw_emissions_per_distance(divId, csvUrl) { @@ -122,9 +134,9 @@ function draw_emissions_per_distance(divId, csvUrl) {
122 let maxemissions = 0; 134 let maxemissions = 0;
123 let maxemissionsPercent = 0; 135 let maxemissionsPercent = 0;
124 let maxDistance = 0; 136 let maxDistance = 0;
125 - let svg = d3.select("#" + divId) 137 + let svg = d3.select(divSelector)
126 .append("svg") 138 .append("svg")
127 - .attr("id", divId + "-svg") 139 + // .attr("id", divSelector + "-svg")
128 .attr("width", width + margin.left + margin.right) 140 .attr("width", width + margin.left + margin.right)
129 .attr("height", height + margin.top + margin.bottom) 141 .attr("height", height + margin.top + margin.bottom)
130 .append("g") 142 .append("g")
@@ -177,7 +189,7 @@ function draw_emissions_per_distance(divId, csvUrl) { @@ -177,7 +189,7 @@ function draw_emissions_per_distance(divId, csvUrl) {
177 maxDistance += 2000; 189 maxDistance += 2000;
178 // console.log(maxDistance); 190 // console.log(maxDistance);
179 191
180 - //Title 192 + // Title
181 svg.append("text") 193 svg.append("text")
182 .attr("transform", 194 .attr("transform",
183 "translate(" + (70 + margin.left) + ", -12)") 195 "translate(" + (70 + margin.left) + ", -12)")
@@ -247,7 +259,7 @@ function draw_emissions_per_distance(divId, csvUrl) { @@ -247,7 +259,7 @@ function draw_emissions_per_distance(divId, csvUrl) {
247 .style("text-anchor", "middle") 259 .style("text-anchor", "middle")
248 .text("Emission (tCO2e)"); 260 .text("Emission (tCO2e)");
249 // set the parameters for the histogram 261 // set the parameters for the histogram
250 - var histogram = d3.histogram() 262 + const histogram = d3.histogram()
251 .domain(x.domain()) // then the domain of the graphic 263 .domain(x.domain()) // then the domain of the graphic
252 .thresholds(x.ticks(Math.floor(maxDistance / 500))); // then the numbers of bins 264 .thresholds(x.ticks(Math.floor(maxDistance / 500))); // then the numbers of bins
253 265
flaskr/templates/estimation.html
@@ -277,7 +277,7 @@ var plots_config = { @@ -277,7 +277,7 @@ var plots_config = {
277 /** PLOTS **/ 277 /** PLOTS **/
278 278
279 draw_emissions_per_distance( 279 draw_emissions_per_distance(
280 - "emissions_per_distance_histogram", 280 + "#emissions_per_distance_histogram",
281 "/estimation/{{ estimation.public_id }}.csv" 281 "/estimation/{{ estimation.public_id }}.csv"
282 ); 282 );
283 283