@ -1,9 +1,10 @@
< template >
< template >
< el -dialog
< el -dialog
class = "trajectory-dialog-wrapper"
: title = "dialogTitle"
: title = "dialogTitle"
: visible . sync = "dialogVisible"
: visible . sync = "dialogVisible"
width = "88 %"
width = "94 %"
top = "4 vh"
top = "1 vh"
custom - class = "trajectory-dialog"
custom - class = "trajectory-dialog"
append - to - body
append - to - body
@ open = "handleOpen"
@ open = "handleOpen"
@ -72,8 +73,9 @@
< div
< div
class = "trajectory-map-shell"
class = "trajectory-map-shell"
: class = "{ 'is-empty': !loading && !mapLoading && !loadError && !trajectoryPoints.length }"
v - loading = "loading || mapLoading"
v - loading = "loading || mapLoading"
: style = "{ minH eight: mapPanelHeight + 'px' }"
: style = "{ h eight: mapPanelHeight + 'px' }"
>
>
< el -empty
< el -empty
v - if = "!loading && !mapLoading && !loadError && !trajectoryPoints.length"
v - if = "!loading && !mapLoading && !loadError && !trajectoryPoints.length"
@ -115,7 +117,7 @@
{ { scope . row . address || "-" } }
{ { scope . row . address || "-" } }
< / template >
< / template >
< / e l - t a b l e - c o l u m n >
< / e l - t a b l e - c o l u m n >
< el -table -column :label ="$t('device.trajectory.table.battery')" prop = "battery" width = "100" align = "center" / >
<!-- < el -table -column :label ="$t('device.trajectory.table.battery')" prop = "battery" width = "100" align = "center" / > -- >
< / e l - t a b l e >
< / e l - t a b l e >
< / e l - t a b - p a n e >
< / e l - t a b - p a n e >
< / e l - t a b s >
< / e l - t a b s >
@ -132,27 +134,27 @@ import { loadAMap } from "@/utils/loadAMap";
import { loadGoogleMaps } from "@/utils/loadGoogleMaps" ;
import { loadGoogleMaps } from "@/utils/loadGoogleMaps" ;
import { loadLeaflet } from "@/utils/loadLeaflet" ;
import { loadLeaflet } from "@/utils/loadLeaflet" ;
/ / 轨 迹 点 未 加 载 前 , 各 地 图 默 认 中 心 点 。
/ / D e f a u l t m a p c e n t e r s b e f o r e t r a j e c t o r y p o i n t s l o a d .
const AMAP_DEFAULT_CENTER = [ 121.4737 , 31.2304 ] ;
const AMAP_DEFAULT_CENTER = [ 121.4737 , 31.2304 ] ;
const GOOGLE_DEFAULT_CENTER = { lat : 31.2304 , lng : 121.4737 } ;
const GOOGLE_DEFAULT_CENTER = { lat : 31.2304 , lng : 121.4737 } ;
const LEAFLET_DEFAULT_CENTER = [ 31.2304 , 121.4737 ] ;
const LEAFLET_DEFAULT_CENTER = [ 31.2304 , 121.4737 ] ;
/ / 各 地 图 默 认 / 详 情 缩 放 级 别 。
/ / D e t a i l z o o m l e v e l s .
const AMAP_FALLBACK_MAX_ZOOM = 17 ;
const AMAP_FALLBACK_MAX_ZOOM = 17 ;
const GOOGLE_DETAIL_ZOOM = 16 ;
const GOOGLE_DETAIL_ZOOM = 16 ;
const LEAFLET_MAX_ZOOM = 16 ;
const LEAFLET_MAX_ZOOM = 16 ;
const LEAFLET_GOOGLE_MAX_ZOOM = 17 ;
const LEAFLET_GOOGLE_MAX_ZOOM = 17 ;
/ / L e a f l e t + G o o g l e 瓦 片 地 址 与 轨 迹 线 样 式 。
/ / L e a f l e t G o o g l e t i l e a n d t r a j e c t o r y s t y l e s .
const LEAFLET_GOOGLE_TILE_URL = "https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}" ;
const LEAFLET_GOOGLE_TILE_URL = "https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}" ;
const LEAFLET_LINE_ARROW_MAX = 36 ;
const LEAFLET_LINE_ARROW_MAX = 36 ;
const LEAFLET_SHOW_LINE_ARROWS = false ;
const LEAFLET_SHOW_LINE_ARROWS = false ;
const LEAFLET_TRAJECTORY_LINE_COLOR = "#1a73e8" ;
const LEAFLET_TRAJECTORY_LINE_COLOR = "#1a73e8" ;
/ / 坐 标 转 换 与 渲 染 数 量 上 限 。
/ / C o o r d i n a t e c o n v e r s i o n b a t c h s i z e .
const CONVERT_BATCH_SIZE = 500 ;
const CONVERT_BATCH_SIZE = 500 ;
const TRAJECTORY_MAP_HEIGHT = 560 ;
/ / 轨 迹 压 缩 阈 值 ( 用 于 减 少 长 时 间 停 留 产 生 的 密 集 点 ) 。
const TRAJECTORY_TABLE_HEIGHT = 520 ;
export default {
export default {
name : "DeviceTrajectoryDialog" ,
name : "DeviceTrajectoryDialog" ,
@ -185,6 +187,7 @@ export default {
mapConfig : null ,
mapConfig : null ,
locationTimeRange : [ ] ,
locationTimeRange : [ ] ,
viewportHeight : typeof window !== "undefined" ? window . innerHeight : 900 ,
viewportHeight : typeof window !== "undefined" ? window . innerHeight : 900 ,
dialogWrapperEl : null ,
} ;
} ;
} ,
} ,
computed : {
computed : {
@ -212,15 +215,20 @@ export default {
return ! ! ( this . mapConfig && this . mapConfig . maptilerKey ) ;
return ! ! ( this . mapConfig && this . mapConfig . maptilerKey ) ;
} ,
} ,
mapPanelHeight ( ) {
mapPanelHeight ( ) {
return Math . min ( 460 , Math . max ( 280 , this . viewportHeight - 640 ) ) ;
return TRAJECTORY_MAP_HEIGHT ;
} ,
} ,
tableMaxHeight ( ) {
tableMaxHeight ( ) {
return Math . min ( 420 , Math . max ( 220 , this . viewportHeight - 660 ) ) ;
return TRAJECTORY_TABLE_HEIGHT ;
} ,
} ,
} ,
} ,
beforeDestroy ( ) {
this . unbindViewportResize ( ) ;
this . unbindDialogWrapper ( ) ;
} ,
methods : {
methods : {
async handleOpen ( ) {
async handleOpen ( ) {
this . bindViewportResize ( ) ;
this . bindViewportResize ( ) ;
this . bindDialogWrapper ( ) ;
this . activePanel = "map" ;
this . activePanel = "map" ;
this . initDefaultLocationTimeRange ( ) ;
this . initDefaultLocationTimeRange ( ) ;
if ( ! this . device || ! this . device . id ) {
if ( ! this . device || ! this . device . id ) {
@ -240,6 +248,7 @@ export default {
} ,
} ,
handleClose ( ) {
handleClose ( ) {
this . unbindViewportResize ( ) ;
this . unbindViewportResize ( ) ;
this . unbindDialogWrapper ( ) ;
this . destroyMap ( true ) ;
this . destroyMap ( true ) ;
this . activePanel = "map" ;
this . activePanel = "map" ;
this . mapProvider = "amap" ;
this . mapProvider = "amap" ;
@ -255,6 +264,24 @@ export default {
window . addEventListener ( "resize" , this . handleViewportResize ) ;
window . addEventListener ( "resize" , this . handleViewportResize ) ;
}
}
} ,
} ,
bindDialogWrapper ( ) {
this . $nextTick ( ( ) => {
const dialog = document . querySelector ( ".trajectory-dialog" ) ;
const wrapper = dialog && dialog . closest ? dialog . closest ( ".el-dialog__wrapper" ) : null ;
if ( ! wrapper ) {
return ;
}
this . dialogWrapperEl = wrapper ;
wrapper . classList . add ( "trajectory-dialog-wrapper" ) ;
} ) ;
} ,
unbindDialogWrapper ( ) {
if ( ! this . dialogWrapperEl ) {
return ;
}
this . dialogWrapperEl . classList . remove ( "trajectory-dialog-wrapper" ) ;
this . dialogWrapperEl = null ;
} ,
unbindViewportResize ( ) {
unbindViewportResize ( ) {
if ( typeof window !== "undefined" ) {
if ( typeof window !== "undefined" ) {
window . removeEventListener ( "resize" , this . handleViewportResize ) ;
window . removeEventListener ( "resize" , this . handleViewportResize ) ;
@ -286,18 +313,15 @@ export default {
await this . renderCurrentProviderMap ( ) ;
await this . renderCurrentProviderMap ( ) ;
} ,
} ,
resolveDefaultProvider ( ) {
resolveDefaultProvider ( ) {
if ( this . hasGoogleKey ) {
if ( this . hasAmapKey ) {
return "google" ;
}
if ( this . hasAmapKey ) {
return "amap" ;
return "amap" ;
}
}
if ( this . hasMaptilerKey ) {
if ( this . hasMaptilerKey ) {
return "maptiler" ;
return "maptiler" ;
}
}
if ( this . hasGoogleKey ) {
return "google" ;
}
return "amap" ;
return "amap" ;
} ,
} ,
initDefaultLocationTimeRange ( ) {
initDefaultLocationTimeRange ( ) {
@ -368,7 +392,7 @@ export default {
} ;
} ;
} ) ;
} ) ;
this . totalTrajectoryCount = normalizedPoints . length ;
this . totalTrajectoryCount = normalizedPoints . length ;
this . trajectoryPoints = normalizedPoints ;
this . trajectoryPoints = this . sortTrajectoryByTime ( normalizedPoints ) ;
} catch ( error ) {
} catch ( error ) {
this . trajectoryPoints = [ ] ;
this . trajectoryPoints = [ ] ;
this . totalTrajectoryCount = 0 ;
this . totalTrajectoryCount = 0 ;
@ -522,6 +546,12 @@ export default {
const startItem = mapPoints [ 0 ] ;
const startItem = mapPoints [ 0 ] ;
const endItem = mapPoints [ mapPoints . length - 1 ] ;
const endItem = mapPoints [ mapPoints . length - 1 ] ;
this . markers = [ ] ;
this . markers = [ ] ;
mapPoints . forEach ( ( item ) => {
const marker = this . createLeafletTrackPointMarker ( item ) ;
if ( marker ) {
this . markers . push ( marker ) ;
}
} ) ;
if ( path . length > 1 ) {
if ( path . length > 1 ) {
const startAngle = this . getLeafletDirectionAngle ( path [ 0 ] , path [ 1 ] ) ;
const startAngle = this . getLeafletDirectionAngle ( path [ 0 ] , path [ 1 ] ) ;
@ -560,8 +590,27 @@ export default {
this . markers . push ( startMarker ) ;
this . markers . push ( startMarker ) ;
}
}
const latestPoint = path [ path . length - 1 ] ;
this . refreshLeafletViewport ( path ) ;
this . map . setView ( latestPoint , LEAFLET_MAX_ZOOM ) ;
} ,
createLeafletTrackPointMarker ( point ) {
if ( ! point || point . latNum === null || point . lngNum === null ) {
return null ;
}
const marker = this . mapsApi . circleMarker ( [ point . latNum , point . lngNum ] , {
radius : 4 ,
color : "#ffffff" ,
weight : 1 ,
fillColor : LEAFLET_TRAJECTORY_LINE_COLOR ,
fillOpacity : 0.92 ,
} ) ;
marker . addTo ( this . map ) ;
marker . bindTooltip ( this . escapeHtml ( this . getPointTrackTime ( point ) ) , {
permanent : true ,
direction : "top" ,
offset : [ 0 , - 6 ] ,
className : "leaflet-trajectory-point-tooltip" ,
} ) ;
return marker ;
} ,
} ,
createLeafletDirectionMarker ( point , angle , shortLabel , color , timeLabel , timeText ) {
createLeafletDirectionMarker ( point , angle , shortLabel , color , timeLabel , timeText ) {
const icon = this . mapsApi . divIcon ( {
const icon = this . mapsApi . divIcon ( {
@ -826,7 +875,15 @@ export default {
const startItem = mapPoints [ 0 ] ;
const startItem = mapPoints [ 0 ] ;
const endItem = mapPoints [ mapPoints . length - 1 ] ;
const endItem = mapPoints [ mapPoints . length - 1 ] ;
this . markers = [
this . markers = [ ] ;
mapPoints . forEach ( ( item ) => {
const marker = this . createAmapTrackPointMarker ( item ) ;
if ( marker ) {
this . markers . push ( marker ) ;
}
} ) ;
this . markers . push (
new this . mapsApi . Marker ( {
new this . mapsApi . Marker ( {
position : startPoint ,
position : startPoint ,
content : this . buildAmapMarkerContent (
content : this . buildAmapMarkerContent (
@ -835,8 +892,9 @@ export default {
this . getPointTrackTime ( startItem )
this . getPointTrackTime ( startItem )
) ,
) ,
offset : new this . mapsApi . Pixel ( - 44 , - 52 ) ,
offset : new this . mapsApi . Pixel ( - 44 , - 52 ) ,
} ) ,
zIndex : 120 ,
] ;
} )
) ;
if ( path . length > 1 ) {
if ( path . length > 1 ) {
this . markers . push (
this . markers . push (
@ -848,6 +906,7 @@ export default {
this . getPointTrackTime ( endItem )
this . getPointTrackTime ( endItem )
) ,
) ,
offset : new this . mapsApi . Pixel ( - 44 , - 52 ) ,
offset : new this . mapsApi . Pixel ( - 44 , - 52 ) ,
zIndex : 120 ,
} )
} )
) ;
) ;
}
}
@ -855,13 +914,89 @@ export default {
this . map . add ( this . polyline ) ;
this . map . add ( this . polyline ) ;
this . map . add ( this . markers ) ;
this . map . add ( this . markers ) ;
/ / 多 点 : 自 动 适 配 全 貌
this . refreshAmapViewport ( path ) ;
if ( path . length > 1 ) {
} ,
this . map . setFitView ( [ this . polyline ] . concat ( this . markers ) , false , [ 60 , 60 , 60 , 60 ] ) ;
refreshLeafletViewport ( path ) {
} else {
if ( ! this . map || this . mapVendor !== "leaflet" || ! this . mapsApi || ! Array . isArray ( path ) || ! path . length ) {
/ / 单 点 : 给 一 个 适 中 的 细 节 级 别
return ;
this . map . setZoomAndCenter ( 16 , startPoint ) ;
}
}
const applyView = ( ) => {
if ( path . length > 1 && typeof this . map . fitBounds === "function" ) {
const bounds = this . mapsApi . latLngBounds ( path ) ;
this . map . fitBounds ( bounds , {
padding : [ 24 , 24 ] ,
maxZoom : LEAFLET_MAX_ZOOM ,
} ) ;
} else if ( path [ 0 ] ) {
this . map . setView ( path [ 0 ] , LEAFLET_MAX_ZOOM ) ;
}
} ;
this . $nextTick ( ( ) => {
if ( typeof this . map . invalidateSize === "function" ) {
this . map . invalidateSize ( ) ;
}
applyView ( ) ;
[ 180 , 420 ] . forEach ( ( delay ) => {
setTimeout ( ( ) => {
if ( this . mapVendor !== "leaflet" || ! this . map || ! this . dialogVisible ) {
return ;
}
if ( typeof this . map . invalidateSize === "function" ) {
this . map . invalidateSize ( ) ;
}
applyView ( ) ;
} , delay ) ;
} ) ;
} ) ;
} ,
refreshAmapViewport ( path ) {
if ( ! this . map || this . mapVendor !== "amap" || ! Array . isArray ( path ) || ! path . length ) {
return ;
}
const applyView = ( ) => {
if ( path . length > 1 ) {
this . map . setFitView ( [ this . polyline ] . concat ( this . markers ) , false , [ 60 , 60 , 60 , 60 ] ) ;
} else {
this . map . setZoomAndCenter ( 16 , path [ 0 ] ) ;
}
} ;
this . $nextTick ( ( ) => {
if ( typeof this . map . resize === "function" ) {
this . map . resize ( ) ;
}
applyView ( ) ;
setTimeout ( ( ) => {
if ( this . mapVendor !== "amap" || ! this . map || ! this . dialogVisible ) {
return ;
}
if ( typeof this . map . resize === "function" ) {
this . map . resize ( ) ;
}
applyView ( ) ;
} , 180 ) ;
} ) ;
} ,
createAmapTrackPointMarker ( point ) {
if ( ! point ) {
return null ;
}
const lng = point . amapLng !== undefined ? point . amapLng : point . lngNum ;
const lat = point . amapLat !== undefined ? point . amapLat : point . latNum ;
if ( ! Number . isFinite ( Number ( lng ) ) || ! Number . isFinite ( Number ( lat ) ) ) {
return null ;
}
return new this . mapsApi . Marker ( {
position : [ Number ( lng ) , Number ( lat ) ] ,
content :
'<div style="display:flex;flex-direction:column;align-items:center;gap:4px;">' +
'<span style="width:8px;height:8px;border-radius:999px;background:#1a73e8;border:1px solid #fff;box-shadow:0 0 0 1px rgba(26,115,232,0.32);display:block;"></span>' +
'<span style="padding:1px 6px;border-radius:10px;background:rgba(255,255,255,0.96);border:1px solid #dbeafe;color:#1f2937;font-size:11px;line-height:1.2;white-space:nowrap;">' +
this . escapeHtml ( this . getPointTrackTime ( point ) ) +
"</span>" +
"</div>" ,
offset : new this . mapsApi . Pixel ( - 20 , - 20 ) ,
zIndex : 60 ,
} ) ;
} ,
} ,
renderGoogleTrajectory ( ) {
renderGoogleTrajectory ( ) {
if ( ! this . map || ! this . mapsApi || ! this . trajectoryPoints . length ) {
if ( ! this . map || ! this . mapsApi || ! this . trajectoryPoints . length ) {
@ -905,46 +1040,79 @@ if (path.length > 1) {
const startItem = mapPoints [ 0 ] ;
const startItem = mapPoints [ 0 ] ;
const endItem = mapPoints [ mapPoints . length - 1 ] ;
const endItem = mapPoints [ mapPoints . length - 1 ] ;
this . markers = [
this . markers = [ ] ;
mapPoints . forEach ( ( item , index ) => {
if ( index === 0 || index === mapPoints . length - 1 ) {
return ;
}
const pointMarker = this . createGoogleTrackPointMarker (
{ lat : item . latNum , lng : item . lngNum } ,
this . getPointTrackTime ( item )
) ;
if ( pointMarker ) {
this . markers . push ( pointMarker ) ;
}
} ) ;
this . markers . push (
new this . mapsApi . Marker ( {
new this . mapsApi . Marker ( {
position : startPoint ,
position : startPoint ,
map : this . map ,
map : this . map ,
label : this . $t ( "device.trajectory.marker.startShort" ) ,
label : {
} ) ,
text : ` ${ this . $t ( "device.trajectory.marker.startShort" ) } ${ this . getPointTrackTime ( startItem ) } ` ,
] ;
color : "#166534" ,
fontSize : "11px" ,
fontWeight : "600" ,
} ,
} )
) ;
if ( path . length > 1 ) {
if ( path . length > 1 ) {
this . markers . push (
this . markers . push (
new this . mapsApi . Marker ( {
new this . mapsApi . Marker ( {
position : endPoint ,
position : endPoint ,
map : this . map ,
map : this . map ,
label : this . $t ( "device.trajectory.marker.endShort" ) ,
label : {
text : ` ${ this . $t ( "device.trajectory.marker.endShort" ) } ${ this . getPointTrackTime ( endItem ) } ` ,
color : "#b91c1c" ,
fontSize : "11px" ,
fontWeight : "600" ,
} ,
} )
} )
) ;
) ;
}
}
const startInfoWindow = this . openGoogleMarkerInfoWindow (
if ( path . length > 1 && this . mapsApi . LatLngBounds ) {
this . markers [ 0 ] ,
const bounds = new this . mapsApi . LatLngBounds ( ) ;
this . $t ( "device.trajectory.message.startTime" ) ,
path . forEach ( ( point ) => bounds . extend ( point ) ) ;
this . getPointTrackTime ( startItem )
this . map . fitBounds ( bounds ) ;
) ;
} else {
if ( startInfoWindow ) {
this . map . setCenter ( endPoint ) ;
this . markerInfoWindows . push ( startInfoWindow ) ;
this . map . setZoom ( GOOGLE_DETAIL_ZOOM ) ;
}
}
} ,
if ( this . markers . length > 1 ) {
createGoogleTrackPointMarker ( position , labelText ) {
const endInfoWindow = this . openGoogleMarkerInfoWindow (
if ( ! this . mapsApi || ! position ) {
this . markers [ this . markers . length - 1 ] ,
return null ;
this . $t ( "device.trajectory.message.endTime" ) ,
this . getPointTrackTime ( endItem )
) ;
if ( endInfoWindow ) {
this . markerInfoWindows . push ( endInfoWindow ) ;
}
}
}
return new this . mapsApi . Marker ( {
this . map . setCenter ( endPoint ) ;
position ,
this . map . setZoom ( GOOGLE_DETAIL_ZOOM ) ;
map : this . map ,
icon : {
path : this . mapsApi . SymbolPath . CIRCLE ,
scale : 4 ,
fillColor : LEAFLET_TRAJECTORY_LINE_COLOR ,
fillOpacity : 1 ,
strokeColor : "#ffffff" ,
strokeWeight : 1 ,
} ,
label : {
text : String ( labelText || "-" ) ,
color : "#1f2937" ,
fontSize : "11px" ,
fontWeight : "500" ,
} ,
} ) ;
} ,
} ,
openGoogleMarkerInfoWindow ( marker , title , timeText ) {
openGoogleMarkerInfoWindow ( marker , title , timeText ) {
if ( ! this . mapsApi || ! this . map || ! marker || ! this . mapsApi . InfoWindow ) {
if ( ! this . mapsApi || ! this . map || ! marker || ! this . mapsApi . InfoWindow ) {
@ -1096,16 +1264,36 @@ if (path.length > 1) {
if ( ! Array . isArray ( this . trajectoryPoints ) || ! this . trajectoryPoints . length ) {
if ( ! Array . isArray ( this . trajectoryPoints ) || ! this . trajectoryPoints . length ) {
return [ ] ;
return [ ] ;
}
}
const mapPoints = this . trajectoryPoints . filter ( ( item ) => item . latNum !== null && item . lngNum !== null ) ;
return this . trajectoryPoints . filter ( ( item ) => item . latNum !== null && item . lngNum !== null ) ;
if ( mapPoints . length < 2 ) {
} ,
return mapPoints ;
sortTrajectoryByTime ( points ) {
}
if ( ! Array . isArray ( points ) || points . length < 2 ) {
const firstTime = this . getTrackTimestamp ( mapPoints [ 0 ] ) ;
return Array . isArray ( points ) ? points . slice ( ) : [ ] ;
const lastTime = this . getTrackTimestamp ( mapPoints [ mapPoints . length - 1 ] ) ;
}
if ( firstTime > 0 && lastTime > 0 && firstTime > lastTime ) {
return points
return mapPoints . slice ( ) . reverse ( ) ;
. map ( ( item , index ) => ( {
}
item ,
return mapPoints ;
index ,
timestamp : this . getTrackTimestamp ( item ) ,
} ) )
. sort ( ( a , b ) => {
const aHasTime = a . timestamp > 0 ;
const bHasTime = b . timestamp > 0 ;
if ( aHasTime && bHasTime ) {
if ( a . timestamp === b . timestamp ) {
return a . index - b . index ;
}
return a . timestamp - b . timestamp ;
}
if ( aHasTime ) {
return - 1 ;
}
if ( bHasTime ) {
return 1 ;
}
return a . index - b . index ;
} )
. map ( ( entry ) => entry . item ) ;
} ,
} ,
getTrackTimestamp ( point ) {
getTrackTimestamp ( point ) {
if ( ! point ) {
if ( ! point ) {
@ -1161,16 +1349,21 @@ if (path.length > 1) {
. trajectory - map - shell {
. trajectory - map - shell {
position : relative ;
position : relative ;
min - height : 280 px ;
border : 1 px solid # ebeef5 ;
border : 1 px solid # ebeef5 ;
border - radius : 8 px ;
border - radius : 8 px ;
overflow : hidden ;
overflow : hidden ;
background : # f5f7fa ;
background : # f5f7fa ;
}
}
. trajectory - map - shell . is - empty {
display : flex ;
align - items : center ;
justify - content : center ;
}
. trajectory - map {
. trajectory - map {
width : 100 % ;
width : 100 % ;
height : 280 px ;
height : 100 % ;
}
}
. trajectory - map - disclaimer {
. trajectory - map - disclaimer {
@ -1189,21 +1382,56 @@ if (path.length > 1) {
box - shadow : 0 2 px 8 px rgba ( 0 , 0 , 0 , 0.12 ) ;
box - shadow : 0 2 px 8 px rgba ( 0 , 0 , 0 , 0.12 ) ;
}
}
. trajectory - dialog {
: deep ( . leaflet - trajectory - point - tooltip ) {
margin - top : 4 vh ! important ;
background : rgba ( 255 , 255 , 255 , 0.96 ) ;
margin - bottom : 4 vh ;
border : 1 px solid # dbeafe ;
max - height : 90 vh ;
border - radius : 10 px ;
color : # 1 f2937 ;
font - size : 11 px ;
font - weight : 500 ;
padding : 1 px 6 px ;
box - shadow : 0 2 px 8 px rgba ( 15 , 23 , 42 , 0.15 ) ;
}
}
. trajectory - dialog . el - dialog__body {
: deep ( . leaflet - trajectory - point - tooltip : : before ) {
max - height : calc ( 90 vh - 120 px ) ;
border - top - color : # dbeafe ! important ;
overflow : hidden ;
}
< / style >
< style >
. trajectory - dialog - wrapper {
overflow : hidden ! important ;
}
. trajectory - dialog - wrapper . trajectory - dialog : not ( . is - fullscreen ) {
margin - top : 10 px ! important ;
margin - bottom : 10 px ;
height : 900 px ;
max - height : 900 px ;
}
. trajectory - dialog - wrapper . trajectory - dialog . el - dialog__body {
max - height : calc ( 900 px - 114 px ) ! important ;
overflow - y : auto ! important ;
overflow - x : hidden ! important ;
padding - top : 10 px ;
padding - top : 10 px ;
padding - bottom : 10 px ;
padding - bottom : 10 px ;
}
}
. trajectory - dialog . el - dialog__footer {
. trajectory - dialog - wrapper . trajectory - dialog . el - dialog__footer {
padding - top : 10 px ;
padding - top : 10 px ;
padding - bottom : 14 px ;
padding - bottom : 14 px ;
}
}
@ media ( max - height : 900 px ) {
. trajectory - dialog - wrapper . trajectory - dialog : not ( . is - fullscreen ) {
height : calc ( 100 vh - 20 px ) ;
max - height : calc ( 100 vh - 20 px ) ;
}
. trajectory - dialog - wrapper . trajectory - dialog . el - dialog__body {
max - height : calc ( 100 vh - 134 px ) ! important ;
}
}
< / style >
< / style >