Improved individual track selection behaviour.
Added track highlighting and automatic popup on selection.
This commit is contained in:
@@ -12,6 +12,10 @@ export default {
|
||||
tracks: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
selectedTrackIndex: {
|
||||
type: Number,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
@@ -48,9 +52,12 @@ export default {
|
||||
if (!props.tracks || props.tracks.length === 0) return
|
||||
|
||||
const allBounds = []
|
||||
let selectedTrackBounds = []
|
||||
let selectedTrackPopupOpened = false
|
||||
|
||||
props.tracks.forEach((track, trackIndex) => {
|
||||
const color = getTrackColor(trackIndex)
|
||||
const isSelected = props.selectedTrackIndex === trackIndex
|
||||
|
||||
track.segments.forEach(segment => {
|
||||
if (segment.points && segment.points.length > 0) {
|
||||
@@ -58,8 +65,9 @@ export default {
|
||||
|
||||
const polyline = L.polyline(latLngs, {
|
||||
color: color,
|
||||
weight: 3,
|
||||
opacity: 0.8
|
||||
weight: isSelected ? 8 : 3,
|
||||
opacity: isSelected ? 1.0 : 0.6,
|
||||
zIndexOffset: isSelected ? 1000 : 0
|
||||
}).bindPopup(`
|
||||
<div class="font-medium">${track.name}</div>
|
||||
<div class="text-sm text-gray-600 mt-1">
|
||||
@@ -70,17 +78,54 @@ export default {
|
||||
`)
|
||||
|
||||
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
|
||||
allBounds.push(...latLngs)
|
||||
|
||||
// Collect bounds for selected track
|
||||
if (isSelected) {
|
||||
selectedTrackBounds.push(...latLngs)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// Fit map to show all tracks
|
||||
if (allBounds.length > 0) {
|
||||
const group = new L.featureGroup(trackLayers.value)
|
||||
// Focus on selected track if one is selected, otherwise show all tracks
|
||||
if (selectedTrackBounds.length > 0) {
|
||||
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] })
|
||||
}
|
||||
}
|
||||
@@ -98,8 +143,9 @@ export default {
|
||||
renderTracks()
|
||||
}
|
||||
|
||||
// Watch for track changes
|
||||
// Watch for track changes and selection changes
|
||||
watch(() => props.tracks, renderTracks, { deep: true })
|
||||
watch(() => props.selectedTrackIndex, renderTracks)
|
||||
|
||||
onMounted(() => {
|
||||
initMap()
|
||||
|
||||
Reference in New Issue
Block a user