@@ -81,6 +81,14 @@ const props = defineProps({
8181 minimapSelectedColorOpacity: {
8282 type: Number ,
8383 default: 0.2
84+ },
85+ minimapSelectedIndex: {
86+ type: Number ,
87+ default: null
88+ },
89+ minimapIndicatorColor: {
90+ type: String ,
91+ default: ' #2D353C'
8492 }
8593});
8694
@@ -89,7 +97,7 @@ const endValue = ref(props.max);
8997const hasMinimap = computed (() => !! props .minimap .length );
9098const uid = ref (createUid ());
9199
92- const emit = defineEmits ([' update:start' , ' update:end' , ' reset' ]);
100+ const emit = defineEmits ([' update:start' , ' update:end' , ' reset' , ' trapMouse ' ]);
93101
94102const highlightStyle = computed (() => {
95103 const range = props .max - props .min ;
@@ -107,6 +115,14 @@ const backgroundColor = computed(() => props.background);
107115const selectColorOpaque = computed (() => ` ${ props .selectColor } 33` );
108116const borderColor = computed (() => props .borderColor );
109117
118+ const availableTraps = computed (() => {
119+ let arr = [];
120+ for (let i = 0 ; i < props .minimap .length ; i += 1 ) {
121+ arr .push (i)
122+ }
123+ return arr;
124+ })
125+
110126function reset () {
111127 emit (' reset' );
112128}
@@ -175,16 +191,9 @@ onMounted(() => {
175191
176192const unitWidthX = computed (() => {
177193 if (! props .minimap .length ) return 0
178- return svgMinimap .value .width / props .minimap .length ;
194+ return svgMinimap .value .width / props .minimap .length
179195});
180196
181- const selectedMap = computed (() => {
182- return {
183- x: unitWidthX .value * props .valueStart ,
184- width: unitWidthX .value * (props .valueEnd - props .valueStart )
185- }
186- })
187-
188197const minimapLine = computed (() => {
189198 if (! props .minimap .length ) return [];
190199 const max = Math .max (... props .minimap );
@@ -193,7 +202,7 @@ const minimapLine = computed(() => {
193202 const points = props .minimap .map ((dp , i ) => {
194203 const normalizedVal = dp - min;
195204 return {
196- x: svgMinimap .value .width / (props .minimap .length - 1 ) * (i),
205+ x: svgMinimap .value .width / (props .minimap .length ) * (i) + ( unitWidthX . value / 2 ),
197206 y: svgMinimap .value .height - (normalizedVal / diff * (svgMinimap .value .height * 0.9 ))
198207 }
199208 });
@@ -208,12 +217,10 @@ const minimapLine = computed(() => {
208217 }
209218});
210219
211- const range = computed (() => props .max - props .min )
212-
213- const selectionRect = computed (() => {
220+ const selectionRectCoordinates = computed (() => {
214221 return {
215- left : (( startValue .value - props . min ) / range .value ) * 100 ,
216- width: ((endValue .value - startValue .value ) / range . value ) * 100
222+ x : unitWidthX .value * startValue . value + ( unitWidthX .value / 2 ) ,
223+ width: svgMinimap . value . width * ((endValue .value - startValue .value ) / props . max ) - unitWidthX . value
217224 }
218225})
219226
@@ -238,26 +245,42 @@ const rightLabelPosition = computed(() => {
238245 };
239246});
240247
248+
249+ const selectedTrap = ref (props .minimapSelectedIndex )
250+
251+ watch (() => props .minimapSelectedIndex , (v ) => {
252+ selectedTrap .value = v + props .valueStart
253+ }, { immediate: true })
254+
255+ function trapMouse (trap ) {
256+ selectedTrap .value = trap;
257+ if (trap >= props .valueStart && trap < props .valueEnd ) {
258+ emit (' trapMouse' , trap - props .valueStart )
259+ }
260+ }
261+
241262 </script >
242263
243264<template >
244265 <div data-html2canvas-ignore style =" padding : 0 24px " >
245- <div class =" vue-data-ui-slicer-labels" style =" position : relative ; z-index : 1 " >
266+ <div class =" vue-data-ui-slicer-labels" style =" position : relative ; z-index : 1 ; pointer-events : none ; " >
246267 <div v-if =" valueStart > 0 || valueEnd < max" style =" width : 100% ; position : relative " >
247268 <button
248269 v-if =" !useResetSlot"
249270 data-cy-reset tabindex =" 0"
250271 role =" button"
251272 class =" vue-data-ui-refresh-button"
252273 :style =" {
253- top: hasMinimap ? '36px' : '-16px'
274+ top: hasMinimap ? '36px' : '-16px',
275+ pointerEvents: 'all !important'
254276 }"
255277 @click =" reset" >
256278 <BaseIcon name =" refresh" :stroke =" textColor" />
257279 </button >
258280 <slot v-else name =" reset-action" :reset =" reset" />
259281 </div >
260282 </div >
283+
261284 <div class =" double-range-slider" ref =" minimapWrapper" style =" z-index : 0 " >
262285 <template v-if =" hasMinimap " >
263286 <div class =" minimap" style =" width : 100% " >
@@ -268,17 +291,48 @@ const rightLabelPosition = computed(() => {
268291 <stop offset =" 100%" stop-color =" transparent" />
269292 </linearGradient >
270293 </defs >
294+
271295 <path
272- :d =" `M0,${svgMinimap.height} ${ minimapLine.fullSet} L${svgMinimap.width},${svgMinimap.height}Z `"
296+ :d =" `M${ minimapLine.fullSet}`"
273297 :stroke =" `${minimapLineColor}`"
274- : fill =" `url(#${uid})` "
298+ fill =" none "
275299 stroke-width =" 1"
276300 stroke-linecap =" round"
277301 stroke-linejoin =" round"
278302 style =" opacity : 1 "
279303 />
304+
305+ <!-- SELECTION RECT -->
306+ <rect
307+ :x =" selectionRectCoordinates.x"
308+ :width =" selectionRectCoordinates.width < 0 ? 0 : selectionRectCoordinates.width"
309+ :height =" svgMinimap.height"
310+ :y =" 0"
311+ :fill =" borderColor"
312+ :rx =" minimapSelectionRadius"
313+ stroke =" none"
314+ />
315+
316+ <path
317+ :d =" `M${unitWidthX / 2},${svgMinimap.height} ${minimapLine.fullSet} L${svgMinimap.width - (unitWidthX / 2)},${svgMinimap.height}Z`"
318+ :fill =" `url(#${uid})`"
319+ stroke =" none"
320+ style =" opacity : 1 "
321+ />
322+
323+ <rect
324+ :x =" selectionRectCoordinates.x"
325+ :width =" selectionRectCoordinates.width < 0 ? 0 : selectionRectCoordinates.width"
326+ :height =" svgMinimap.height"
327+ :y =" 0"
328+ :fill =" minimapSelectedColor"
329+ :style =" {
330+ opacity: minimapSelectedColorOpacity
331+ }"
332+ />
333+
280334 <!-- This is not quite there yet: there's an annoying offset between input handles and plots -->
281- <!-- < path
335+ <path
282336 :d =" `M ${minimapLine.selectionSet}`"
283337 :stroke =" `${minimapLineColor}`"
284338 fill =" transparent"
@@ -301,34 +355,47 @@ const rightLabelPosition = computed(() => {
301355 :stroke =" borderColor"
302356 r =" 3"
303357 :fill =" minimapLineColor"
304- /> -->
305- <line :x1 =" 0" :x2 =" svgMinimap.width < 0 ? 0 : svgMinimap.width" :y1 =" (svgMinimap.height < 0 ? 0 : svgMinimap.height)" :y2 =" (svgMinimap.height < 0 ? 0 : svgMinimap.height)" :stroke =" borderColor" stroke-width =" 3" />
306- <line :x1 =" 0" :x2 =" 0" :y1 =" 0" :y2 =" svgMinimap.height < 0 ? 0 : svgMinimap.height" :stroke =" borderColor" stroke-width =" 5" />
307- <line :x1 =" svgMinimap.width < 0 ? 0 : svgMinimap.width" :x2 =" svgMinimap.width < 0 ? 0 : svgMinimap.width" :y1 =" 0" :y2 =" svgMinimap.height < 0 ? 0 : svgMinimap.height" :stroke =" borderColor" stroke-width =" 5" />
358+ />
359+
360+ <!-- SELECTION INDICATOR -->
361+ <template v-if =" selectedTrap !== null " >
362+ <g v-for =" (trap, i) in availableTraps" >
363+ <line
364+ :x1 =" unitWidthX * i + (unitWidthX / 2)"
365+ :x2 =" unitWidthX * i + (unitWidthX / 2)"
366+ :y1 =" 0"
367+ :y2 =" svgMinimap.height"
368+ :stroke =" minimapIndicatorColor"
369+ stroke-linecap =" round"
370+ stroke-dasharray =" 2"
371+ stroke-width =" 1"
372+ v-if =" selectedTrap === trap && trap >= valueStart && trap < valueEnd"
373+ />
374+ </g >
375+ </template >
376+
377+ <!-- TOOLTIP TRAPS -->
378+ <rect
379+ v-for =" (trap, i) in availableTraps"
380+ :x =" unitWidthX * i"
381+ :y =" 0"
382+ :height =" svgMinimap.height"
383+ :width =" unitWidthX"
384+ fill =" transparent"
385+ style =" pointer-events : all !important ;"
386+ @mouseenter =" trapMouse(trap)"
387+ @mouseleave =" selectedTrap = null; emit('trapMouse', null)"
388+ />
308389 </svg >
309390 </div >
310- <div
311- class =" sel"
312- :style =" {
313- position: 'absolute',
314- top: '-33px',
315- left: `calc(${selectionRect.left}%)`,
316- background: minimapSelectedColor,
317- height: '40px',
318- width: selectionRect.width + '%',
319- borderRadius: `${minimapSelectionRadius}px ${minimapSelectionRadius}px 0 0`,
320- opacity: minimapSelectedColorOpacity
321- }"
322- />
323391 </template >
324-
325392 <div class =" slider-track" ></div >
326393 <div class =" range-highlight" :style =" highlightStyle" ></div >
327- <input type =" range" :min =" min" :max =" max" v-model =" startValue" @input =" onStartInput" />
394+ <input type =" range" class = " range-left " :min =" min" :max =" max" v-model =" startValue" @input =" onStartInput" />
328395 <div class =" thumb-label thumb-label-left" :style =" leftLabelPosition" >
329396 {{ labelLeft }}
330397 </div >
331- <input type =" range" :min =" min" :max =" max" v-model =" endValue" @input =" onEndInput" />
398+ <input type =" range" class = " range-right " :min =" min" :max =" max" v-model =" endValue" @input =" onEndInput" />
332399 <div class =" thumb-label thumb-label-right" :style =" rightLabelPosition" >
333400 {{ labelRight }}
334401 </div >
@@ -359,8 +426,9 @@ const rightLabelPosition = computed(() => {
359426
360427input [type = " range" ] {
361428 position : absolute ;
362- left : 0 ;
363- width : 100% ;
429+ left : -10px ;
430+ width : calc (100% + 17px );
431+ right : 3px ;
364432 appearance : none ;
365433 background : transparent ;
366434 pointer-events : none ;
@@ -471,7 +539,7 @@ input[type="range"]::-ms-thumb {
471539 display : flex ;
472540 flex-direction : row ;
473541 align-items : center ;
474- padding : 0 24px ;
542+ // padding: 0 24px;
475543 height : 40px ;
476544}
477545
0 commit comments