Projekt

Obecné

Profil

Stáhnout (16.9 KB) Statistiky
| Větev: | Revize:
1 8feb1753 ballakt
/* global L */
2
/* global $ */
3 2f227a6c ballakt
4 8feb1753 ballakt
var mymap
5
var heatmapLayer = null
6
var marksLayer = null
7 03c02899 vastja
8 8feb1753 ballakt
var startX = 49.7248
9
var startY = 13.3521
10
var startZoom = 17
11 3fc08f2d vastja
12 8feb1753 ballakt
var dataSourceRoute
13 1cf1413d ballakt
let positionsSourceRoute
14 8feb1753 ballakt
var currentTime
15 a48642fb vastja
16 8feb1753 ballakt
var timer
17
var isAnimationRunning = false
18
var data = []
19 a48642fb vastja
20 70a3df53 vastja
var info = []
21 2f227a6c ballakt
let currentInfo = 0
22
23 883a423e Tomáš Ballák
const datasetDictNameDisplayName = {}
24 2f227a6c ballakt
var datasetSelected = []
25 70a3df53 vastja
26 8feb1753 ballakt
const globalMarkersHolder = {}
27 d5a88af0 Tomáš Ballák
// all marker from which popup was removed
28
// contains: {key:[L.circle,L.pupup]}
29
// key: x and y, x + '' + y string
30
let globalMarkersChanged = {}
31 084a5972 ballakt
32 c892003d Martin Sebela
33 2f227a6c ballakt
const fetchByNameDate = async (baseRoute, name, date, currentTime) => {
34
  const headers = new Headers()
35
  const myRequest = new Request(baseRoute + '/' + name + '/' + date + '/' + currentTime, {
36
    method: 'GET',
37
    headers: headers
38
  })
39
  const beforeJson = await fetch(myRequest)
40
  return beforeJson.json()
41
}
42 c892003d Martin Sebela
43
44 2f227a6c ballakt
const fetchDataSourceMarks = async (positionRoute, datasetName) => {
45
  const headers = new Headers()
46
  const myRequest = new Request(positionRoute + '/' + datasetName, {
47
    method: 'GET',
48
    headers: headers
49
  })
50
  const beforeJson = await fetch(myRequest)
51
  return beforeJson.json()
52
}
53 084a5972 ballakt
54 c892003d Martin Sebela
55 2f227a6c ballakt
const genPopUpControlButtons = (currentPage, numPages, onNextClick, onPreviousClick) => ({
56
  previousButton: '<button id="previous-info-btn" class="circle-button" onclick="previousInfo()"></button>',
57 c892003d Martin Sebela
  nextButton: '<button id="next-info-btn" class="circle-button next" onclick="nextInfo()"></button>',
58 2f227a6c ballakt
  posInfo: `<div id="count-info">${currentPage} z ${numPages}</div>`
59
})
60 c892003d Martin Sebela
61
62 084a5972 ballakt
const genPopUpControls = (controls) => {
63 2f227a6c ballakt
  return `<div class="popup-controls">${controls ? controls.reduce((sum, item) => sum + item, '') : ''}</div>`
64 084a5972 ballakt
}
65 c892003d Martin Sebela
66
67 883a423e Tomáš Ballák
const genMultipleDatasetsPopUp = (sum, currentPos, maxPos, datasetName) => {
68 c892003d Martin Sebela
  const popupHeader = `<strong id="dataset-info">${datasetName}</strong>`
69
  const popupData = `<div id="number-info"><span id="digit-info">${sum}</span></div>`
70 2f227a6c ballakt
  const { previousButton, nextButton, posInfo } = genPopUpControlButtons(currentPos, maxPos)
71 c892003d Martin Sebela
72 2f227a6c ballakt
  return `
73 c892003d Martin Sebela
  ${popupHeader}
74
  ${popupData}
75 2f227a6c ballakt
  ${genPopUpControls([previousButton, posInfo, nextButton])}
76
  `
77
}
78 c892003d Martin Sebela
79
80 2f227a6c ballakt
const prepareLayerPopUp = (lat, lng, num, className) => L.popup({
81
  autoPan: false,
82
  className: className
83
}).setLatLng([lat / num, lng / num])
84
85 c892003d Martin Sebela
86 bb2d43b5 Martin Sebela
const genPopUp = (datasetName, place, count, sum, currentPos, maxPos) => {
87
  const popupHeader = `
88
    <strong>${datasetName}</strong>
89
    <div id="place-info">${place}</div>`
90
  const popupData = `
91
    <div id="number-info">
92
      <span id="digit-info">${count}</span>
93
      <span id="total-info">${(sum && (sum != count)) ? '/' + sum : ''}</span>
94
    </div>`
95 2f227a6c ballakt
  const { previousButton, nextButton, posInfo } = genPopUpControlButtons(currentPos, maxPos)
96 bb2d43b5 Martin Sebela
97 084a5972 ballakt
  return `
98 bb2d43b5 Martin Sebela
  ${popupHeader}
99
  ${popupData}
100 2f227a6c ballakt
  ${genPopUpControls(maxPos > 1 ? [previousButton, posInfo, nextButton] : null)}
101 084a5972 ballakt
  `
102
}
103 c892003d Martin Sebela
104
105 1cf1413d ballakt
const onCheckboxClicked = async (checkbox) => {
106
  if ($(checkbox).prop('checked')) {
107
    loadCurrentTimeHeatmap(dataSourceRoute, positionsSourceRoute)
108
    changeUrl()
109 c892003d Martin Sebela
  }
110
  else {
111 1cf1413d ballakt
    loadCheckboxDatasetNameData()
112 c892003d Martin Sebela
113 1cf1413d ballakt
    data.forEach((item, index) => {
114
      Object.keys(item).forEach((datasetName) => {
115
        if (datasetName === $(checkbox).val()) {
116
          delete data[index][datasetName]
117
        }
118
      })
119
      drawHeatmap(data[currentTime])
120
    })
121 c892003d Martin Sebela
122 1cf1413d ballakt
    changeUrl()
123
  }
124
}
125 c892003d Martin Sebela
126
127 1cf1413d ballakt
const debounce = (func, delay) => {
128
  let inDebounce
129
  return function () {
130
    const context = this
131
    const args = arguments
132
    clearTimeout(inDebounce)
133
    inDebounce = setTimeout(() => func.apply(context, args), delay)
134
  }
135
}
136 bb2d43b5 Martin Sebela
137 c892003d Martin Sebela
138 1cf1413d ballakt
const onValueChangeRegister = () => {
139
  $('#date').change(function () {
140
    data = []
141
    loadCurrentTimeHeatmap(dataSourceRoute, positionsSourceRoute)
142
    const date = new Date($(this).val())
143
    $('#player-date').html(`${date.getDate()}. ${date.getMonth() + 1}. ${date.getFullYear()}`)
144 bb2d43b5 Martin Sebela
    changeUrl()
145 1cf1413d ballakt
  })
146 bb2d43b5 Martin Sebela
147 c892003d Martin Sebela
  $('#dropdown-time input[type="radio"]').each(function () {
148 1cf1413d ballakt
    $(this).change(function () {
149 94c6eb49 Martin Sebela
      currentTime = parseInt($(this).val())
150 1cf1413d ballakt
      updateHeaderControls()
151
      setTimeline()
152
      drawHeatmap(data[currentTime])
153 bb2d43b5 Martin Sebela
      changeUrl()
154 1cf1413d ballakt
    })
155
  })
156 bb2d43b5 Martin Sebela
157 c892003d Martin Sebela
  $('#dropdown-dataset input[type="checkbox"]').each(function () {
158 1cf1413d ballakt
    $(this).change(
159
      debounce(() => onCheckboxClicked(this), 1000)
160
    )
161
  })
162
}
163 bb2d43b5 Martin Sebela
164 c892003d Martin Sebela
165 70a3df53 vastja
/**
166
 * Initialize leaflet map on start position which can be default or set based on user action
167
 */
