JSFiddle - React, Tailwind, and code Playground
by Tonio Loewald
HTML
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/v1.4.1/mapbox-gl.css">
<script src="https://api.mapbox.com/mapbox-gl-js/v1.4.1/mapbox-gl.js"></script>
<div id="layout">
<div id="map">
</div>
<div id="data">
</div>
</div>
<img...
CSS
* {
box-sizing: border-box;
font-family: Sans-serif;
}
th, td {
padding: 4px 8px;
}
#layout {
display: flex;
height: 400px;
width: 100%;
flex-direction: row;
position: relative;
}
#data {
position: relative;
overflow: scroll;
overflow: overlay;
}
#layout > * {
flex: 0 0 50%;
height: 400px;
}
table {
border-collapse: collapse;
}
tr:not(.header):hover {
height: var(--row-height);
background: #eee;
}
.picked {
background: #ddd;
}
.header {
background: #222;
color: white;
}
/*
fixed header over scrolling table content
*/
.header:nth-child(1) {
position: fixed;
}
/*
duplicate header row for column metrics, but hidden
*/
.header:nth-child(2) {
visibility: hidden;
}
JavaScript
(async () => {
const [long, lat, zoom] = [38.2641789,-120.5922877,2]
mapboxgl.accessToken = 'pk.eyJ1IjoicG9kcGVyc29uIiwiYSI6ImNqc2JlbWU0bjA1ZmY0YW5ycHZod3VhbWcifQ.arvqfpOqMgFYkKgQ35UScA'
const map = new mapboxgl.Map({
container: document.getElementById('map'),
style: 'mapbox://styles/mapbox/outdoors-v10',
zoom,
center: [lat, long],
})
const flameMarker = document.querySelector('img')
flameMarker.remove()
flameMarker.style.display = ''
const response = await fetch('http://api.511.org/transit/VehicleMonitoring?api_key=0b552e16-e64a-4ac4-99b3-141fc3e99c74&agency=SF')
const vehicles = reponse.json().Siri.ServiceDelivery.VehicleMonitoringDelivery.VehicleActivity
const header = Object.keys(vehicles[0])
const rowMarkerMap = []
const tr = (data, cols, elementType='td', className) => {
const tr = document.createElement('tr')
if (className) tr.classList.add(className)
filtered = cols ? cols.map(i => data[i]) : data
filtered.forEach(datum => {
const elt = document.createElement(elementType)
elt.textContent = datum
tr.append(elt)
})
return tr
}
const cols = [0, 1, 8]
const table = document.createElement('table')
table.append(tr(header, cols, 'th', 'header'))
table.append(tr(header, cols, 'th', 'header'))
rows.forEach((row, i) => {
const rowElt = tr(row, cols)
table.append(rowElt)
// const red = Math.floor(parseFloat(row[8]) * 2.55)
const element = flameMarker.cloneNode(true)
element.style.opacity = parseFloat(row[8] * 0.01)
const marker = new mapboxgl.Marker({
// color: `rgb(${red},0,0)`,
element
})
.setLngLat([row[1], row[0]])
.addTo(map);
rowMarkerMap.push({
rowElt,
markerElt: marker._element
})
})
document.getElementById('data').append(table)
map.on('click', (e) => {
const elt = e.originalEvent.target.closest('.mapboxgl-marker')
const rowElt = (rowMarkerMap.find(x => x.markerElt === elt)...