Improved individual track selection behaviour.

Added track highlighting and automatic popup on selection.
This commit is contained in:
Atharva Sawant
2024-11-26 16:33:52 +05:30
parent 0613d8c07f
commit 9f25a63c80

View File

@@ -12,6 +12,10 @@ export default {
tracks: { tracks: {
type: Array, type: Array,
default: () => [] default: () => []
},
selectedTrackIndex: {
type: Number,
default: null
} }
}, },
setup(props) { setup(props) {
@@ -48,9 +52,12 @@ export default {
if (!props.tracks || props.tracks.length === 0) return if (!props.tracks || props.tracks.length === 0) return
const allBounds = [] const allBounds = []
let selectedTrackBounds = []
let selectedTrackPopupOpened = false
props.tracks.forEach((track, trackIndex) => { props.tracks.forEach((track, trackIndex) => {
const color = getTrackColor(trackIndex) const color = getTrackColor(trackIndex)
const isSelected = props.selectedTrackIndex === trackIndex
track.segments.forEach(segment => { track.segments.forEach(segment => {
if (segment.points && segment.points.length > 0) { if (segment.points && segment.points.length > 0) {
@@ -58,8 +65,9 @@ export default {
const polyline = L.polyline(latLngs, { const polyline = L.polyline(latLngs, {
color: color, color: color,
weight: 3, weight: isSelected ? 8 : 3,
opacity: 0.8 opacity: isSelected ? 1.0 : 0.6,
zIndexOffset: isSelected ? 1000 : 0
}).bindPopup(` }).bindPopup(`
<div class="font-medium">${track.name}</div> <div class="font-medium">${track.name}</div>
<div class="text-sm text-gray-600 mt-1"> <div class="text-sm text-gray-600 mt-1">
@@ -70,17 +78,54 @@ export default {
`) `)
polyline.addTo(map.value) polyline.addTo(map.value)
trackLayers.value.push(polyline) trackLayers.value.push({ polyline, trackIndex })
// Open popup for selected track (only for first segment)
if (isSelected && !selectedTrackPopupOpened) {
// Find the northernmost point (highest latitude)
const northernmostPoint = latLngs.reduce((north, current) =>
current[0] > north[0] ? current : north
)
// Create popup at northernmost point
const popup = L.popup()
.setLatLng(northernmostPoint)
.setContent(`
<div class="font-medium">${track.name}</div>
<div class="text-sm text-gray-600 mt-1">
Distance: ${(track.stats?.distance / 1000 || 0).toFixed(1)} km<br>
Duration: ${Math.floor((track.stats?.duration || 0) / 3600)}:${Math.floor(((track.stats?.duration || 0) % 3600) / 60).toString().padStart(2, '0')}<br>
Avg Speed: ${track.stats?.avgSpeed || 0} km/h
</div>
`)
.openOn(map.value)
selectedTrackPopupOpened = true
}
// Add bounds for this segment // Add bounds for this segment
allBounds.push(...latLngs) allBounds.push(...latLngs)
// Collect bounds for selected track
if (isSelected) {
selectedTrackBounds.push(...latLngs)
}
} }
}) })
}) })
// Fit map to show all tracks // Focus on selected track if one is selected, otherwise show all tracks
if (allBounds.length > 0) { if (selectedTrackBounds.length > 0) {
const group = new L.featureGroup(trackLayers.value) const selectedGroup = L.latLngBounds(selectedTrackBounds)
// Add extra padding at the top to accommodate popup
// Popup is roughly 80-100px tall, so add more top padding
map.value.fitBounds(selectedGroup, {
paddingTopLeft: [50, 120], // Extra top padding for popup
paddingBottomRight: [50, 50]
})
} else if (allBounds.length > 0) {
const group = new L.featureGroup(trackLayers.value.map(item => item.polyline))
map.value.fitBounds(group.getBounds(), { padding: [20, 20] }) map.value.fitBounds(group.getBounds(), { padding: [20, 20] })
} }
} }
@@ -98,8 +143,9 @@ export default {
renderTracks() renderTracks()
} }
// Watch for track changes // Watch for track changes and selection changes
watch(() => props.tracks, renderTracks, { deep: true }) watch(() => props.tracks, renderTracks, { deep: true })
watch(() => props.selectedTrackIndex, renderTracks)
onMounted(() => { onMounted(() => {
initMap() initMap()