168 8feb1753 ballakt
// eslint-disable-next-line no-unused-vars
169
function initMap () {
170 90d3db28 Tomáš Ballák
  startX = localStorage.getItem('lat') || startX
171
  startY = localStorage.getItem('lng') || startY
172
  startZoom = localStorage.getItem('zoom') || startZoom
173 72a438f3 vastja
174 8feb1753 ballakt
  mymap = L.map('heatmap').setView([startX, startY], startZoom)
175 3fc08f2d vastja
176 c236b33a msebela
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
177
    attribution: '',
178
    maxZoom: 19
179 8feb1753 ballakt
  }).addTo(mymap)
180 3ae59f75 vastja
181 8feb1753 ballakt
  mymap.on('click', showInfo)
182 c236b33a msebela
}
183 c892003d Martin Sebela
184
185 2f227a6c ballakt
const getInfoLength = () => {
186
  const infoKeys = Object.keys(info)
187
  if (infoKeys.length === 1) {
188
    // return number of records in one dataset (one dataset in area)
189
    return info[infoKeys[0]].items.length
190
  }
191
  // return number of datasets (agregation of all datasets in area)
192
  return infoKeys.length
193
}
194 c892003d Martin Sebela
195
196 2f227a6c ballakt
const getElFromObjectInfo = (position) => {
197
  const keys = Object.keys(info)
198
  return info[keys[position]]
199
}
200 c892003d Martin Sebela
201
202 2f227a6c ballakt
const hasInfoMultipleDatasets = () => {
203
  return Object.keys(info).length > 1
204
}
205 c892003d Martin Sebela
206
207 8feb1753 ballakt
function showInfo (e) {
208 3ae59f75 vastja
  info = []
209 2f227a6c ballakt
  currentInfo = 0
210 3ae59f75 vastja
211
  // https://wiki.openstreetmap.org/wiki/Zoom_levels
212
  // Todo change to variable - it is used in heatmap init
213 2f227a6c ballakt
  const stile = 40075016.686 * Math.cos(startX) / Math.pow(2, mymap.getZoom())
214
  const radius = 25 * stile / 256
215
216
  let i = 0
217
  let lat = 0
218
  let lng = 0
219
220
  let total = 0
221
222
  const datasetsInRadius = {}
223
224
  Object.keys(data[currentTime]).forEach((key) => {
225
    const namedData = data[currentTime][key]
226
    namedData.items.forEach(element => {
227
      if (e.latlng.distanceTo(new L.LatLng(element.x, element.y)) < radius) {
228
        lat += element.x
229
        lng += element.y
230
        info[i] = { place: element.place, number: element.number, datasetName: key }
231
        total += parseInt(element.number)
232
        i++
233
        datasetsInRadius[key] = true
234
      }
235
    })
236 8feb1753 ballakt
  })
237 3ae59f75 vastja
238 2f227a6c ballakt
  // Process info for more then one dataset
239 8feb1753 ballakt
240 2f227a6c ballakt
  info = info.reduce((acc, item) => {
241
    if (!acc[item.datasetName]) {
242
      acc[item.datasetName] = {
243
        items: [],
244
        number: 0,
245
        datasetName: item.datasetName
246
      }
247
    }
248 c892003d Martin Sebela
249 2f227a6c ballakt
    acc[item.datasetName].items.push(item)
250
    acc[item.datasetName].number += Number(item.number)
251
    return acc
252
  }, {})
253
254
  // There is one dataset
255
256
  const numDatasets = Object.keys(datasetsInRadius).length
257
258 d5a88af0 Tomáš Ballák
  if (!numDatasets) {
259
    return
260
  }
261 2f227a6c ballakt
262
  if (numDatasets === 1) {
263
    const infoDict = getElFromObjectInfo(0)
264
    const info_ = infoDict.items
265
    const { place, number } = info_[currentInfo]
266
    prepareLayerPopUp(lat, lng, i, `popup-${infoDict.datasetName}`)
267 883a423e Tomáš Ballák
      .setContent(genPopUp(datasetDictNameDisplayName[infoDict.datasetName], place, number, total, currentInfo + 1, info_.length))
268 2f227a6c ballakt
      .openOn(mymap)
269 c892003d Martin Sebela
270 2f227a6c ballakt
    if (info_.length === 1) {
271 8feb1753 ballakt
      $('#previous-info-btn').prop('disabled', true)
272
      $('#next-info-btn').prop('disabled', true)
273
      $('.popup-controls').hide()
274 3ae59f75 vastja
    }
275 c892003d Martin Sebela
  }
276
  else {
277 2f227a6c ballakt
    const { datasetName, number } = getElFromObjectInfo(currentInfo)
278 c892003d Martin Sebela
279 2f227a6c ballakt
    prepareLayerPopUp(lat, lng, i, `popup-${datasetName}`)
280 883a423e Tomáš Ballák
      .setContent(genMultipleDatasetsPopUp(number, currentInfo + 1, getInfoLength(), datasetDictNameDisplayName[datasetName]))
281 2f227a6c ballakt
      .openOn(mymap)
282 3ae59f75 vastja
  }
283
}
284
285 c892003d Martin Sebela
286 8feb1753 ballakt
// eslint-disable-next-line no-unused-vars
287
function previousInfo () {
288 2f227a6c ballakt
  const infoLength = getInfoLength()
289
  const previousCurrentInfo = currentInfo
290 c892003d Martin Sebela
291 2f227a6c ballakt
  currentInfo = (currentInfo + infoLength - 1) % infoLength
292
  displayInfoText(previousCurrentInfo)
293 3ae59f75 vastja
}
294
295 c892003d Martin Sebela
296 8feb1753 ballakt
// eslint-disable-next-line no-unused-vars
297
function nextInfo () {
298 2f227a6c ballakt
  const infoLength = getInfoLength()
299
  const previousCurrentInfo = currentInfo
300 c892003d Martin Sebela
301 2f227a6c ballakt
  currentInfo = (currentInfo + 1) % infoLength
302
  displayInfoText(previousCurrentInfo)
303 3ae59f75 vastja
}
304 c892003d Martin Sebela
305
306 2f227a6c ballakt
function displayInfoText (previousInfoNum) {
307
  const previousInfo = hasInfoMultipleDatasets() ? getElFromObjectInfo(previousInfoNum) : getElFromObjectInfo(0).items[previousInfoNum]
308
  const info_ = hasInfoMultipleDatasets() ? getElFromObjectInfo(currentInfo) : getElFromObjectInfo(0).items[currentInfo]
309
  const infoLength = getInfoLength()
310 883a423e Tomáš Ballák
  const datasetInfo = $('#dataset-info')
311 c892003d Martin Sebela
312 883a423e Tomáš Ballák
  if (datasetInfo) {
313
    $(datasetInfo).html(datasetDictNameDisplayName[info_.datasetName])
314
  }
315 c892003d Martin Sebela
  
316 2f227a6c ballakt
  $('#place-info').html(info_.place ? info_.place : info_.datasetName)
317
  $('#digit-info').html(info_.number)
318
  $('#count-info').html(currentInfo + 1 + ' z ' + infoLength)
319 c892003d Martin Sebela
320 2f227a6c ballakt
  $('.leaflet-popup').removeClass(`popup-${previousInfo.datasetName}`)
321
  $('.leaflet-popup').addClass(`popup-${info_.datasetName}`)
322 3ae59f75 vastja
}
323 351696d5 Martin Sebela
324 c892003d Martin Sebela
325 8feb1753 ballakt
// eslint-disable-next-line no-unused-vars
326 72a438f3 vastja
function setMapView (latitude, longitude, zoom) {
327 90d3db28 Tomáš Ballák
  localStorage.setItem('lat', latitude)
328
  localStorage.setItem('lng', longitude)
329
  localStorage.setItem('zoom', zoom)
330 8feb1753 ballakt
  mymap.setView([latitude, longitude], zoom)
331 3fc08f2d vastja
}
332
333 c892003d Martin Sebela
334 70a3df53 vastja
/**
335
 * Change animation start from playing to stopped or the other way round
336
 */
