Commit 701dbf83625d61e45d9feececd519dfd427121d5

Authored by Antoine Goutenoir
1 parent e86f2462
Exists in master

feat: integrate the emissions histogram plot

flaskr/static/js/plots/emissions-per-distance.js
1 -function draw_emissions_per_distance(divSelector, csvUrl) { 1 +function draw_emissions_per_distance(containerSelector, csvUrl) {
2 // set the dimensions and margins of the graph 2 // set the dimensions and margins of the graph
3 let margin = {top: 48, right: 88, bottom: 68, left: 98}, 3 let margin = {top: 48, right: 88, bottom: 68, left: 98},
4 width = 960 - margin.left - margin.right, 4 width = 960 - margin.left - margin.right,
@@ -75,13 +75,14 @@ function draw_emissions_per_distance(divSelector, csvUrl) { @@ -75,13 +75,14 @@ function draw_emissions_per_distance(divSelector, csvUrl) {
75 vertical.style("display", "inherit"); 75 vertical.style("display", "inherit");
76 tooltip.style("display", "inherit"); 76 tooltip.style("display", "inherit");
77 } 77 }
78 - tooltip.text(attendeePercent + " % of attendees"); 78 +
  79 + tooltip.text((((attendeePercent<10)?'0':'') + attendeePercent) + "% of attendees");
79 } 80 }
80 81
81 function addVerticalLineAndListenCursor(xScale, attendeeNumberPerGroup, attendeeSum) { 82 function addVerticalLineAndListenCursor(xScale, attendeeNumberPerGroup, attendeeSum) {
82 - let verticalRuler = d3.select(divSelector) 83 + let verticalRuler = d3.select(containerSelector)
83 .append("div") 84 .append("div")
84 - // .attr("class", "remove") 85 + .attr("class", "no-pointer-events")
85 .style("display", "none") 86 .style("display", "none")
86 .style("position", "absolute") 87 .style("position", "absolute")
87 .style("z-index", "19") 88 .style("z-index", "19")
@@ -92,9 +93,9 @@ function draw_emissions_per_distance(divSelector, csvUrl) { @@ -92,9 +93,9 @@ function draw_emissions_per_distance(divSelector, csvUrl) {
92 .style("left", "-10px") 93 .style("left", "-10px")
93 .style("background", "#000"); 94 .style("background", "#000");
94 95
95 - let rightArea = d3.select(divSelector) 96 + let rightArea = d3.select(containerSelector)
96 .append("div") 97 .append("div")
97 - // .attr("class", "remove") 98 + .attr("class", "no-pointer-events")
98 .style("display", "none") 99 .style("display", "none")
99 .style("position", "absolute") 100 .style("position", "absolute")
100 .style("z-index", "-50") 101 .style("z-index", "-50")
@@ -105,13 +106,13 @@ function draw_emissions_per_distance(divSelector, csvUrl) { @@ -105,13 +106,13 @@ function draw_emissions_per_distance(divSelector, csvUrl) {
105 .style("left", "0px") 106 .style("left", "0px")
106 .style("background", "rgba(60, 200, 60, 0.3)"); 107 .style("background", "rgba(60, 200, 60, 0.3)");
107 108
108 - let tooltip = d3.select(divSelector) 109 + let tooltip = d3.select(containerSelector)
109 .append("div") 110 .append("div")
110 .attr("class", "no-pointer-events") 111 .attr("class", "no-pointer-events")
111 .style("display", "none") 112 .style("display", "none")
112 .style("position", "absolute") 113 .style("position", "absolute")
113 .style("z-index", "20") 114 .style("z-index", "20")
114 - .style("width", "155px") 115 + .style("width", "161px")
115 .style("height", "35px") 116 .style("height", "35px")
116 .style("top", "10px") 117 .style("top", "10px")
117 .style("bottom", "30px") 118 .style("bottom", "30px")
@@ -123,7 +124,7 @@ function draw_emissions_per_distance(divSelector, csvUrl) { @@ -123,7 +124,7 @@ function draw_emissions_per_distance(divSelector, csvUrl) {
123 .style("border", "1px solid grey") 124 .style("border", "1px solid grey")
124 .style("background", "rgba(255, 255, 255, 0.7)"); 125 .style("background", "rgba(255, 255, 255, 0.7)");
125 126
126 - d3.select(divSelector + " svg") 127 + d3.select(containerSelector + " svg")
127 .on("mousemove", function (event) { 128 .on("mousemove", function (event) {
128 setupCursorBoxes(event, attendeeSum, attendeeNumberPerGroup, xScale, tooltip, verticalRuler, rightArea); 129 setupCursorBoxes(event, attendeeSum, attendeeNumberPerGroup, xScale, tooltip, verticalRuler, rightArea);
129 }) 130 })
@@ -133,12 +134,14 @@ function draw_emissions_per_distance(divSelector, csvUrl) { @@ -133,12 +134,14 @@ function draw_emissions_per_distance(divSelector, csvUrl) {
133 } 134 }
134 135
135 document.addEventListener("DOMContentLoaded", () => { 136 document.addEventListener("DOMContentLoaded", () => {
  137 + width = Math.max(880, $(containerSelector).parent().width());
  138 + width = width - margin.left - margin.right;
136 let maxemissions = 0; 139 let maxemissions = 0;
137 let maxemissionsPercent = 0; 140 let maxemissionsPercent = 0;
138 let maxDistance = 0; 141 let maxDistance = 0;
139 - let svg = d3.select(divSelector) 142 + let svg = d3.select(containerSelector)
140 .append("svg") 143 .append("svg")
141 - // .attr("id", divSelector + "-svg") 144 + // .attr("id", containerSelector + "-svg")
142 .attr("width", width + margin.left + margin.right) 145 .attr("width", width + margin.left + margin.right)
143 .attr("height", height + margin.top + margin.bottom) 146 .attr("height", height + margin.top + margin.bottom)
144 .append("g") 147 .append("g")
flaskr/static/js/plots/utils.js 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +/** POLYFILLS **/
  2 +Math.log10 = Math.log10 || function(x) { return Math.log(x) * Math.LOG10E; };
  3 +
  4 +/**
  5 + * Useful for axes' domains on plots.
  6 + * @param value
  7 + * @returns {number}
  8 + */
  9 +const ceil_value_to_magnitude = function (value) {
  10 + let sign = 1;
  11 + if (value < 0) {
  12 + value = Math.abs(value);
  13 + sign = -1;
  14 + }
  15 + if (value < 1) {
  16 + return sign;
  17 + }
  18 +
  19 + const low = Math.pow(10, Math.floor(Math.log10(value)));
  20 +
  21 + let cursor = low;
  22 + let noloop = 0;
  23 + while ((cursor < value) && (noloop <= 100)) {
  24 + cursor += 0.1 * low;
  25 + noloop += 1;
  26 + }
  27 +
  28 + return sign * cursor;
  29 +};
flaskr/templates/estimation.html
@@ -103,10 +103,6 @@ @@ -103,10 +103,6 @@
103 {# <div id="cities_footprints_d3viz" class="plot-container"></div>#} 103 {# <div id="cities_footprints_d3viz" class="plot-container"></div>#}
104 <hr> 104 <hr>
105 <div id="cities_footprints_spinner" class="lds-ripple text-center"><div></div><div></div><div></div></div> 105 <div id="cities_footprints_spinner" class="lds-ripple text-center"><div></div><div></div><div></div></div>
106 -  
107 - <div id="emissions_per_distance_histogram" class="plot-container">  
108 - </div>  
109 -  
110 {# This MUST stay empty (because Simg uses svg.getparentnode.innerhtml) #} 106 {# This MUST stay empty (because Simg uses svg.getparentnode.innerhtml) #}
111 <div id="cities_footprints_d3viz_lollipop" class="plot-container"> 107 <div id="cities_footprints_d3viz_lollipop" class="plot-container">
112 </div> 108 </div>
@@ -115,8 +111,21 @@ @@ -115,8 +111,21 @@
115 </div> 111 </div>
116 112
117 <hr> 113 <hr>
  114 +
  115 +{# EMISSIONS PER DISTANCE HISTOGRAM ##########################################}
  116 +{# That plot makes no sense with our many to many data. #}
  117 +{% if not estimation.is_many_to_many() %}
  118 +<div class="row">
  119 + <div id="emissions_per_distance_histogram" class="plot-container"></div>
  120 +</div>
  121 +<hr>
118 {% endif %} 122 {% endif %}
  123 +{#############################################################################}
119 124
  125 +{% endif %}{# not estimation.has_failed() #}
  126 +
  127 +
  128 +{# LIST OF CITIES ############################################################}
120 <div class="row"> 129 <div class="row">
121 130
122 {% if not estimation.has_failed() %} 131 {% if not estimation.has_failed() %}
@@ -216,7 +225,7 @@ @@ -216,7 +225,7 @@
216 {{ content.estimation.footer | markdown | safe }} 225 {{ content.estimation.footer | markdown | safe }}
217 </div> 226 </div>
218 227
219 -{# Buffer to drop the PNG image into to trick firefox into downloading the PNG #} 228 +{# Buffer to drop the PNG image into, to trick firefox into downloading the PNG #}
220 <div id="png_buffer"></div> 229 <div id="png_buffer"></div>
221 230
222 {% endif %}{# not estimation.has_failed() #} 231 {% endif %}{# not estimation.has_failed() #}
@@ -233,53 +242,22 @@ @@ -233,53 +242,22 @@
233 <script src="/static/js/vendor/d3-legend.js"></script> 242 <script src="/static/js/vendor/d3-legend.js"></script>
234 <script src="/static/js/vendor/d3-scale-chromatic.v1.min.js"></script> 243 <script src="/static/js/vendor/d3-scale-chromatic.v1.min.js"></script>
235 <script src="/static/js/vendor/d3-geo-projection.v2.min.js"></script> 244 <script src="/static/js/vendor/d3-geo-projection.v2.min.js"></script>
  245 +<script src="/static/js/plots/utils.js"></script>
236 <script src="/static/js/plots/emissions-per-distance.js"></script> 246 <script src="/static/js/plots/emissions-per-distance.js"></script>
237 <script src="/static/js/plots/travel-legs-worldmap.js"></script> 247 <script src="/static/js/plots/travel-legs-worldmap.js"></script>
238 248
239 <script type="text/javascript"> 249 <script type="text/javascript">
240 250
241 -/** POLYFILLS **/  
242 -Math.log10 = Math.log10 || function(x) { return Math.log(x) * Math.LOG10E; };  
243 -  
244 -/**  
245 - * Useful for axes' domains on plots.  
246 - * @param value  
247 - * @returns {number}  
248 - */  
249 -var ceil_value_to_magnitude = function(value) {  
250 - var sign = 1;  
251 - if (value < 0) {  
252 - value = Math.abs(value);  
253 - sign = -1;  
254 - }  
255 - if (value < 1) {  
256 - return sign;  
257 - }  
258 -  
259 - var low = Math.pow(10, Math.floor(Math.log10(value)));  
260 -  
261 - var cursor = low;  
262 - var noloop = 0;  
263 - while ((cursor < value) && (noloop <= 100)) {  
264 - cursor += 0.1 * low;  
265 - noloop += 1;  
266 - }  
267 -  
268 - return sign * cursor;  
269 -};  
270 -  
271 -/** CONFIG **/  
272 -  
273 var plots_config = { 251 var plots_config = {
274 'cities_count': {{ estimation_output.cities | length }} 252 'cities_count': {{ estimation_output.cities | length }}
275 }; 253 };
276 254
277 -/** PLOTS **/  
278 - 255 +{% if not estimation.is_many_to_many() %}
279 draw_emissions_per_distance( 256 draw_emissions_per_distance(
280 "#emissions_per_distance_histogram", 257 "#emissions_per_distance_histogram",
281 "/estimation/{{ estimation.public_id }}.csv" 258 "/estimation/{{ estimation.public_id }}.csv"
282 ); 259 );
  260 +{% endif %}
283 261
284 262
285 draw_travel_legs_worldmap( 263 draw_travel_legs_worldmap(
@@ -374,7 +352,7 @@ jQuery(document).ready(function($){ @@ -374,7 +352,7 @@ jQuery(document).ready(function($){
374 352
375 var margin = {top: 40, right: 40, bottom: 150, left: 180}, 353 var margin = {top: 40, right: 40, bottom: 150, left: 180},
376 height = Math.max(300, 100 + 16*plots_config['cities_count']) - margin.top - margin.bottom; 354 height = Math.max(300, 100 + 16*plots_config['cities_count']) - margin.top - margin.bottom;
377 - var width = Math.max(880, $(vizid).parent().width()); 355 + var width = Math.max(800, $(vizid).parent().width());
378 width = width - margin.left - margin.right; 356 width = width - margin.left - margin.right;
379 357
380 var svg_tag = d3.select(vizid) 358 var svg_tag = d3.select(vizid)