source: OpenWorkouts-current/ow/static/js/ow.js @ dbfab70

currentfeature/docs
Last change on this file since dbfab70 was dbfab70, checked in by borja <borja@…>, 5 years ago

(#7) Show workouts in the profile page related to the highlighted/current month

selected in the yearly chart.

Also, allow users to click on the monthly bars on the chart, to choose that month.

  • Property mode set to 100644
File size: 11.6 KB
Line 
1
2/*
3
4  OpenWorkouts Javascript code
5
6*/
7
8
9// Namespace
10var owjs = {};
11
12
13owjs.map = function(spec) {
14
15    "use strict";
16
17    // parameters provided when creating an "instance" of a map
18    var map_id = spec.map_id;
19    var latitude = spec.latitude;
20    var longitude = spec.longitude;
21    var zoom = spec.zoom;
22    var gpx_url = spec.gpx_url;
23    var start_icon = spec.start_icon;
24    var end_icon = spec.end_icon;
25    var shadow = spec.shadow;
26    var elevation = spec.elevation;
27    var zoom_control = spec.zoom_control;
28
29    // OpenStreetMap urls and references
30    var openstreetmap_url = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
31    var openstreetmap_attr = 'Map data &copy; <a href="http://www.osm.org">OpenStreetMap</a>';
32
33    // Some vars reused through the code
34    var map;
35    var gpx;
36    var elevation;
37    var ow_charts;
38
39    var create_map = function create_map(latitude, longitude, zoom) {
40        /* Create a Leaflet map, set center point and add tiles */
41        map = L.map(map_id, {zoomControl: zoom_control});
42        map.setView([latitude, longitude], zoom);
43        var tile_layer = L.tileLayer(openstreetmap_url, {
44            attribution: openstreetmap_attr
45        });
46        tile_layer.addTo(map);
47    };
48
49    var add_elevation_chart = function add_elevation_chart() {
50        /*
51           Add the elevation chart support to the map.
52           This has to be called *after* create_map and *before* load_gpx.
53        */
54        elevation = L.control.elevation({
55            position: "bottomright",
56            theme: "steelblue-theme", //default: lime-theme
57            width: 600,
58            height: 125,
59            margins: {
60                top: 10,
61                right: 20,
62                bottom: 30,
63                left: 50
64            },
65            useHeightIndicator: true, //if false a marker is drawn at map position
66            interpolation: "linear", //see https://github.com/mbostock/d3/wiki/SVG-Shapes#wiki-area_interpolate
67            hoverNumber: {
68                decimalsX: 3, //decimals on distance (always in km)
69                decimalsY: 0, //deciamls on height (always in m)
70                formatter: undefined //custom formatter function may be injected
71            },
72            xTicks: undefined, //number of ticks in x axis, calculated by default according to width
73            yTicks: undefined, //number of ticks on y axis, calculated by default according to height
74            collapsed: false    //collapsed mode, show chart on click or mouseover
75        });
76
77        var ele_container = elevation.addTo(map);
78        /* document.getElementById('ow-analysis').appendChild(
79            ele_container._container); */
80    };
81
82    var load_gpx = function load_gpx(gpx_url) {
83        /*
84          Load the gpx from the given url, add it to the map and feed it to the
85          elevation chart
86        */
87        var gpx = new L.GPX(gpx_url, {
88            async: true,
89            marker_options: {
90                startIconUrl: start_icon,
91                endIconUrl: end_icon,
92                shadowUrl: shadow,
93            },
94        });
95
96        gpx.on('loaded', function(e) {
97            map.fitBounds(e.target.getBounds());
98        });
99
100        if (elevation) {
101            gpx.on("addline",function(e){
102                elevation.addData(e.line);
103                // ow_charts.addData(e.line);
104            });
105        };
106
107        gpx.addTo(map);
108    };
109
110    var render = function render() {
111        // create the map, add elevation, load gpx
112        create_map(latitude, longitude, zoom);
113        if (elevation) {
114            add_elevation_chart();
115        }
116        // add_ow_charts();
117        load_gpx(gpx_url);
118    };
119
120    var that = {}
121    that.render = render;
122    return that
123
124};
125
126
127owjs.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(chart_selector),
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};
229
230
231owjs.year_chart = function(spec) {
232
233    "use strict";
234
235    // parameters provided when creating an "instance" of the chart
236    var chart_selector = spec.chart_selector,
237        filters_selector = spec.filters_selector,
238        url = spec.url,
239        current_month = spec.current_month,
240        y_axis_labels = spec.y_axis_labels;
241
242    // Helpers
243    function select_x_axis_label(d) {
244        /* Given a value, return the label associated with it */
245        return d3.select('.x-axis-b')
246            .selectAll('text')
247            .filter(function(x) { return x == d.name; });
248    };
249
250    function get_y_value(d, filter_by) {
251        return Number(d[filter_by]);
252    };
253
254    function get_y_axis_label(filter_by) {
255        return y_axis_labels[filter_by];
256    };
257
258    // Methods
259    var filters_setup = function filters_setup() {
260        $(filters_selector).on('click', function(e) {
261            var filter_by = 'distance';
262            e.preventDefault();
263            filter_by = $(this).attr('class').split('-')[1]
264            var chart = d3.select(chart_selector);
265            chart.selectAll("*").remove();
266            render(filter_by);
267        });
268    };
269
270    var render = function render(filter_by) {
271        /*
272          Build a d3 bar chart, populated with data from the given url.
273        */
274        var chart = d3.select(chart_selector),
275            margin = {top: 20, right: 20, bottom: 30, left: 50},
276            width = +chart.attr("width") - margin.left - margin.right,
277            height = +chart.attr("height") - margin.top - margin.bottom,
278            g = chart.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"),
279            x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
280            y = d3.scaleLinear().rangeRound([height, 0]);
281
282        d3.json(url).then(function (data) {
283            x.domain(data.map(function (d) {
284                return d.name;
285            }));
286
287            y.domain([0, d3.max(data, function (d) {
288                return get_y_value(d, filter_by);
289            })]);
290
291            g.append("g")
292                .attr('class', 'x-axis-b')
293                .attr("transform", "translate(0," + height + ")")
294                .call(d3.axisBottom(x))
295
296            g.append("g")
297                .call(d3.axisLeft(y))
298                .append("text")
299                .attr("fill", "#000")
300                .attr("transform", "rotate(-90)")
301                .attr("y", 6)
302                .attr("dy", "0.71em")
303                .attr("text-anchor", "end")
304                .text(get_y_axis_label(filter_by));
305
306            g.selectAll(".bar")
307                .data(data)
308                .enter().append("rect")
309                .attr("class", function(d) {
310                    if (d.id == current_month){
311                        select_x_axis_label(d).attr('style', "font-weight: bold;");
312                        return 'bar current'
313                    }
314                    else {
315                        return 'bar'
316                    }
317                })
318                .attr("x", function (d) {
319                    return x(d.name);
320                })
321                .attr("y", function (d) {
322                    return y(get_y_value(d, filter_by));
323                })
324                .attr("width", x.bandwidth())
325                .attr("height", function (d) {
326                    return height - y(get_y_value(d, filter_by));
327                })
328                .on('mouseover', function(d) {
329                    if (d.id != current_month){
330                        select_x_axis_label(d).attr('style', "font-weight: bold;");
331                    }
332                })
333                .on('mouseout', function(d) {
334                    if (d.id != current_month){
335                        select_x_axis_label(d).attr('style', "font-weight: regular;");
336                    }
337                })
338                .on('click', function(d) {
339                    window.location.href = d.url;
340                });
341
342            g.selectAll(".text")
343                .data(data)
344                .enter()
345                .append("text")
346                .attr("class","label")
347                .attr("x", function (d) {
348                    return x(d.name) + x.bandwidth()/2;
349                })
350                .attr("y", function (d) {
351                    /*
352                      Get the value for the current bar, then get the maximum
353                      value to be displayed in the bar, which is used to
354                      calculate the proper position of the label for this bar,
355                      relatively to its height (1% above the bar)
356                     */
357                    var value = get_y_value(d, filter_by);
358                    var max = y.domain()[1];
359                    return y(value + y.domain()[1] * 0.01);
360                })
361                .text(function(d) {
362                    var value = get_y_value(d, filter_by)
363                    if ( value > 0) {
364                        return value;
365                    }
366                });
367
368        });
369    };
370
371    var that = {}
372    that.filters_setup = filters_setup;
373    that.render = render;
374    return that
375
376};
Note: See TracBrowser for help on using the repository browser.