From 3820e045f23c7b4873cd09968b97583437944b3d Mon Sep 17 00:00:00 2001 From: Matthieu Viry Date: Thu, 11 May 2023 14:41:51 +0200 Subject: [PATCH] Change behavior of label position reprojection when labels were moved manually --- client/js/function.js | 4 +- client/js/helpers.js | 78 +++++++++++++++++++++++++++------ client/js/layers_style_popup.js | 3 +- 3 files changed, 68 insertions(+), 17 deletions(-) diff --git a/client/js/function.js b/client/js/function.js index 5a2e14b08..b2986b0ae 100755 --- a/client/js/function.js +++ b/client/js/function.js @@ -22,7 +22,7 @@ import { isNumber, makeDorlingSimulation, makeDemersSimulation, - reprojectToRobinson, reprojectFromRobinson, sleep, + reprojectToRobinson, reprojectFromRobinson, sleep, drag_label, } from './helpers'; import { getBinsCount, get_nb_decimals, has_negative, @@ -5043,7 +5043,7 @@ export const render_label = function render_label(layer, rendering_params, optio .on('dblclick contextmenu', function (event) { context_menu.showMenu(event, document.querySelector('body'), getItems(this)); }) - .call(drag_elem_geo); + .call(drag_label); data_manager.current_layers[layer_to_add] = { n_features: new_layer_data.length, diff --git a/client/js/helpers.js b/client/js/helpers.js index 96889c2e0..085f4e4fe 100755 --- a/client/js/helpers.js +++ b/client/js/helpers.js @@ -86,6 +86,28 @@ export const createWaitingOverlay = () => { }; }; +/** + * Function called while the user moves labels / proportional symbols / waffle on the map + * in order to indicate the original position of the element. + * + * @param {Event} event - The event that triggered the function call. + */ +const drag_start_ref_position = function (event) { + const zoom = svg_map.__zoom; + const centroid = path.centroid(this.__data__.geometry); + centroid[0] = centroid[0] * zoom.k + zoom.x; + centroid[1] = centroid[1] * zoom.k + zoom.y; + map.append('rect') + .attrs({ + x: centroid[0] - 2, + y: centroid[1] - 2, + height: 4, + width: 4, + id: 'ref_symbol_location', + }) + .style('fill', 'red'); +}; + export const drag_elem_geo = d3.drag() .subject(function () { const t = d3.select(this); @@ -139,24 +161,14 @@ export const drag_elem_geo2 = d3.drag() event.sourceEvent.stopPropagation(); event.sourceEvent.preventDefault(); handle_click_hand('lock'); - const zoom = svg_map.__zoom; - const centroid = path.centroid(this.__data__.geometry); - centroid[0] = centroid[0] * zoom.k + zoom.x; - centroid[1] = centroid[1] * zoom.k + zoom.y; - map.append('rect') - .attrs({ - x: centroid[0] - 2, - y: centroid[1] - 2, - height: 4, - width: 4, - id: 'ref_symbol_location', - }) - .style('fill', 'red'); + // Display a red square to indicate the original position of the label + drag_start_ref_position.call(this, event); }) .on('end', (event) => { if (event.subject && !event.subject.map_locked) { handle_click_hand('unlock'); } + // Remove red square thaht indicates the original position of the label map.selectAll('#ref_symbol_location').remove(); }) .on('drag', function (event) { @@ -167,6 +179,40 @@ export const drag_elem_geo2 = d3.drag() } }); +export const drag_label = d3.drag() + .subject(function () { + const t = d3.select(this); + return { + x: t.attr('x'), + y: t.attr('y'), + map_locked: !!map_div.select('#hand_button').classed('locked'), + }; + }) + .on('start', function (event) { + event.sourceEvent.stopPropagation(); + event.sourceEvent.preventDefault(); + handle_click_hand('lock'); + // Display a red square to indicate the original position of the label + drag_start_ref_position.call(this, event); + }) + .on('end', function (event) { + if (event.subject && !event.subject.map_locked) { handle_click_hand('unlock'); } + // Compute geo coordinates corresponding to the label position + // and modify the geometry of the label + // (the original position is still stored in the data properties) + const t = d3.select(this); + const x = +t.attr('x'); + const y = +t.attr('y'); + const new_coords = proj.invert([x, y]); + t.datum().geometry.coordinates = new_coords; + // Remove red square thaht indicates the original position of the label + map.selectAll('#ref_symbol_location').remove(); + }) + .on('drag', function (event) { + d3.select(this).attr('x', event.x).attr('y', event.y); + }); + + export const drag_waffle = d3.drag() .filter(function () { return data_manager.current_layers[_app.id_to_layer.get(this.parentElement.id)].draggable; @@ -181,16 +227,20 @@ export const drag_waffle = d3.drag() map_locked: !!map_div.select('#hand_button').classed('locked'), }; }) - .on('start', (event) => { + .on('start', function (event) { event.sourceEvent.stopPropagation(); event.sourceEvent.preventDefault(); handle_click_hand('lock'); + // Display a red square to indicate the original position of the label + drag_start_ref_position.call(this, event); }) .on('end', function (event) { if (event.subject && !event.subject.map_locked) { handle_click_hand('unlock'); } d3.select(this).style('cursor', 'grab'); + // Remove red square thaht indicates the original position of the label + map.selectAll('#ref_symbol_location').remove(); }) .on('drag', function (event) { d3.select(this) diff --git a/client/js/layers_style_popup.js b/client/js/layers_style_popup.js index b1ccf6639..ef58f3a44 100755 --- a/client/js/layers_style_popup.js +++ b/client/js/layers_style_popup.js @@ -388,7 +388,8 @@ function createStyleBoxLabel(layer_name) { .on('click', () => { selection.transition() .attrs((d) => { - const coords = global.proj(d.geometry.coordinates); + const ref_coords = [d.properties.x, d.properties.y]; + const coords = global.proj(ref_coords); return { x: coords[0], y: coords[1] }; }); });