From efacbde3d8a6a2c04c5ae466232f235c4ac37ef7 Mon Sep 17 00:00:00 2001 From: Felix Schmenger Date: Thu, 22 Feb 2024 17:27:52 +0100 Subject: [PATCH 1/5] Fix dangling tooltip behavior: Hide the currently displayed tooltip and cancel out pending timers, when the mouse leaves the map-canvas. --- src/components/ol/HoverController.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/ol/HoverController.js b/src/components/ol/HoverController.js index 6d4a06af..0dca5921 100644 --- a/src/components/ol/HoverController.js +++ b/src/components/ol/HoverController.js @@ -40,6 +40,15 @@ export default class HoverController { me.onPointerRest(event); }, timeout); }); + + // If the mouse leaves the map canvas, clear out the "pointer rest" timer and hide + // the existing tooltip. + map.getViewport().addEventListener('mouseout', (event) => { + if (me.timerHandle) { + clearTimeout(me.timerHandle); + } + me.displayTooltip(null); + }, false); } /** From 0f8c80c8ebeb25abbe3f1d52e846229a826261b7 Mon Sep 17 00:00:00 2001 From: Felix Schmenger Date: Thu, 22 Feb 2024 18:11:10 +0100 Subject: [PATCH 2/5] Introduce a global configuration property mapHover to customize hover tooltip behavior. --- src/components/ol/HoverController.js | 23 ++++++++++++++++------- src/components/ol/Map.vue | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/components/ol/HoverController.js b/src/components/ol/HoverController.js index 0dca5921..b82b8a1b 100644 --- a/src/components/ol/HoverController.js +++ b/src/components/ol/HoverController.js @@ -4,13 +4,18 @@ import VectorSource from 'ol/source/Vector'; import VectorTileSource from 'ol/source/VectorTile'; import WMSGetFeatureInfo from 'ol/format/WMSGetFeatureInfo'; import { WguEventBus } from '../../WguEventBus'; +import ObjectUtil from '../../util/Object'; import axios from 'axios'; export default class HoverController { - DEFAULT_POINTER_REST_INTERVAL = 150; - DEFAULT_HOVER_OVERLAY = 'wgu-hover-tooltip'; + DEFAULT_OPTIONS = { + delay: 150, + hideOnMousemove: false, + hoverOverlay: 'wgu-hover-tooltip' + }; map = null; + conf = null; timerHandle = null; activeOverlayId = null; pendingRequestsCancelSrc = null; @@ -23,22 +28,26 @@ export default class HoverController { * 'hoverAttribute' if the layer is configured as 'hoverable' * * @param {ol.Map} map OpenLayers map. - * @param {Number} pointerRestInterval Timespan in milliseconds, by which displaying the tooltip is deferred. + * @param {object} hoverConf Global configuration options. */ - constructor (map, pointerRestInterval) { + constructor (map, hoverConf) { const me = this; me.map = map; + me.conf = me.DEFAULT_OPTIONS; + ObjectUtil.mergeDeep(me.conf, hoverConf); // To limit the amount of asynchronous requests, implement a "pointer rest" behavior, // which will potentially show a tooltip after the mouse has not moved for a given time period. - const timeout = pointerRestInterval ?? me.DEFAULT_POINTER_REST_INTERVAL; map.on('pointermove', (event) => { if (me.timerHandle) { clearTimeout(me.timerHandle); } me.timerHandle = setTimeout(() => { me.onPointerRest(event); - }, timeout); + }, me.conf.delay); + if (me.conf.hideOnMousemove) { + me.displayTooltip(null); + } }); // If the mouse leaves the map canvas, clear out the "pointer rest" timer and hide @@ -208,7 +217,7 @@ export default class HoverController { const feature = featureInfo.feature; const layer = featureInfo.layer; const hoverAttr = layer.get('hoverAttribute'); - const overlayId = layer.get('hoverOverlay') || me.DEFAULT_HOVER_OVERLAY; + const overlayId = layer.get('hoverOverlay') || me.conf.hoverOverlay; if (me.activeOverlayId !== overlayId) { WguEventBus.$emit(me.activeOverlayId + '-update-overlay', false); diff --git a/src/components/ol/Map.vue b/src/components/ol/Map.vue index 200272dd..18013f3b 100644 --- a/src/components/ol/Map.vue +++ b/src/components/ol/Map.vue @@ -251,7 +251,7 @@ export default { * @return {HoverController} HoverController instance. */ createHoverController () { - return new HoverController(this.map); + return new HoverController(this.map, this.$appConfig.mapHover); }, /** From 334342fb08436eb2d5e368562ac0b41be2a7d439 Mon Sep 17 00:00:00 2001 From: Felix Schmenger Date: Thu, 22 Feb 2024 18:20:17 +0100 Subject: [PATCH 3/5] Update unit tests for HoverController. --- tests/unit/specs/components/ol/HoverController.spec.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unit/specs/components/ol/HoverController.spec.js b/tests/unit/specs/components/ol/HoverController.spec.js index 8fe549cc..d050d601 100644 --- a/tests/unit/specs/components/ol/HoverController.spec.js +++ b/tests/unit/specs/components/ol/HoverController.spec.js @@ -43,6 +43,9 @@ describe('ol/HoverController.js', () => { expect(comp.timerHandle).to.equal(null); expect(comp.activeOverlayId).to.equal(null); expect(comp.pendingRequestsCancelSrc).to.equal(null); + expect(comp.conf.delay).to.equal(150) + expect(comp.conf.hideOnMousemove).to.equal(false) + expect(comp.conf.hoverOverlay).to.equal('wgu-hover-tooltip') }); afterEach(() => { From 8cb136fc40c25f233191c64eca2f6d422c2c4a98 Mon Sep 17 00:00:00 2001 From: Felix Schmenger Date: Thu, 22 Feb 2024 18:51:37 +0100 Subject: [PATCH 4/5] Document on the newly added mapHover configuration property. --- docs/wegue-configuration.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/wegue-configuration.md b/docs/wegue-configuration.md index cce40eaf..440ebd64 100644 --- a/docs/wegue-configuration.md +++ b/docs/wegue-configuration.md @@ -19,6 +19,7 @@ This describes the Wegue application configuration, which is modelled as JSON do | **mapCenter** | Initial center of the map in map projection | `"mapCenter": [0, 0]` | | mapProjection | Configuration object for CRS / projection used for the map | see [mapProjection](wegue-configuration?id=mapprojection) | | mapGeodataDragDop | Configuration object for geodata file drag/drop functionality on the map. Only by setting the config this function will be enabled. | see [mapGeodataDragDop](wegue-configuration?id=mapGeodataDragDop) | +| mapHover | Configuration object to customize the bevahior of hover tooltips on the map. | see [mapHover](wegue-configuration?id=mapHover) | **modules** | Array of module configuration objects | See [modules](module-configuration) | | **mapLayers** | Array of map layer configuration objects | See [mapLayers](map-layer-configuration) | | overviewMap | Configuration object for the overview map. | See [overviewMap](wegue-configuration?id=overviewMap) @@ -226,6 +227,29 @@ Below is an example for such a configuration object: } ``` +### mapHover + +Optional configuration object to customize the behavior of hover tooltips on the map. +The following properties are supported: + +| Property | Meaning | Example | +|--------------------|:---------:|---------| +| delay | Timespan in milliseconds, by which displaying the tooltip is deferred after the mouse pointer rests. Defaults to `150`. | `"delay": 150` +| hideOnMousemove | Hide the tooltip when the mouse cursor is moved. Defaults to `false`. | `"hideOnMousemove": false` +| hoverOverlay | ID of a custom map overlay to use as a default display when a feature of the layer is hovered. Declaration of the `hoverOverlay` property on a mapLayer level takes precedence. For more information on how to implement a map overlay see the [reusable components](reusable-components?id=map-overlay) section. Defaults to Wegue's default tooltip `wgu-hover-tooltip` | `"hoverOverlay": "my-custom-overlay"` + +Example: + +```json +"mapHover": + { + "delay": 150, + "hideOnMousemove": false, + "hoverOverlay": "my-custom-overlay" + } +``` + + ### lang Wegue comes with multi-language support and currently supplies 2 language packs for English (`en`) and German (`de`). Languages supported by the application can be configured via the `lang` property. Wegue will automatically detect the users preferred languages from the browser settings and choose the most appropriate match. If no languages are configured, Wegue will default to English. From 4480de918ab348737ba6b1147bba2030b7a99e1b Mon Sep 17 00:00:00 2001 From: Felix Schmenger Date: Mon, 18 Mar 2024 17:00:04 +0100 Subject: [PATCH 5/5] Tweak documentation with respect to code review. --- docs/wegue-configuration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/wegue-configuration.md b/docs/wegue-configuration.md index 440ebd64..33b46edb 100644 --- a/docs/wegue-configuration.md +++ b/docs/wegue-configuration.md @@ -19,7 +19,7 @@ This describes the Wegue application configuration, which is modelled as JSON do | **mapCenter** | Initial center of the map in map projection | `"mapCenter": [0, 0]` | | mapProjection | Configuration object for CRS / projection used for the map | see [mapProjection](wegue-configuration?id=mapprojection) | | mapGeodataDragDop | Configuration object for geodata file drag/drop functionality on the map. Only by setting the config this function will be enabled. | see [mapGeodataDragDop](wegue-configuration?id=mapGeodataDragDop) | -| mapHover | Configuration object to customize the bevahior of hover tooltips on the map. | see [mapHover](wegue-configuration?id=mapHover) +| mapHover | Configuration object containing application wide parameters for hover tooltips on the map. | see [mapHover](wegue-configuration?id=mapHover) | **modules** | Array of module configuration objects | See [modules](module-configuration) | | **mapLayers** | Array of map layer configuration objects | See [mapLayers](map-layer-configuration) | | overviewMap | Configuration object for the overview map. | See [overviewMap](wegue-configuration?id=overviewMap) @@ -229,14 +229,14 @@ Below is an example for such a configuration object: ### mapHover -Optional configuration object to customize the behavior of hover tooltips on the map. +Wegue allows for customized tooltips that display one or multiple attributes of a feature when it is hovered over on the map. The optional `mapHover` property in the main Wegue configuration specifies application-wide parameters for tooltip behavior. This property affects only layers with the `hoverable` attribute set to `true` - refer to the [mapLayers](map-layer-configuration) section for more details. The following properties are supported: | Property | Meaning | Example | |--------------------|:---------:|---------| | delay | Timespan in milliseconds, by which displaying the tooltip is deferred after the mouse pointer rests. Defaults to `150`. | `"delay": 150` | hideOnMousemove | Hide the tooltip when the mouse cursor is moved. Defaults to `false`. | `"hideOnMousemove": false` -| hoverOverlay | ID of a custom map overlay to use as a default display when a feature of the layer is hovered. Declaration of the `hoverOverlay` property on a mapLayer level takes precedence. For more information on how to implement a map overlay see the [reusable components](reusable-components?id=map-overlay) section. Defaults to Wegue's default tooltip `wgu-hover-tooltip` | `"hoverOverlay": "my-custom-overlay"` +| hoverOverlay | ID of a custom map overlay to use as a default display when a feature of a layer is hovered. Declaration of the `hoverOverlay` property on a mapLayer level takes precedence. For more information on how to implement a map overlay see the [reusable components](reusable-components?id=map-overlay) section. Defaults to Wegue's default tooltip `wgu-hover-tooltip` | `"hoverOverlay": "my-custom-overlay"` Example: