Projekt

Obecné

Profil

« Předchozí | Další » 

Revize fb12df6d

Přidáno uživatelem Jan Kohlíček před téměř 7 roky(ů)

refs #7014: přidané grafy denní průměry, optimalizace API, styly převedeny do SASS, zvětšený prostor pro grafy

Zobrazit rozdíly:

frontend/app.js
2 2

  
3 3
app.constant('config', {
4 4
    APP_NAME: 'PVPK',
5
    APP_VERSION: 1.0,
5
    APP_VERSION: '1.2.0',
6 6
    API_URL: API_URL,
7 7
    API_TOKEN: API_TOKEN,
8 8
    DEFAULT_POSITION: {LAT: 49.53, LNG: 13.3},
9
    DEFAULT_ZOOM: 10
9
    DEFAULT_ZOOM: 10,
10
    DEFAULT_ZOOM_MAX: 7,
10 11
});
11 12

  
12
//PRIPRAVA PRO REFAKTORING
13
// app.config(function($stateProvider, $locationProvider) {
14
//     // $stateProvider
15
//     // .state('report',{
16
//     //     views: {
17
//     //         'search': {
18
//     //             templateUrl: 'report-filters.html',
19
//     //             controller: searchController
20
//     //         },
21
//     //         'graph': {
22
//     //             templateUrl: 'report-table.html',
23
//     //             controller: graphController
24
//     //         },
25
//     //         'map': {
26
//     //             templateUrl: 'report-graph.html',
27
//     //             controller: mapController
28
//     //         }
29
//     //     }
30
//     // });
31
//    $locationProvider.html5Mode(true);
32
// });
33

  
34

  
35 13
app.controller('mainController', function ($rootScope, $scope, $location, $window) {
36 14

  
37 15
    this.$onInit = function () {
38

  
16
        $scope.showLoadingScreen = true;
39 17
    };
40 18

  
41 19
    $window.onload = function () {
42 20
        let params = $location.search();
43 21
        if (params.deviceId) {
44
            $rootScope.$emit('infoLocation', {id: params.deviceId, direction: params.direction});
45 22
            $rootScope.$emit('activeMarker', {id: params.deviceId});
46 23
        }
47 24

  
48
        $scope.showLoadingScreen = false;
25
        $scope.$apply(function () {
26
            $scope.showLoadingScreen = false;
27
        });
49 28
    };
50 29

  
51 30
    $rootScope.$on('$locationChangeSuccess', function (event, newUrl, oldUrl) {
31
        let params = $location.search();
52 32

  
53 33
        if (newUrl !== oldUrl && $scope.historyUrl) {
54
            let params = $location.search();
55

  
56 34
            if ($scope.historyUrl.q !== $scope.historyUrl.q || $scope.historyUrl.isDirection != params.isDirection) {
57 35
                $rootScope.$emit('setSearchFromUrl', null);
58 36
            }
......
66 44
            } else if (params.deviceId && ($scope.historyUrl.deviceId !== params.deviceId || $scope.historyUrl.direction !== params.direction)) {
67 45
                $rootScope.$emit('infoLocation', {id: params.deviceId, direction: params.direction});
68 46
                $rootScope.$emit('activeMarker', {id: params.deviceId});
69
            }else if(!params.deviceId && $scope.historyUrl.deviceId){
47
            } else if (!params.deviceId && $scope.historyUrl.deviceId) {
70 48
                $rootScope.selectDevice = null;
71 49
                $rootScope.$emit('setDefaultMap', null);
72 50
            }
51
        } else if (params.deviceId) {
52
            $rootScope.$emit('infoLocation', {id: params.deviceId, direction: params.direction});
73 53
        }
74 54

  
75 55
        $scope.historyUrl = $location.search();
......
133 113
app.controller('searchController', function ($rootScope, $scope, $location, config, Device) {
134 114

  
135 115
    this.$onInit = function () {
116
        $scope.config = config;
136 117
        $scope.locations = [];
137 118
        $scope.showSearchLoading = false;
138 119

  
......
140 121
    };
141 122

  
142 123
    $scope.searchLocations = function () {
124
        let params = $location.search();
125
        params.q = $scope.search.q;
126
        params.isDirection = $scope.search.isDirection ? 1 : null;
127
        $location.search(params);
128

  
143 129
        if (!$scope.search.q || $scope.search.q.length <= 1) {
144 130
            $scope.locations = [];
145 131
            return;
......
147 133

  
148 134
        $scope.showSearchLoading = true;
149 135

  
150
        let params = $location.search();
151
        params.q = $scope.search.q;
152
        params.isDirection = $scope.search.isDirection ? 1 : 0;
153
        $location.search(params);
154

  
155 136
        Device.query({
156 137
            address: $scope.search.q,
157 138
            showDirection: $scope.search.isDirection ? 1 : 0
......
167 148

  
168 149
    $rootScope.$on('setSearchFromUrl', function (event, args) {
169 150
        let params = $location.search();
170

  
171 151
        $scope.search = {
172 152
            q: params.q,
173 153
            isDirection: params.isDirection ? !!+params.isDirection : false
......
189 169
        $rootScope.selectDevice = null;
190 170
        $scope.showInfoLoading = false;
191 171
        $scope.vehicles = [];
192
        $scope.typeVehicle = null;
193 172
        $scope.filterVehicles = [];
194 173

  
195 174
        Vehicle.query(null, function (data) {
......
211 190
            fromDate: moment(params.fromDate, 'YYYY-MM-DD').isValid() ? moment(params.fromDate).toDate() : defaultRange.fromDate.toDate(),
212 191
            toDate: moment(params.toDate, 'YYYY-MM-DD').isValid() ? moment(params.toDate).toDate() : defaultRange.toDate.toDate(),
213 192
            fromTime: moment(params.fromTime, 'HH:mm').isValid() ? moment(params.fromTime, 'HH:mm').toDate() : defaultRange.fromTime.toDate(),
214
            toTime: moment(params.toTime, 'HH:mm').isValid() ? moment(params.toTime, 'HH:mm').toDate() : defaultRange.toTime.toDate()
193
            toTime: moment(params.toTime, 'HH:mm').isValid() ? moment(params.toTime, 'HH:mm').toDate() : defaultRange.toTime.toDate(),
194
            isTime: params.isTime == 0 ? false : defaultRange.isTime
215 195
        };
216 196

  
217 197
    });
......
226 206

  
227 207
        let range = $scope.getRange();
228 208

  
209
        // if (!$rootScope.selectDevice || args.id !== $rootScope.selectDevice.id)
210
        //     $rootScope.selectDevice = {name: '...', street: '...', town: '...'};
211

  
212

  
229 213
        Device.get({
214
            period: range.isTime ? 'time-period' : 'day-period',
230 215
            id: args.id,
231 216
            direction: args.direction,
232 217
            dateFrom: range.fromDate.format('YYYY-MM-DD'),
233 218
            dateTo: range.toDate.format('YYYY-MM-DD'),
234
            timeFrom: range.fromTime.format('HH:mm'),
235
            timeTo: range.toTime.format('HH:mm'),
219
            timeFrom: range.isTime ? range.fromTime.format('HH:mm') : null,
220
            timeTo: range.isTime ? range.toTime.format('HH:mm') : null,
236 221
        }, function (data) {
237 222
            $rootScope.selectDevice = data;
238 223

  
239
            $scope.typeVehicle = null;
240 224
            $scope.renderGraphAverageSpeed();
241 225
            $scope.renderGraphNumberVehicles();
242 226

  
......
250 234

  
251 235
    });
252 236

  
237

  
253 238
    $scope.changeRange = function () {
254
        if ($scope.range.fromDate >= $scope.range.toDate || $scope.range.fromTime >= $scope.range.toTime) {
239
        if ($scope.range.fromDate >= $scope.range.toDate || ($scope.range.isTime && $scope.range.fromTime >= $scope.range.toTime)) {
255 240
            $rootScope.selectDevice.traffics = [];
256 241
            return;
257 242
        }
......
261 246
        let params = $location.search();
262 247
        params.fromDate = range.fromDate.format('YYYY-MM-DD');
263 248
        params.toDate = range.toDate.format('YYYY-MM-DD');
264
        params.fromTime = range.fromTime.format('HH:mm');
265
        params.toTime = range.toTime.format('HH:mm');
249
        params.fromTime = range.isTime ? range.fromTime.format('HH:mm') : null;
250
        params.toTime = range.isTime ? range.toTime.format('HH:mm') : null;
251
        params.isTime = range.isTime ? null : 0;
266 252
        $location.search(params);
267 253

  
268 254
        if ($rootScope.selectDevice)
......
279 265
            fromDate: moment($scope.range.fromDate).isValid() ? moment($scope.range.fromDate) : defaultRange.fromDate,
280 266
            toDate: moment($scope.range.toDate).isValid() ? moment($scope.range.toDate) : defaultRange.toDate,
281 267
            fromTime: moment($scope.range.fromTime).isValid() ? moment($scope.range.fromTime) : defaultRange.fromTime,
282
            toTime: moment($scope.range.toTime).isValid() ? moment($scope.range.toTime) : defaultRange.toTime
268
            toTime: moment($scope.range.toTime).isValid() ? moment($scope.range.toTime) : defaultRange.toTime,
269
            isTime: $scope.range.isTime ? true : false
283 270
        };
284 271
    };
285 272

  
......
288 275
            fromDate: moment().day(-30),
289 276
            toDate: moment().day(-1),
290 277
            fromTime: moment({hour: 7}),
291
            toTime: moment({hour: 16})
278
            toTime: moment({hour: 16}),
279
            isTime: true
292 280
        };
293 281
    };
294 282

  
295

  
296 283
    $scope.renderGraphAverageSpeed = function () {
297 284

  
298 285
        let t = $rootScope.selectDevice.traffics.reduce(function (l, r) {
299
            let key = r.timeFrom;
286
            let key = $scope.range.isTime ? r.timeFrom : r.date;
300 287
            if (typeof l[key] === 'undefined') {
301 288
                l[key] = {
302 289
                    numberVehicle: 0,
......
312 299
        }, {});
313 300

  
314 301
        let labels = jQuery.unique($rootScope.selectDevice.traffics.map(function (d) {
315
            return d.timeFrom;
302
            return $scope.range.isTime ? d.timeFrom : moment(d.date, 'YYYY-MM-DD').format('D.M.YYYY');
316 303
        }));
317 304
        let data = Object.values(t).map(function (d) {
318 305
            return Math.round(d.speedSum / d.numberVehicle);
319 306
        });
320 307

  
321

  
322 308
        let canvasGraphAverageSpeed = document.getElementById('graphAverageSpeed').getContext('2d');
323 309

  
324 310
        if ($scope.graphAverageSpeed)
......
336 322
                    backgroundColor: 'rgba(0, 123, 255, 0.3)',
337 323
                    borderColor: 'rgba(0, 123, 255,1)',
338 324
                    cubicInterpolationMode: 'monotone',
339
                    radius: 0
325
                    pointRadius: 0
340 326
                }]
341 327
            },
342 328
            options: {
343 329
                responsive: true,
344 330
                pointDot: false,
331
                legend: {
332
                    display: false
333
                },
345 334
                scales: {
346 335
                    xAxes: [{
347 336
                        ticks: {
......
355 344
                            labelString: 'km/h'
356 345
                        },
357 346
                        ticks: {
358
                            beginAtZero: true
347
                            beginAtZero: true,
348
                            max: Math.max(Math.round((Math.max.apply(null, data) + 10) / 10) * 10, 70)
359 349
                        }
360 350
                    }]
361 351
                },
362 352
                tooltips: {
363
                    enabled: true,
364
                    mode: 'single',
353
                    mode: 'index',
354
                    intersect: false,
365 355
                    callbacks: {
366 356
                        label: function (tooltipItems) {
367 357
                            return tooltipItems.yLabel + ' km/h';
......
380 370

  
381 371

  
382 372
        let labels = jQuery.unique($rootScope.selectDevice.traffics.map(function (d) {
383
            return d.timeFrom;
373
            return $scope.range.isTime ? d.timeFrom : moment(d.date, 'YYYY-MM-DD').format('D.M.YYYY');
384 374
        }));
385 375

  
386 376
        let useVehiclesIds = jQuery.unique($rootScope.selectDevice.traffics.map(function (d) {
......
393 383

  
394 384
        let datasets = [];
395 385
        for (let i = 0, vehicle; vehicle = $scope.filterVehicles[i]; i++) {
396
            if ($scope.typeVehicle == null || $scope.typeVehicle === vehicle.id) {
397
                let dataset = {
398
                    label: vehicle.name,
399
                    backgroundColor: color[vehicle.id].replace("#alpha", "0.3"),
400
                    borderColor: color[vehicle.id].replace("#alpha", "1"),
401
                    borderWidth: 2,
402
                    data: []
403
                };
404

  
405
                let l = 0;
406
                for (let j = 0, traffic; traffic = $rootScope.selectDevice.traffics[j]; j++) {
407
                    if (labels[l] !== traffic.timeFrom) {
408
                        l++;
409
                        if (dataset.data.length < l) {
410
                            dataset.data.push(0);
411
                        }
412
                    }
413
                    if (traffic.typeVehicleId === vehicle.id) {
414
                        dataset.data.push(traffic.numberVehicleAverage);
386
            let dataset = {
387
                label: vehicle.name,
388
                backgroundColor: color[vehicle.id].replace("#alpha", "0.3"),
389
                borderColor: color[vehicle.id].replace("#alpha", "1"),
390
                borderWidth: 2,
391
                data: []
392
            };
393

  
394
            let l = 0;
395
            for (let j = 0, traffic; traffic = $rootScope.selectDevice.traffics[j]; j++) {
396
                if (($scope.range.isTime && labels[l] !== traffic.timeFrom) || (!$scope.range.isTime && labels[l] !== moment(traffic.date, 'YYYY-MM-DD').format('D.M.YYYY'))) {
397
                    l++;
398
                    if (dataset.data.length < l) {
399
                        dataset.data.push(0);
415 400
                    }
416 401
                }
417
                datasets.push(dataset);
402
                if (traffic.typeVehicleId === vehicle.id) {
403
                    dataset.data.push($scope.range.isTime ? traffic.numberVehicleAverage : traffic.numberVehicle);
404
                }
418 405
            }
406
            datasets.push(dataset);
419 407
        }
420 408

  
421 409
        let canvasGraphNumberVehicles = document.getElementById('graphNumberVehicles').getContext('2d');
......
430 418
                datasets: datasets
431 419
            },
432 420
            options: {
433
                tooltips: {
434
                    mode: 'index',
435
                    intersect: false
436
                },
437 421
                responsive: true,
422
                onResize: function (chart, size) {
423
                    chart.options.legend.display = size.height > 240;
424
                    chart.update();
425
                },
426
                legend: {
427
                    position: 'bottom',
428
                },
438 429
                scales: {
439 430
                    xAxes: [{
440 431
                        stacked: true,
......
450 441
                        },
451 442
                        stacked: true
452 443
                    }]
444
                },
445
                tooltips: {
446
                    mode: 'index',
447
                    intersect: false
453 448
                }
454 449
            }
455 450
        });
456 451
    };
457 452

  
458

  
459 453
    $scope.infoClose = function () {
460 454
        $rootScope.selectDevice = null;
461 455

  
......
472 466
app.controller('mapController', function ($rootScope, $scope, config, Device) {
473 467

  
474 468
    this.$onInit = function () {
469
        $scope.markers = [];
475 470

  
476
        $scope.map = new GMaps({
477
            div: '#map',
471
        $scope.map = new google.maps.Map(document.getElementById('map'), {
472
            center: {lat: config.DEFAULT_POSITION.LAT, lng: config.DEFAULT_POSITION.LNG},
473
            zoom: config.DEFAULT_ZOOM,
474
            minZoom: config.DEFAULT_ZOOM_MAX,
478 475
            zoomControl: true,
479 476
            mapTypeControl: false,
480 477
            scaleControl: false,
481 478
            streetViewControl: false,
482 479
            rotateControl: false,
483 480
            fullscreenControl: false,
484
            mapTypeId: 'roadmap',
485
            zoom: config.DEFAULT_ZOOM,
486
            lat: config.DEFAULT_POSITION.LAT,
487
            lng: config.DEFAULT_POSITION.LNG,
488
            // styles: [
489
            //     {
490
            //         featureType: "poi",
491
            //         elementType: "labels",
492
            //         stylers: [{ visibility: "off" }]
493
            //     }
494
            // ]
481
            mapTypeId: google.maps.MapTypeId.ROADMAP
495 482
        });
496 483

  
497 484
        Device.query({showDirection: 0}, function (data) {
......
504 491
        });
505 492
    };
506 493

  
507

  
508 494
    $scope.createMarker = function (lctn) {
509 495
        if (lctn.lat && lctn.lng) {
510
            $scope.map.addMarker({
511
                lat: lctn.lat,
512
                lng: lctn.lng,
496
            let marker = new google.maps.Marker({
497
                map: $scope.map,
498
                position: {lat: lctn.lat, lng: lctn.lng},
513 499
                title: lctn.name,
514
                click: function () {
515
                    $rootScope.$emit('infoLocation', {id: lctn.id});
516
                },
517
                infoWindow: {
500
                infoWindow: new google.maps.InfoWindow({
518 501
                    content: '<h6 class="mb-1">' + lctn.name + '</h6>'
519 502
                    + '<address>' + lctn.street + ', ' + lctn.town + '</address>'
520
                },
503
                }),
521 504
                id: lctn.id
522 505
            });
506

  
507
            marker.addListener('click', function () {
508
                $scope.closeInfoWindows();
509
                marker.infoWindow.open($scope.map, marker);
510
                $rootScope.$emit('infoLocation', {id: lctn.id});
511
            });
512

  
513
            $scope.markers.push(marker);
523 514
        }
524 515
    };
525 516

  
526 517
    $rootScope.$on('activeMarker', function (event, args) {
527 518
        let id = args.id;
528
        for (let i = 0, marker; marker = $scope.map.markers[i]; i++) {
519
        for (let i = 0, marker; marker = $scope.markers[i]; i++) {
529 520
            if (marker.id && marker.id === id && marker.infoWindow) {
530
                $scope.map.setCenter(marker.position.lat(), marker.position.lng());
521
                $scope.map.setCenter(marker.getPosition());
531 522
                $scope.map.setZoom(12);
532
                $scope.map.hideInfoWindows();
533 523
                marker.infoWindow.open($scope.map, marker);
534
                return;
524
            } else {
525
                marker.infoWindow.close();
535 526
            }
536 527
        }
537 528
    });
538 529

  
539 530
    $rootScope.$on('setDefaultMap', function (event, args) {
540
        $scope.map.setCenter(config.DEFAULT_POSITION.LAT, config.DEFAULT_POSITION.LNG);
531
        $scope.map.setCenter({lat: config.DEFAULT_POSITION.LAT, lng: config.DEFAULT_POSITION.LNG});
541 532
        $scope.map.setZoom(config.DEFAULT_ZOOM);
542
        $scope.map.hideInfoWindows();
533
        $scope.closeInfoWindows();
543 534
    });
535

  
536
    $scope.closeInfoWindows = function () {
537
        for (let i = 0, marker; marker = $scope.markers[i]; i++) {
538
            marker.infoWindow.close();
539
        }
540
    };
544 541
});
545 542

  
546 543

  
547 544
app.factory('Device', function ($resource, config) {
548
    return $resource(config.API_URL + '/devices/:id', {id: '@id'}, {
545
    return $resource(config.API_URL + '/devices/:id', {id: '@id', period: '@period'}, {
549 546
        'get': {
550
            url: config.API_URL + '/devices/:id/time-period',
547
            url: config.API_URL + '/devices/:id/:period',
551 548
            method: 'GET',
552 549
            headers: {
553 550
                'Content-Type': 'application/json',

Také k dispozici: Unified diff