337 8feb1753 ballakt
// eslint-disable-next-line no-unused-vars
338
function changeAnimationState () {
339 a48642fb vastja
  isAnimationRunning = !isAnimationRunning
340 c892003d Martin Sebela
341 a48642fb vastja
  if (isAnimationRunning) {
342 8feb1753 ballakt
    $('#play-pause').attr('class', 'pause')
343 c892003d Martin Sebela
    timer = setInterval(function() { next() }, 800)
344
  }
345
  else {
346 8feb1753 ballakt
    clearTimeout(timer)
347
    $('#play-pause').attr('class', 'play')
348 351696d5 Martin Sebela
  }
349
}
350
351 c892003d Martin Sebela
352 8feb1753 ballakt
// eslint-disable-next-line no-unused-vars
353
function previous () {
354
  currentTime = (currentTime + 23) % 24
355
  drawHeatmap(data[currentTime])
356
  setTimeline()
357
  mymap.closePopup()
358
  updateHeaderControls()
359
  changeUrl()
360 a48642fb vastja
}
361
362 c892003d Martin Sebela
363 8feb1753 ballakt
function next () {
364
  currentTime = (currentTime + 1) % 24
365
  drawHeatmap(data[currentTime])
366
  setTimeline()
367
  mymap.closePopup()
368
  updateHeaderControls()
369
  changeUrl()
370 8b840eb7 vastja
}
371 c892003d Martin Sebela
372
373 70a3df53 vastja
/**
374 c892003d Martin Sebela
 * Change browser url based on animation step.
375 70a3df53 vastja
 */
