File : dialogs/profileDialog/SvgMouseMoveEL.js

1
/*
2
Copyright - 2020 - wwwouaiebe - Contact: http//www.ouaie.be/
3
4
This  program is free software;
5
you can redistribute it and/or modify it under the terms of the
6
GNU General Public License as published by the Free Software Foundation;
7
either version 3 of the License, or any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
*/
18
/*
19
Changes:
20
    - v4.0.0:
21
        - created from v3.6.0
22
Doc reviewed 202208
23
 */
24
25
import theEventDispatcher from '../../core/lib/EventDispatcher.js';
26
import theUtilities from '../../core/uiLib/Utilities.js';
27
import theDataSearchEngine from '../../data/DataSearchEngine.js';
28
import SvgProfileBuilder from '../../core/lib/SvgProfileBuilder.js';
29
import BaseSvgEL from './BaseSvgEL.js';
30
import { SVG_NS, ZERO, TWO, THREE } from '../../main/Constants.js';
31
32
/* ------------------------------------------------------------------------------------------------------------------------- */
33
/**
34
mousemove event listener for svg profile
35
*/
36
/* ------------------------------------------------------------------------------------------------------------------------- */
37
38
class SvgMouseMoveEL extends BaseSvgEL {
39
40
    /**
41
    The vertical svg polyline at the mouse position
42
    @type {SVGElement}
43
    */
44
45
    #marker;
46
47
    /**
48
    The svg text with the distance since the beginning of the route at the mouse position
49
    @type {SVGElement}
50
    */
51
52
    #distanceText;
53
54
    /**
55
    The svg text with the elevation at the mouse position
56
    @type {SVGElement}
57
    */
58
59
    #elevText;
60
61
    /**
62
    The svg text with the ascent of the route at the mouse position
63
    @type {SVGElement}
64
    */
65
66
    #ascentText;
67
68
    /**
69
    A string indicating where is the text anchor. Must be 'end' or 'start'
70
    @type {String}
71
    */
72
73
    #textAnchor;
74
75
    /**
76
    The horizontal position of the marker on the svg
77
    @type {Number}
78
    */
79
80
    #markerX;
81
82
    /**
83
    The svgElement with the profile
84
    @type {SVGElement}
85
    */
86
87
    #profileSvg;
88
89
    /**
90
    A method to create a svg:text.
91
    @param {String} text The text to add in the svg:text
92
    @param {Number} markerY The vertical position of the text on the svg
93
    @return {SVGElement} The svg:text element
94
    */
95
96
    #createSvgText ( text, markerY ) {
97
        const svgText = document.createElementNS ( SVG_NS, 'text' );
98
        svgText.appendChild ( document.createTextNode ( text ) );
99
        svgText.setAttributeNS ( null, 'class', 'TravelNotes-Route-SvgProfile-elevText' );
100
        svgText.setAttributeNS ( null, 'x', this.#markerX );
101
        svgText.setAttributeNS ( null, 'y', markerY );
102
        svgText.setAttributeNS ( null, 'text-anchor', this.#textAnchor );
103
        this.#profileSvg.appendChild ( svgText );
104
105
        return svgText;
106
    }
107
108
    /**
109
    The constructor
110
    */
111
112
    constructor ( ) {
113
        super ( );
114
    }
115
116
    /**
117
    Event listener method
118
    @param {Event} mouseEvent The event to handle
119
    */
120
121
    handleEvent ( mouseEvent ) {
122
123
        mouseEvent.preventDefault ( );
124
        mouseEvent.stopPropagation ( );
125
126
        this.#profileSvg = mouseEvent.currentTarget;
127
        const latLngElevOnRoute = this.getlatLngElevOnRouteAtMousePosition ( mouseEvent );
128
        if ( latLngElevOnRoute ) {
129
130
            // itinerary point marker on the map
131
            const markerObjId = Number.parseInt ( this.#profileSvg.dataset.tanMarkerObjId );
132
            theEventDispatcher.dispatch ( 'removeobject', { objId : markerObjId } );
133
            theEventDispatcher.dispatch (
134
                'additinerarypointmarker',
135
                {
136
                    objId : markerObjId,
137
                    latLng : latLngElevOnRoute.latLng
138
                }
139
            );
140
141
            // Line and text on svg
142
            if ( this.#marker && this.#profileSvg.contains ( this.#marker ) ) {
143
                this.#profileSvg.removeChild ( this.#marker );
144
                this.#profileSvg.removeChild ( this.#distanceText );
145
                this.#profileSvg.removeChild ( this.#elevText );
146
                this.#profileSvg.removeChild ( this.#ascentText );
147
            }
148
            else {
149
                this.#marker = null;
150
                this.#distanceText = null;
151
                this.#elevText = null;
152
                this.#ascentText = null;
153
            }
154
            const clientRect = this.#profileSvg.getBoundingClientRect ( );
155
            this.#markerX =
156
                ( ( TWO * SvgProfileBuilder.PROFILE_MARGIN ) + SvgProfileBuilder.PROFILE_WIDTH ) *
157
                ( mouseEvent.clientX - clientRect.x ) / clientRect.width;
158
            const markerY = SvgProfileBuilder.PROFILE_MARGIN + SvgProfileBuilder.PROFILE_HEIGHT;
159
160
            // line
161
            this.#marker = document.createElementNS ( SVG_NS, 'polyline' );
162
            this.#marker.setAttributeNS (
163
                null,
164
                'points',
165
                String ( this.#markerX ) + ',' + SvgProfileBuilder.PROFILE_MARGIN + ' ' + this.#markerX + ',' + markerY
166
            );
167
            this.#marker.setAttributeNS ( null, 'class', 'TravelNotes-Route-SvgProfile-markerPolyline' );
168
            this.#profileSvg.appendChild ( this.#marker );
169
170
            // texts
171
            const route = theDataSearchEngine.getRoute ( Number.parseInt ( this.#profileSvg.dataset.tanObjId ) );
172
            this.#textAnchor = latLngElevOnRoute.distance > route.distance / TWO ? 'end' : 'start';
173
            this.#markerX +=
174
                latLngElevOnRoute.distance > route.distance / TWO
175
                    ?
176
                    -SvgProfileBuilder.X_DELTA_TEXT
177
                    :
178
                    SvgProfileBuilder.X_DELTA_TEXT;
179
180
            // distance
181
            this.#distanceText = this.#createSvgText (
182
                theUtilities.formatDistance ( latLngElevOnRoute.distance ),
183
                SvgProfileBuilder.PROFILE_MARGIN + SvgProfileBuilder.Y_DELTA_TEXT
184
            );
185
186
            this.#elevText = this.#createSvgText (
187
                'Alt. ' + latLngElevOnRoute.elev.toFixed ( ZERO ) + ' m.',
188
                SvgProfileBuilder.PROFILE_MARGIN + ( SvgProfileBuilder.Y_DELTA_TEXT * TWO )
189
            );
190
191
            this.#ascentText = this.#createSvgText (
192
                'Pente ' + latLngElevOnRoute.ascent.toFixed ( ZERO ) + ' % ',
193
                SvgProfileBuilder.PROFILE_MARGIN + ( SvgProfileBuilder.Y_DELTA_TEXT * THREE )
194
            );
195
        }
196
    }
197
}
198
199
export default SvgMouseMoveEL;
200
201
/* --- End of file --------------------------------------------------------------------------------------------------------- */
202