Changeset 5bdfbfb in OpenWorkouts-current
- Timestamp:
- Jan 25, 2019, 12:42:33 AM (5 years ago)
- Branches:
- current, feature/docs, master
- Children:
- 26220ba, 7783f97
- Parents:
- 421f05f
- Location:
- ow
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
ow/static/css/openworkouts.css
r421f05f r5bdfbfb 12 12 background-color: #eeeeee; 13 13 } 14 15 /* dashboard, weekly stats */ 16 17 span.week_totals_left { 18 padding-right: 5px; 19 border-right: 1px solid #e1e1e1; 20 } 21 22 span.week_totals_right { 23 padding-left: 5px; 24 } 25 26 .x-axis path, .x-axis line { 27 fill: none; 28 stroke: none; 29 } 30 31 .bar { 32 fill: #f8b5be; 33 } 34 35 .bar:hover { 36 fill: #ee4056; 37 } 38 39 .current { 40 fill: #ee4056; 41 } 42 43 text.label { 44 font-size: 0.6em; 45 text-anchor: middle; 46 } -
ow/static/js/ow.js
r421f05f r5bdfbfb 123 123 124 124 }; 125 126 127 owjs.week_chart = function(spec) { 128 129 "use strict"; 130 131 // parameters provided when creating an "instance" of the chart 132 var chart_selector = spec.chart_selector, 133 url = spec.url, 134 current_day_name = spec.current_day_name 135 136 // Helpers 137 function select_x_axis_label(d) { 138 /* Given a value, return the label associated with it */ 139 return d3.select('.x-axis') 140 .selectAll('text') 141 .filter(function(x) { return x == d.name; }); 142 } 143 144 // Methods 145 var render = function render() { 146 /* 147 Build a d3 bar chart, populated with data from the given url. 148 */ 149 var chart = d3.select("svg"), 150 margin = {top: 20, right: 20, bottom: 30, left: 50}, 151 width = +chart.attr("width") - margin.left - margin.right, 152 height = +chart.attr("height") - margin.top - margin.bottom, 153 g = chart.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"), 154 x = d3.scaleBand().rangeRound([0, width]).padding(0.1), 155 y = d3.scaleLinear().rangeRound([height, 0]); 156 157 d3.json(url).then(function (data) { 158 x.domain(data.map(function (d) { 159 return d.name; 160 })); 161 162 y.domain([0, d3.max(data, function (d) { 163 return Number(d.distance); 164 })]); 165 166 g.append("g") 167 .attr('class', 'x-axis') 168 .attr("transform", "translate(0," + height + ")") 169 .call(d3.axisBottom(x)) 170 171 g.selectAll(".bar") 172 .data(data) 173 .enter().append("rect") 174 .attr("class", function(d) { 175 if (d.name == current_day_name){ 176 select_x_axis_label(d).attr('style', "font-weight: bold;"); 177 return 'bar current' 178 } 179 else { 180 return 'bar' 181 } 182 }) 183 .attr("x", function (d) { 184 return x(d.name); 185 }) 186 .attr("y", function (d) { 187 return y(Number(d.distance)); 188 }) 189 .attr("width", x.bandwidth()) 190 .attr("height", function (d) { 191 return height - y(Number(d.distance)); 192 }) 193 .on('mouseover', function(d) { 194 if (d.name != current_day_name){ 195 select_x_axis_label(d).attr('style', "font-weight: bold;"); 196 } 197 }) 198 .on('mouseout', function(d) { 199 if (d.name != current_day_name){ 200 select_x_axis_label(d).attr('style', "font-weight: regular;"); 201 } 202 }); 203 204 g.selectAll(".text") 205 .data(data) 206 .enter() 207 .append("text") 208 .attr("class","label") 209 .attr("x", function (d) { 210 return x(d.name) + x.bandwidth()/2; 211 }) 212 .attr("y", function (d) { 213 return y(Number(d.distance) + 5); 214 }) 215 .text(function(d) { 216 if (Number(d.distance) > 0) { 217 return d.distance; 218 } 219 }); 220 221 }); 222 }; 223 224 var that = {} 225 that.render = render; 226 return that 227 228 }; -
ow/templates/dashboard.pt
r421f05f r5bdfbfb 142 142 </ul> 143 143 </tal:activity_tree> 144 145 <tal:stats> 146 147 <div class="week-stats js-week-stats"> 148 <h3><tal:t i18n:translate="">This week</tal:t></h3> 149 <h4 tal:define="totals context.week_totals"> 150 <span class="week_totals_left"> 151 <tal:d tal:content="round(totals['distance'])"></tal:d> 152 <tal:t i18n:translate="">kms</tal:t> 153 </span> 154 <span class="week_totals_right"> 155 <tal:hms tal:define="hms timedelta_to_hms(totals['time'])"> 156 <tal:h tal:content="str(hms[0]).zfill(2)"></tal:h> 157 <tal:t i18n:translate="">hours</tal:t>, 158 <tal:h tal:content="str(hms[1]).zfill(2)"></tal:h> 159 <tal:t i18n:translate="">min.</tal:t> 160 </tal:hms> 161 </span> 162 </h4> 163 <svg width="300" height="200"></svg> 164 <style> 165 166 </style> 167 </div> 168 169 <div class="user-stats"> 170 <tal:year-stats tal:repeat="year context.activity_years"> 171 <h3><a href="" tal:content="year"></a></h3> 172 <ul tal:define="stats context.stats(year)"> 173 <li> 174 <span i18n:translate="">Workouts:</span> 175 <span tal:content="stats['workouts']"></span> 176 </li> 177 <li> 178 <span i18n:translate="">Distance:</span> 179 <span tal:content="round(stats['distance'])"></span> kms 180 </li> 181 <li> 182 <span i18n:translate="">Time:</span> 183 <tal:hms tal:define="hms timedelta_to_hms(stats['time'])"> 184 <span> 185 <tal:h tal:content="str(hms[0]).zfill(2)"></tal:h> 186 <tal:t i18n:translate="">hours</tal:t>, 187 <tal:h tal:content="str(hms[1]).zfill(2)"></tal:h> 188 <tal:t i18n:translate="">min.</tal:t> 189 </span> 190 </tal:hms> 191 </li> 192 <li> 193 <span i18n:translate="">Elevation:</span> 194 <span tal:content="stats['elevation']"></span> m 195 </li> 196 </ul> 197 </tal:year-stats> 198 </div> 199 </tal:stats> 200 144 201 </aside> 145 202 … … 148 205 </metal:content> 149 206 207 <metal:body-js metal:fill-slot="body-js"> 208 <script src="${request.static_url('ow:static/components/d3/d3.min.js')}"></script> 209 <script src="${request.static_url('ow:static/js/ow.js')}"></script> 210 211 <script type="text/javascript"> 212 var week_chart = owjs.week_chart({ 213 chart_selector: 'div.js-week-stats', 214 url: "${request.resource_url(context, 'week')}", 215 current_day_name: "${current_day_name}" 216 }); 217 week_chart.render(); 218 </script> 219 220 </metal:body-js> 221 150 222 </html> -
ow/tests/views/test_user.py
r421f05f r5bdfbfb 153 153 request = dummy_request 154 154 response = user_views.dashboard(john, request) 155 assert len(response) == 4 156 assert 'month_name' in response.keys() 155 assert len(response) == 6 156 assert 'month_name' in response.keys() 157 assert response['current_year'] == datetime.now().year 158 assert response['current_day_name'] == datetime.now().strftime('%a') 157 159 # this user has a single workout, in 2015 158 160 assert response['viewing_year'] == 2015 … … 168 170 request.GET['year'] = 2015 169 171 response = user_views.dashboard(john, request) 170 assert len(response) == 4 171 assert 'month_name' in response.keys() 172 assert len(response) == 6 173 assert 'month_name' in response.keys() 174 assert response['current_year'] == datetime.now().year 175 assert response['current_day_name'] == datetime.now().strftime('%a') 172 176 # this user has a single workout, in 2015 173 177 assert response['viewing_year'] == 2015 … … 177 181 request.GET['year'] = 2000 178 182 response = user_views.dashboard(john, request) 179 assert len(response) == 4 180 assert 'month_name' in response.keys() 183 assert len(response) == 6 184 assert 'month_name' in response.keys() 185 assert response['current_year'] == datetime.now().year 186 assert response['current_day_name'] == datetime.now().strftime('%a') 181 187 # this user has a single workout, in 2015 182 188 assert response['viewing_year'] == 2000 … … 195 201 request.GET['month'] = 6 196 202 response = user_views.dashboard(john, request) 197 assert len(response) == 4 198 assert 'month_name' in response.keys() 203 assert len(response) == 6 204 assert 'month_name' in response.keys() 205 assert response['current_year'] == datetime.now().year 206 assert response['current_day_name'] == datetime.now().strftime('%a') 199 207 # this user has a single workout, in 2015 200 208 assert response['viewing_year'] == 2015 … … 204 212 request.GET['month'] = 2 205 213 response = user_views.dashboard(john, request) 206 assert len(response) == 4 207 assert 'month_name' in response.keys() 214 assert len(response) == 6 215 assert 'month_name' in response.keys() 216 assert response['current_year'] == datetime.now().year 217 assert response['current_day_name'] == datetime.now().strftime('%a') 208 218 # this user has a single workout, in 2015 209 219 assert response['viewing_year'] == 2015 … … 214 224 request.GET['month'] = 6 215 225 response = user_views.dashboard(john, request) 216 assert len(response) == 4 217 assert 'month_name' in response.keys() 226 assert len(response) == 6 227 assert 'month_name' in response.keys() 228 assert response['current_year'] == datetime.now().year 229 assert response['current_day_name'] == datetime.now().strftime('%a') 218 230 # this user has a single workout, in 2015 219 231 assert response['viewing_year'] == 2010 … … 230 242 request.GET['month'] = 5 231 243 response = user_views.dashboard(john, request) 232 assert len(response) == 4 233 assert 'month_name' in response.keys() 244 assert len(response) == 6 245 assert 'month_name' in response.keys() 246 assert response['current_year'] == datetime.now().year 247 assert response['current_day_name'] == datetime.now().strftime('%a') 234 248 # this user has a single workout, in 2015 235 249 assert response['viewing_year'] == 2015 … … 239 253 request.GET['month'] = 6 240 254 response = user_views.dashboard(john, request) 241 assert len(response) == 4 242 assert 'month_name' in response.keys() 255 assert len(response) == 6 256 assert 'month_name' in response.keys() 257 assert response['current_year'] == datetime.now().year 258 assert response['current_day_name'] == datetime.now().strftime('%a') 243 259 # this user has a single workout, in 2015 244 260 assert response['viewing_year'] == 2015 -
ow/views/user.py
r421f05f r5bdfbfb 146 146 147 147 return { 148 'current_year': datetime.now().year, 149 'current_day_name': datetime.now().strftime('%a'), 148 150 'month_name': month_name, 149 151 'viewing_year': viewing_year, -
ow/views/workout.py
r421f05f r5bdfbfb 1 from decimal import Decimal 1 2 from datetime import datetime, timedelta, time, timezone 2 3 … … 121 122 tzinfo=timezone.utc) 122 123 context.start = start 124 # ensure distance is a decimal 125 context.distance = Decimal(context.distance) 123 126 catalog = get_catalog(context) 124 127 reindex_object(catalog, context)
Note: See TracChangeset
for help on using the changeset viewer.