376 8feb1753 ballakt
function changeUrl () {
377 8b840eb7 vastja
  window.history.pushState(
378 8feb1753 ballakt
    '',
379 8b840eb7 vastja
    document.title,
380 c892003d Martin Sebela
    window.location.origin + window.location.pathname + `?date=${$('#date').val()}&time=${currentTime}${datasetSelected.reduce((acc, current) => acc + '&type=' + current, '')}`
381 8feb1753 ballakt
  )
382 4e8c0e5b Martin Sebela
}
383
384 c892003d Martin Sebela
385 8feb1753 ballakt
function updateHeaderControls () {
386 1cf1413d ballakt
  $(`#time_${currentTime}`).prop('checked', true)
387 bb2d43b5 Martin Sebela
  $('#dropdownMenuButtonTime').html((currentTime < 10 ? '0' : '') + `${currentTime}:00`)
388 a48642fb vastja
}
389 351696d5 Martin Sebela
390 c892003d Martin Sebela
391 8feb1753 ballakt
function setTimeline () {
392
  $('#timeline').text(currentTime + ':00')
393
  $('#timeline').attr('class', 'time hour-' + currentTime)
394 351696d5 Martin Sebela
}
395
396 c892003d Martin Sebela
397
function changeHour(hour) {
398
  currentTime = hour
399
  updateHeaderControls()
400
  setTimeline()
401
  drawHeatmap(data[currentTime])
402
  changeUrl()
403
}
404
405
406 70a3df53 vastja
/**
407
 * Load and display heatmap layer for current data
408
 * @param {string} opendataRoute route to dataset source
409
 * @param {string} positionsRoute  route to dataset postitions source
410
 */
