-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathindex.js
More file actions
124 lines (95 loc) · 4.09 KB
/
index.js
File metadata and controls
124 lines (95 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
(function() {
const createTilemap = json => {
return new Promise((resolve, reject) => {
try {
const xmlns = 'http://www.w3.org/2000/svg'
const size = 50
const gap = 2
const counties = [...new Set(json.map(d => d.county_ru))]
const svg = document.createElementNS(xmlns, 'svg')
svg.setAttributeNS(null, 'viewbox', `0 0 ${size * 17} ${size * 10}`)
svg.setAttributeNS(null, 'preserveAspectRatio', 'xMidYMid meet')
json.forEach(tile => {
const { id, code, lat, lon, label, name_ru, county_ru } = tile
const countyIndex = counties.sort().findIndex(d => d === county_ru)
const rect = document.createElementNS(xmlns, 'rect')
rect.setAttributeNS(null, 'width', size - gap)
rect.setAttributeNS(null, 'height', size - gap)
rect.classList.add(`county-${countyIndex}`)
rect.classList.add('region')
rect.dataset.id = id
rect.dataset.code = code
rect.dataset.region = name_ru
rect.dataset.county = county_ru
const text = document.createElementNS(xmlns, 'text')
text.setAttributeNS(null, 'x', size / 2 - gap / 2)
text.setAttributeNS(null, 'y', size / 5 * 3 - gap / 2)
text.textContent = label
const region = document.createElementNS(xmlns, 'g')
region.setAttributeNS(null, 'transform', `matrix(1 0 0 1 ${lon * size} ${lat * size})`)
region.setAttributeNS(null, 'text-anchor', 'middle')
region.setAttributeNS(null, 'font-family', 'sans-serif')
region.setAttributeNS(null, 'font-size', size / 4)
region.appendChild(rect)
region.appendChild(text)
svg.appendChild(region)
})
resolve(svg)
} catch (error) {
reject(error)
}
})
}
const getTable = dataset => {
const table = document.createElement('table')
for (key in dataset) {
if (key === 'id') continue
const name = document.createElement('td')
name.innerText = key
const value = document.createElement('td')
value.innerText = dataset[key]
const row = document.createElement('tr')
row.appendChild(name)
row.appendChild(value)
table.appendChild(row)
}
return table
}
const handlerOver = popup => {
return event => {
const { target } = event
if (!target.classList.contains('region')) return
const table = getTable(target.dataset)
popup.appendChild(table)
const popupRect = popup.getBoundingClientRect()
const regionRect = target.getBoundingClientRect()
const x = regionRect.left
const y = regionRect.top - popupRect.height
popup.style.transform = `translate(${x}px, ${y}px)`
popup.classList.add('active')
}
}
const handlerOut = popup => {
return () => {
popup.classList.remove('active')
popup.innerHTML = null
}
}
const start = async url => {
try {
const response = await fetch(url)
const json = await response.json()
const tilemap = await createTilemap(json)
const popup = document.createElement('div')
popup.classList.add('popup')
tilemap.addEventListener('mouseover', handlerOver(popup), false)
tilemap.addEventListener('mouseout', handlerOut(popup), false)
const body = document.querySelector('body')
body.appendChild(tilemap)
body.appendChild(popup)
} catch (error) {
console.error(error)
}
}
start('tilemap.json')
})()