Commit 701dbf83625d61e45d9feececd519dfd427121d5
1 parent
e86f2462
Exists in
master
feat: integrate the emissions histogram plot
Showing
3 changed files
with
61 additions
and
51 deletions
Show diff stats
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 | 2 | // set the dimensions and margins of the graph |
3 | 3 | let margin = {top: 48, right: 88, bottom: 68, left: 98}, |
4 | 4 | width = 960 - margin.left - margin.right, |
... | ... | @@ -75,13 +75,14 @@ function draw_emissions_per_distance(divSelector, csvUrl) { |
75 | 75 | vertical.style("display", "inherit"); |
76 | 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 | 82 | function addVerticalLineAndListenCursor(xScale, attendeeNumberPerGroup, attendeeSum) { |
82 | - let verticalRuler = d3.select(divSelector) | |
83 | + let verticalRuler = d3.select(containerSelector) | |
83 | 84 | .append("div") |
84 | - // .attr("class", "remove") | |
85 | + .attr("class", "no-pointer-events") | |
85 | 86 | .style("display", "none") |
86 | 87 | .style("position", "absolute") |
87 | 88 | .style("z-index", "19") |
... | ... | @@ -92,9 +93,9 @@ function draw_emissions_per_distance(divSelector, csvUrl) { |
92 | 93 | .style("left", "-10px") |
93 | 94 | .style("background", "#000"); |
94 | 95 | |
95 | - let rightArea = d3.select(divSelector) | |
96 | + let rightArea = d3.select(containerSelector) | |
96 | 97 | .append("div") |
97 | - // .attr("class", "remove") | |
98 | + .attr("class", "no-pointer-events") | |
98 | 99 | .style("display", "none") |
99 | 100 | .style("position", "absolute") |
100 | 101 | .style("z-index", "-50") |
... | ... | @@ -105,13 +106,13 @@ function draw_emissions_per_distance(divSelector, csvUrl) { |
105 | 106 | .style("left", "0px") |
106 | 107 | .style("background", "rgba(60, 200, 60, 0.3)"); |
107 | 108 | |
108 | - let tooltip = d3.select(divSelector) | |
109 | + let tooltip = d3.select(containerSelector) | |
109 | 110 | .append("div") |
110 | 111 | .attr("class", "no-pointer-events") |
111 | 112 | .style("display", "none") |
112 | 113 | .style("position", "absolute") |
113 | 114 | .style("z-index", "20") |
114 | - .style("width", "155px") | |
115 | + .style("width", "161px") | |
115 | 116 | .style("height", "35px") |
116 | 117 | .style("top", "10px") |
117 | 118 | .style("bottom", "30px") |
... | ... | @@ -123,7 +124,7 @@ function draw_emissions_per_distance(divSelector, csvUrl) { |
123 | 124 | .style("border", "1px solid grey") |
124 | 125 | .style("background", "rgba(255, 255, 255, 0.7)"); |
125 | 126 | |
126 | - d3.select(divSelector + " svg") | |
127 | + d3.select(containerSelector + " svg") | |
127 | 128 | .on("mousemove", function (event) { |
128 | 129 | setupCursorBoxes(event, attendeeSum, attendeeNumberPerGroup, xScale, tooltip, verticalRuler, rightArea); |
129 | 130 | }) |
... | ... | @@ -133,12 +134,14 @@ function draw_emissions_per_distance(divSelector, csvUrl) { |
133 | 134 | } |
134 | 135 | |
135 | 136 | document.addEventListener("DOMContentLoaded", () => { |
137 | + width = Math.max(880, $(containerSelector).parent().width()); | |
138 | + width = width - margin.left - margin.right; | |
136 | 139 | let maxemissions = 0; |
137 | 140 | let maxemissionsPercent = 0; |
138 | 141 | let maxDistance = 0; |
139 | - let svg = d3.select(divSelector) | |
142 | + let svg = d3.select(containerSelector) | |
140 | 143 | .append("svg") |
141 | - // .attr("id", divSelector + "-svg") | |
144 | + // .attr("id", containerSelector + "-svg") | |
142 | 145 | .attr("width", width + margin.left + margin.right) |
143 | 146 | .attr("height", height + margin.top + margin.bottom) |
144 | 147 | .append("g") | ... | ... |
... | ... | @@ -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 | 103 | {# <div id="cities_footprints_d3viz" class="plot-container"></div>#} |
104 | 104 | <hr> |
105 | 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 | 106 | {# This MUST stay empty (because Simg uses svg.getparentnode.innerhtml) #} |
111 | 107 | <div id="cities_footprints_d3viz_lollipop" class="plot-container"> |
112 | 108 | </div> |
... | ... | @@ -115,8 +111,21 @@ |
115 | 111 | </div> |
116 | 112 | |
117 | 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 | 122 | {% endif %} |
123 | +{#############################################################################} | |
119 | 124 | |
125 | +{% endif %}{# not estimation.has_failed() #} | |
126 | + | |
127 | + | |
128 | +{# LIST OF CITIES ############################################################} | |
120 | 129 | <div class="row"> |
121 | 130 | |
122 | 131 | {% if not estimation.has_failed() %} |
... | ... | @@ -216,7 +225,7 @@ |
216 | 225 | {{ content.estimation.footer | markdown | safe }} |
217 | 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 | 229 | <div id="png_buffer"></div> |
221 | 230 | |
222 | 231 | {% endif %}{# not estimation.has_failed() #} |
... | ... | @@ -233,53 +242,22 @@ |
233 | 242 | <script src="/static/js/vendor/d3-legend.js"></script> |
234 | 243 | <script src="/static/js/vendor/d3-scale-chromatic.v1.min.js"></script> |
235 | 244 | <script src="/static/js/vendor/d3-geo-projection.v2.min.js"></script> |
245 | +<script src="/static/js/plots/utils.js"></script> | |
236 | 246 | <script src="/static/js/plots/emissions-per-distance.js"></script> |
237 | 247 | <script src="/static/js/plots/travel-legs-worldmap.js"></script> |
238 | 248 | |
239 | 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 | 251 | var plots_config = { |
274 | 252 | 'cities_count': {{ estimation_output.cities | length }} |
275 | 253 | }; |
276 | 254 | |
277 | -/** PLOTS **/ | |
278 | - | |
255 | +{% if not estimation.is_many_to_many() %} | |
279 | 256 | draw_emissions_per_distance( |
280 | 257 | "#emissions_per_distance_histogram", |
281 | 258 | "/estimation/{{ estimation.public_id }}.csv" |
282 | 259 | ); |
260 | +{% endif %} | |
283 | 261 | |
284 | 262 | |
285 | 263 | draw_travel_legs_worldmap( |
... | ... | @@ -374,7 +352,7 @@ jQuery(document).ready(function($){ |
374 | 352 | |
375 | 353 | var margin = {top: 40, right: 40, bottom: 150, left: 180}, |
376 | 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 | 356 | width = width - margin.left - margin.right; |
379 | 357 | |
380 | 358 | var svg_tag = d3.select(vizid) | ... | ... |