411 8feb1753 ballakt
// eslint-disable-next-line no-unused-vars
412 2f227a6c ballakt
async function loadCurrentTimeHeatmap (opendataRoute, positionsRoute) {
413 1cf1413d ballakt
  loadCheckboxDatasetNameData()
414 c892003d Martin Sebela
415 8feb1753 ballakt
  dataSourceRoute = opendataRoute
416 1cf1413d ballakt
  positionsSourceRoute = positionsRoute
417 2f227a6c ballakt
  const dataSourceMarks = {}
418
  const allPromises = []
419
  const date = $('#date').val()
420 c892003d Martin Sebela
  currentTime = parseInt($('#dropdown-time input[type="radio"]:checked').val())
421 1cf1413d ballakt
422 8feb1753 ballakt
  setTimeline()
423 2f227a6c ballakt
  data[currentTime] = {}
424
  const dataSelectedHandler = async (datasetName) => {
425
    const marks = await fetchDataSourceMarks(positionsRoute, datasetName)
426
    const datasetData = await fetchByNameDate(dataSourceRoute, datasetName, date, currentTime)
427
    dataSourceMarks[datasetName] = marks
428
    data[currentTime][datasetName] = datasetData
429
  }
430 c892003d Martin Sebela
431 2f227a6c ballakt
  await datasetSelected.forEach((datasetName) => {
432
    allPromises.push(dataSelectedHandler(datasetName))
433 8feb1753 ballakt
  })
434 c892003d Martin Sebela
435 2f227a6c ballakt
  Promise.all(allPromises).then(
436
    () => {
437
      drawDataSourceMarks(dataSourceMarks)
438
      drawHeatmap(data[currentTime])
439
      preload(currentTime, 1, date)
440
      preload(currentTime, -1, date)
441
    }
442
  )
443 a48642fb vastja
}
444
445 c892003d Martin Sebela
446 8feb1753 ballakt
function drawDataSourceMarks (data) {
447 61ff7718 vastja
  if (marksLayer != null) {
448 1cf1413d ballakt
    mymap.removeLayer(marksLayer)
449 61ff7718 vastja
  }
450 c892003d Martin Sebela
451 8feb1753 ballakt
  marksLayer = L.layerGroup()
452 c892003d Martin Sebela
453 2f227a6c ballakt
  Object.keys(data).forEach((key_) => {
454
    for (var key in data[key_]) {
455
      const { x, y, name } = data[key_][key]
456
      const pop =
457
          prepareLayerPopUp(x, y, 1, `popup-${key_}`)
458 883a423e Tomáš Ballák
            .setContent(genPopUp(datasetDictNameDisplayName[key_], name, 0, 0, 1, 1))
459 2f227a6c ballakt
      const newCircle =
460
        L.circle([x, y], { radius: 2, fillOpacity: 0.8, color: '#004fb3', fillColor: '#004fb3', bubblingMouseEvents: true })
461
          .bindPopup(pop)
462
      globalMarkersHolder[x + '' + y] = [newCircle, pop] // add new marker to global holders
463
      marksLayer.addLayer(
464
        newCircle
465
      )
466
    }
467
  })
468 61ff7718 vastja
469 8feb1753 ballakt
  marksLayer.setZIndex(-1).addTo(mymap)
470 61ff7718 vastja
}
471
472 c892003d Martin Sebela
473 2f227a6c ballakt
async function preload (time, change, date) {
474
  for (let nTime = time + change; nTime >= 0 && nTime <= 23; nTime = nTime + change) {
475
    if (!data[nTime]) {
476
      data[nTime] = {}
477
    }
478 c892003d Martin Sebela
479 1cf1413d ballakt
    datasetSelected.forEach(async (datasetName) => {
480
      if (!data[nTime][datasetName]) {
481
        data[nTime][datasetName] = await fetchByNameDate(dataSourceRoute, datasetName, date, nTime)
482
      }
483
    })
484 a48642fb vastja
  }
485 3fc08f2d vastja
}
486
487 c892003d Martin Sebela
488 2f227a6c ballakt
function drawHeatmap (dataRaw) {
489 03c02899 vastja
  // Todo still switched
490 2f227a6c ballakt
  const dataDict = dataRaw
491
  const mergedPoints = []
492
  let max = 0
493 c892003d Martin Sebela
  
494 d5a88af0 Tomáš Ballák
  if (Object.keys(globalMarkersChanged).length) {
495
    Object.keys(globalMarkersChanged).forEach(function (key) {
496
      globalMarkersChanged[key][0].bindPopup(globalMarkersChanged[key][1])
497
    })
498
    globalMarkersChanged = {}
499
  }
500 c892003d Martin Sebela
501 2f227a6c ballakt
  Object.keys(dataDict).forEach((key) => {
502
    const data = dataDict[key]
503
    max = Math.max(max, data.max)
504 c892003d Martin Sebela
505 2f227a6c ballakt
    if (data != null) {
506 8feb1753 ballakt
    // Bind back popups for markers (we dont know if there is any data for this marker or not)
507 2f227a6c ballakt
      const points = data.items.map((point) => {
508
        const { x, y, number } = point
509
        const key = x + '' + y
510
        const holder = globalMarkersHolder[key]
511 c892003d Martin Sebela
512 2f227a6c ballakt
        if (!globalMarkersChanged[key] && number) {
513 8feb1753 ballakt
        // There is data for this marker => unbind popup with zero value
514 2f227a6c ballakt
          holder[0] = holder[0].unbindPopup()
515
          globalMarkersChanged[key] = holder
516
        }
517 c892003d Martin Sebela
518 2f227a6c ballakt
        return [x, y, number]
519
      })
520
      mergedPoints.push(...points)
521 c892003d Martin Sebela
    }
522
    else {
523 2f227a6c ballakt
      if (heatmapLayer != null) {
524
        mymap.removeLayer(heatmapLayer)
525 084a5972 ballakt
      }
526 a48642fb vastja
    }
527 2f227a6c ballakt
  })
528 c892003d Martin Sebela
529 2f227a6c ballakt
  if (heatmapLayer != null) {
530
    mymap.removeLayer(heatmapLayer)
531
  }
532 c892003d Martin Sebela
533 2f227a6c ballakt
  if (mergedPoints.length) {
534
    heatmapLayer = L.heatLayer(mergedPoints, { max: max, minOpacity: 0.5, radius: 35, blur: 30 }).addTo(mymap)
535 a48642fb vastja
  }
536 03c02899 vastja
}
537 3fc08f2d vastja
538 c892003d Martin Sebela
539 70a3df53 vastja
/**
540
 * Checks dataset availibility
541 81980e82 ballakt
 * @param {string} route authority for datasets availibility checks
542 70a3df53 vastja
 */
