Commit 39d465697749a89b759029b504e5e7392fe78f34
1 parent
8a74d49c
Exists in
master
Surpriiiiise ! :party:
Showing
1 changed file
with
180 additions
and
33 deletions
Show diff stats
flaskr/templates/estimation.html
@@ -18,6 +18,27 @@ | @@ -18,6 +18,27 @@ | ||
18 | 18 | ||
19 | 19 | ||
20 | 20 | ||
21 | +{% macro render_cities(cities) %} | ||
22 | +<ul class="numbered-list"> | ||
23 | +{% for city in cities %} | ||
24 | + <li> | ||
25 | + <span class="city-name" title="{{ city.address }}"> | ||
26 | + {% if loop.first %} | ||
27 | + <strong> | ||
28 | + {{ city.city }} | ||
29 | + </strong> | ||
30 | + {% else %} | ||
31 | + {{ city.city }} | ||
32 | + {% endif %} | ||
33 | + </span> | ||
34 | + – | ||
35 | + {{ "%.d" | format(city.footprint | round(0) | int) }} CO<sub>2</sub><small>EQ</small> | ||
36 | + </li> | ||
37 | +{% endfor %} | ||
38 | +</ul> | ||
39 | +{% endmacro %} | ||
40 | + | ||
41 | + | ||
21 | {% block body %} | 42 | {% block body %} |
22 | <h2> | 43 | <h2> |
23 | {{ estimation.public_id }} ({{ estimation.status.name }}) | 44 | {{ estimation.public_id }} ({{ estimation.status.name }}) |
@@ -46,37 +67,37 @@ | @@ -46,37 +67,37 @@ | ||
46 | {% endif %} | 67 | {% endif %} |
47 | </div> | 68 | </div> |
48 | {% endif %} | 69 | {% endif %} |
49 | -{% if not estimation.has_failed() %} | ||
50 | 70 | ||
51 | -{% if estimation.has_many_to_many() %} | ||
52 | 71 | ||
72 | +<div class="row"> | ||
73 | + <h4>Total CO<sub>2</sub> footprint (in grams-equivalent) of each city</h4> | ||
74 | + <div id="cities_footprints_d3viz"></div> | ||
75 | +{# <br>#} | ||
76 | +{# <p>A Legend here</p>#} | ||
77 | +</div> | ||
78 | + | ||
79 | +<hr> | ||
80 | + | ||
81 | +<div class="row"> | ||
82 | + | ||
83 | +{% if not estimation.has_failed() %} | ||
84 | +{% set estimation_output = estimation.get_output_dict() %} | ||
85 | +{% if estimation.has_many_to_many() %} | ||
86 | + <div class="col-md-6"> | ||
53 | <p> | 87 | <p> |
54 | - For each city, the sum of the travels from all the origins. | 88 | + For each destination city, the sum of the travels from all the origins. |
55 | </p> | 89 | </p> |
56 | - | ||
57 | - <ul class="numbered-list"> | ||
58 | - {% for city in estimation.get_output_dict().cities %} | ||
59 | - <li> | ||
60 | - {% if loop.first %} | ||
61 | - <strong> | ||
62 | - {{ city.city }} | ||
63 | - </strong> | ||
64 | - {% else %} | ||
65 | - {{ city.city }} | ||
66 | - {% endif %} | ||
67 | - – | ||
68 | - {{ "%.d" | format(city.total | round(0) | int) }} CO<sub>2</sub><small>EQ</small> | ||
69 | - </li> | ||
70 | - {% endfor %} | ||
71 | - </ul> | 90 | + {{ render_cities(estimation_output.cities) }} |
91 | + </div> | ||
92 | +{% else %} | ||
93 | + <div class="col-md-6"> | ||
94 | + <p> | ||
95 | + Carbon footprint for each city. | ||
96 | + </p> | ||
97 | + {{ render_cities(estimation_output.mean_footprint.cities) }} | ||
98 | + </div> | ||
72 | {% endif %} | 99 | {% endif %} |
73 | 100 | ||
74 | - <div class="row"> | ||
75 | - <div class="col-md-6"> | ||
76 | - <pre> | ||
77 | -{{ estimation.output_yaml }} | ||
78 | - </pre> | ||
79 | - </div> | ||
80 | <div class="col-md-6"> | 101 | <div class="col-md-6"> |
81 | <ul class="nav"> | 102 | <ul class="nav"> |
82 | <li class="nav-item m-4"> | 103 | <li class="nav-item m-4"> |
@@ -85,18 +106,144 @@ | @@ -85,18 +106,144 @@ | ||
85 | </a> | 106 | </a> |
86 | </li> | 107 | </li> |
87 | <li class="nav-item m-4"> | 108 | <li class="nav-item m-4"> |
88 | - <a href="/estimation/{{ estimation.public_id }}.xls" class="btn btn-lg btn-secondary disabled"> | ||
89 | - Download XLS | ||
90 | - </a> | ||
91 | - </li> | ||
92 | - <li class="nav-item m-4"> | ||
93 | - <a href="/estimation/{{ estimation.public_id }}.ods" class="btn btn-lg btn-secondary disabled"> | ||
94 | - Download ODS | 109 | + <a href="/estimation/{{ estimation.public_id }}.yml" class="btn btn-lg btn-warning"> |
110 | + Download Raw YAML | ||
95 | </a> | 111 | </a> |
96 | </li> | 112 | </li> |
113 | +{# <li class="nav-item m-4">#} | ||
114 | +{# <a href="/estimation/{{ estimation.public_id }}.xls" class="btn btn-lg btn-secondary disabled">#} | ||
115 | +{# Download XLS#} | ||
116 | +{# </a>#} | ||
117 | +{# </li>#} | ||
118 | +{# <li class="nav-item m-4">#} | ||
119 | +{# <a href="/estimation/{{ estimation.public_id }}.ods" class="btn btn-lg btn-secondary disabled">#} | ||
120 | +{# Download ODS#} | ||
121 | +{# </a>#} | ||
122 | +{# </li>#} | ||
97 | </ul> | 123 | </ul> |
98 | - | ||
99 | </div> | 124 | </div> |
125 | + | ||
100 | </div> | 126 | </div> |
127 | + | ||
128 | +<hr> | ||
129 | + | ||
130 | +{#<div class="row">#} | ||
131 | +{# <div class="col-md-6">#} | ||
132 | +{# <h3>Raw Output <small>(YAML)</small></h3>#} | ||
133 | +{# <pre>#} | ||
134 | +{#{{ estimation.output_yaml }}#} | ||
135 | +{# </pre>#} | ||
136 | +{# </div>#} | ||
137 | +{#</div>#} | ||
101 | {% endif %} | 138 | {% endif %} |
102 | {% endblock %} | 139 | {% endblock %} |
140 | +{% block js %} | ||
141 | +<script src="https://d3js.org/d3.v4.js"></script> | ||
142 | +<script type="text/javascript"> | ||
143 | + | ||
144 | +/** POLYFILLS **/ | ||
145 | +Math.log10 = Math.log10 || function(x) { | ||
146 | + return Math.log(x) * Math.LOG10E; | ||
147 | +}; | ||
148 | + | ||
149 | +/** | ||
150 | + * | ||
151 | + * @param value | ||
152 | + * @returns {number} | ||
153 | + */ | ||
154 | +var ceil_value_to_magnitude = function(value) { | ||
155 | + var sign = 1; | ||
156 | + if (value < 0) { | ||
157 | + value = Math.abs(value); | ||
158 | + sign = -1; | ||
159 | + } | ||
160 | + if (value < 1) { | ||
161 | + return sign; | ||
162 | + } | ||
163 | + | ||
164 | + var low = Math.pow(10, Math.floor(Math.log10(value))); | ||
165 | + | ||
166 | + var cursor = low; | ||
167 | + var follop = 0; | ||
168 | + while ((cursor < value) && (follop <= 100)) { | ||
169 | + cursor += 0.1 * low; | ||
170 | + follop += 1; | ||
171 | + } | ||
172 | + | ||
173 | + return sign * cursor; | ||
174 | +}; | ||
175 | + | ||
176 | + | ||
177 | +/** PLOTS **/ | ||
178 | +jQuery(document).ready(function($){ | ||
179 | + | ||
180 | + var vizid = "#cities_footprints_d3viz"; | ||
181 | + | ||
182 | + // Set the dimensions and margins of the graph | ||
183 | + var margin = {top: 10, right: 30, bottom: 100, left: 100}, | ||
184 | + height = 666 - margin.top - margin.bottom; | ||
185 | + var width = Math.max(880, $(vizid).parent().width()); | ||
186 | + width = width - margin.left - margin.right; | ||
187 | + | ||
188 | + // Append the svg object to the body of the page | ||
189 | + var svg = d3.select(vizid) | ||
190 | + .append("svg") | ||
191 | + .attr("width", width + margin.left + margin.right) | ||
192 | + .attr("height", height + margin.top + margin.bottom) | ||
193 | + .append("g") | ||
194 | + .attr("transform", | ||
195 | + "translate(" + margin.left + "," + margin.top + ")"); | ||
196 | + | ||
197 | + // Parse the Data | ||
198 | + d3.csv("/estimation/{{ estimation.public_id }}.csv", function(data) { | ||
199 | + | ||
200 | + // Extrema | ||
201 | + var data_y_max = d3.max(data, function(d) { return parseFloat(d['co2 (g)']); }); | ||
202 | + var axis_y_max = ceil_value_to_magnitude(data_y_max); | ||
203 | + | ||
204 | + // X axis | ||
205 | + var x = d3.scaleBand() | ||
206 | + .range([ 0, width ]) | ||
207 | + .domain(data.map(function(d) { return d.city; })) | ||
208 | + .padding(0.2); | ||
209 | + svg.append("g") | ||
210 | + .attr("transform", "translate(0," + height + ")") | ||
211 | + .call(d3.axisBottom(x)) | ||
212 | + .selectAll("text") | ||
213 | + .attr("transform", "translate(-10,0)rotate(-45)") | ||
214 | + .style("text-anchor", "end"); | ||
215 | + | ||
216 | + // Add Y axis | ||
217 | + var y = d3.scaleLinear() | ||
218 | + .range([ height, 0 ]) | ||
219 | + .domain([ 0, axis_y_max ]); | ||
220 | + svg.append("g") | ||
221 | + .call(d3.axisLeft(y)); | ||
222 | + | ||
223 | + // Bars | ||
224 | + svg.selectAll("mybar") | ||
225 | + .data(data) | ||
226 | + .enter() | ||
227 | + .append("rect") | ||
228 | + .attr("x", function(d) { return x(d['city']); }) | ||
229 | + .attr("width", x.bandwidth()) | ||
230 | + .attr("fill", "#d0808b") | ||
231 | + // Hide bar at the beginning | ||
232 | + .attr("height", function(d) { return height - y(0); }) // always equal to 0 | ||
233 | + .attr("y", function(d) { return y(0); }); | ||
234 | + | ||
235 | + // Animation | ||
236 | + svg.selectAll("rect") | ||
237 | + .transition() | ||
238 | + .duration(800) | ||
239 | + .attr("y", function(d) { return y(d['co2 (g)']); }) | ||
240 | + .attr("height", function(d) { return height - y(d['co2 (g)']); }) | ||
241 | + .delay(function(d, i) { return(i*100); }); | ||
242 | + | ||
243 | + // … | ||
244 | + }); | ||
245 | + | ||
246 | +}); | ||
247 | +</script> | ||
248 | +{% endblock %} | ||
249 | + |