543 8feb1753 ballakt
// eslint-disable-next-line no-unused-vars
544
function checkDataSetsAvailability (route) {
545 03c02899 vastja
  $.ajax({
546 8feb1753 ballakt
    type: 'POST',
547 03c02899 vastja
    // Todo it might be good idea to change db collections format
548 03ccdd65 vastja
    url: route + '/' + $('#date').val(),
549 8feb1753 ballakt
    success: function (result) {
550
      updateAvailableDataSets(result)
551 03c02899 vastja
    }
552 8feb1753 ballakt
  })
553 03c02899 vastja
}
554
555 c892003d Martin Sebela
556 8feb1753 ballakt
function updateAvailableDataSets (available) {
557 2f227a6c ballakt
  let leastOneOptionEnabled = false
558
  // datasetSelected = []
559 c892003d Martin Sebela
560
  $('#dropdown-dataset .dropdown-item').each(function () {
561 2f227a6c ballakt
    const input = $(this).find('input')
562
    const inputVal = input[0].value
563 c892003d Martin Sebela
564 2f227a6c ballakt
    if (!(inputVal in available)) {
565
      $(this).addClass('disabled')
566
      $(input).prop('checked', false)
567 c892003d Martin Sebela
    }
568
    else {
569 2f227a6c ballakt
      leastOneOptionEnabled = true
570
      $(this).removeClass('disabled')
571 5d599617 vastja
    }
572 8feb1753 ballakt
  })
573 dfe43218 vastja
574 94c6eb49 Martin Sebela
  $('#btn-update-heatmap').prop('disabled', !leastOneOptionEnabled)
575 03c02899 vastja
}
576 0a828a5a Martin Sebela
577 c892003d Martin Sebela
578 8feb1753 ballakt
function formatDate (date) {
579
  var day = String(date.getDate())
580
  var month = String(date.getMonth() + 1)
581 0a828a5a Martin Sebela
582
  if (day.length === 1) {
583 8feb1753 ballakt
    day = '0' + day
584 0a828a5a Martin Sebela
  }
585
586
  if (month.length === 1) {
587 8feb1753 ballakt
    month = '0' + month
588 0a828a5a Martin Sebela
  }
589
590 8feb1753 ballakt
  return date.getFullYear() + '-' + month + '-' + day
591 0a828a5a Martin Sebela
}
592
593 c892003d Martin Sebela
594 8feb1753 ballakt
// eslint-disable-next-line no-unused-vars
595
function initDatepicker (availableDatesSource) {
596
  var availableDates = ''
597 0a828a5a Martin Sebela
598
  $.ajax({
599
    type: 'GET',
600
    url: availableDatesSource,
601 8feb1753 ballakt
    success: function (result) {
602
      availableDates = String(result).split(',')
603 0a828a5a Martin Sebela
    }
604 a7e04778 Martin Sebela
  }).then(function () {
605
    $('#date').datepicker({
606
      format: 'yyyy-mm-dd',
607
      language: 'cs',
608 8feb1753 ballakt
      beforeShowDay: function (date) {
609 a7e04778 Martin Sebela
        if (availableDates.indexOf(formatDate(date)) < 0) {
610 8feb1753 ballakt
          return { enabled: false, tooltip: 'Žádná data' }
611 c892003d Martin Sebela
        }
612
        else {
613 8feb1753 ballakt
          return { enabled: true }
614 a7e04778 Martin Sebela
        }
615
      },
616
      autoclose: true
617 8feb1753 ballakt
    })
618
  })
619
}
620 dd652e61 Martin Sebela
621 c892003d Martin Sebela
622 81980e82 ballakt
function initLocationsMenu () {
623
  var locationsWrapper = '.locations'
624
  var locationsDisplayClass = 'show'
625 dd652e61 Martin Sebela
626 81980e82 ballakt
  if ($(window).width() <= 480) {
627
    $(locationsWrapper).removeClass(locationsDisplayClass)
628 c892003d Martin Sebela
  }
629
  else {
630 81980e82 ballakt
    $(locationsWrapper).addClass(locationsDisplayClass)
631 dd652e61 Martin Sebela
  }
632 4e003182 Martin Sebela
}
633
634 c892003d Martin Sebela
635 81980e82 ballakt
function openDatepicker () {
636 4e003182 Martin Sebela
  if ($(window).width() <= 990) {
637 81980e82 ballakt
    $('.navbar-collapse').collapse()
638 4e003182 Martin Sebela
  }
639
640
  $('#date').datepicker('show')
641 81980e82 ballakt
}
642 c892003d Martin Sebela
643
644 2f227a6c ballakt
function onDocumentReady () {
645 c892003d Martin Sebela
  $('#dropdown-dataset').on('click', function (e) {
646 2f227a6c ballakt
    e.stopPropagation()
647
  })
648 1cf1413d ballakt
649 94c6eb49 Martin Sebela
  $('#btn-update-heatmap').prop('name', '')
650 1cf1413d ballakt
  onValueChangeRegister()
651
}
652 c892003d Martin Sebela
653
654 1cf1413d ballakt
const loadCheckboxDatasetNameData = () => {
655 2f227a6c ballakt
  datasetSelected = []
656 c892003d Martin Sebela
  $('#dropdown-dataset .dropdown-item').each(function () {
657 2f227a6c ballakt
    const input = $(this).find('input')
658
    const inputVal = input[0].value
659 c892003d Martin Sebela
660 2f227a6c ballakt
    if (input[0].checked) {
661
      datasetSelected.push(inputVal)
662
    }
663 c892003d Martin Sebela
664 883a423e Tomáš Ballák
    datasetDictNameDisplayName[inputVal] = $(input).data('dataset-display-name')
665 2f227a6c ballakt
  })
666
}