Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/typo symbol filtering #106

Merged
merged 22 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
b2bbeea
added js for being able to check which picto we want to show or hide
Mar 16, 2023
70f1fcd
added css styling to match global magrit look. added js commentary
Mar 16, 2023
c4352ba
Added translation for checbox description
Mar 16, 2023
857664a
feature/typo_symbol_filtering ready
Mar 16, 2023
5c125af
Removed unecessary subgit repo for PR
Mar 16, 2023
5b1d439
Fixed _tr("translation") typo mistake in js
Mar 16, 2023
aebe2e2
Added the list of hidden_pictograms to render_TypoSymbols function
Mar 16, 2023
50b1c38
correction for render_TypoSymols - doesn't add filtered images to the…
Mar 16, 2023
08bd50f
fixed typo mistakes and removed unnecessary class
Mar 16, 2023
7b16c8c
added smoomacypy to gitignreo so it doesnt push its src/
Mar 16, 2023
5ce9098
change symbol rendering so its using more of basic magrit functioning
Mar 16, 2023
69fd15c
Improved the way we display selected typo symbols on the map
Mar 16, 2023
b06757d
Removed unecessary comments for PR
Mar 16, 2023
2ad70f8
Changed the symbols_map of rendering_params into symbols_to_display
Mar 17, 2023
537dc78
Removed comments that were used for debugging
Mar 17, 2023
5da6ee5
Fix bug when category value is a number
mthh Mar 20, 2023
427893a
Fix bug when reloading when category value is a number
mthh Mar 20, 2023
81fd48d
Fix some formatting / trailing whitespace / etc. issues
mthh Mar 20, 2023
88d1be4
Fix where filtering of unselected typo symbols happens to avoid empty…
mthh Mar 20, 2023
f1bf804
Update changelogs
mthh Mar 20, 2023
05cd43e
Remove outdated comment
mthh Mar 20, 2023
91c275b
Remove new duplicate entry in gitignore
mthh Mar 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ develop-eggs/
downloads/
eggs/
.eggs/

src/
# Virtual environnements
venv/

Expand Down
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Changes
=======

Unreleased
----------

- Enables the filtering of one or more categories of symbols when rendering a Typo Symbol map (thanks to @robLittiere and @ArmelVidali / see PR #106)


0.13.4 (2023-03-14)
-------------------

Expand Down
12 changes: 12 additions & 0 deletions client/css/discretization.css
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,16 @@ li.typo_class > p.color_square {
li.typo_class > p.symbol_section {
cursor: pointer;
}

li.typo_li {
display: flex;
align-items: center;
transition: opacity 0.1s;

}

.typo_container {
display: flex;
flex-direction: column;
}
/* End of styles for list of elements in categorical / picto panel */
52 changes: 33 additions & 19 deletions client/js/function.js
Original file line number Diff line number Diff line change
Expand Up @@ -3853,16 +3853,19 @@ const fields_TypoSymbol = {
document.getElementById('yesTypoSymbols').disabled = null;
self.rendering_params[field] = {
nb_cat: confirmed[0],
symbols_map: confirmed[1],
field,
symbols_to_display: confirmed[1],
field: field,
// List of fields checked by the user for fields images not to be rendered
// We get this from the returned promise
picto_filter: confirmed[2],
};
}
});
}, () => null);
});
ok_button.on('click', () => {
const field = field_to_use.node().value;
render_TypoSymbols(self.rendering_params[field], uo_layer_name.node().value);
render_TypoSymbols(self.rendering_params[field], uo_layer_name.node().value, self.rendering_params[field].picto_filter);
});
setSelected(field_to_use.node(), fields_all[0]);
uo_layer_name.attr('value', ['Symbols', layer].join('_'));
Expand All @@ -3874,10 +3877,11 @@ const fields_TypoSymbol = {
rendering_params: {},
};

function render_TypoSymbols(rendering_params, new_name) {
// Added picto_filter parameter, a list of pictograms not to be displayed
function render_TypoSymbols(rendering_params, new_name, filtered_symbols) {
const layer_name = Object.getOwnPropertyNames(data_manager.user_data)[0];
const ref_layer_id = _app.layer_to_id.get(layer_name);
const { field } = rendering_params;
const field = rendering_params.field;
const layer_to_add = check_layer_name(new_name.length > 0 ? new_name : ['Symbols', field, layer_name].join('_'));
const ref_selection = document.getElementById(ref_layer_id).getElementsByTagName('path');
const nb_ft = ref_selection.length;
Expand All @@ -3887,16 +3891,19 @@ function render_TypoSymbols(rendering_params, new_name) {
for (let i = 0, nb_features = ref_selection.length; i < nb_features; ++i) {
const ft = ref_selection[i].__data__;
const value = ft.properties[field];
const new_obj = {
id: i,
type: 'Feature',
properties: {},
geometry: { type: 'Point' },
};
new_obj.properties.symbol_field = value;
new_obj.properties.id_parent = ft.id;
new_obj.geometry.coordinates = coordsPointOnFeature(ft.geometry);
result.push(new_obj);
// Check if field value is within the filtered list the user doesn't want to display
if (!filtered_symbols.includes(`${value}`)) {
const new_obj = {
id: i,
type: 'Feature',
properties: {},
geometry: {type: 'Point'},
};
new_obj.properties.symbol_field = value;
new_obj.properties.id_parent = ft.id;
new_obj.geometry.coordinates = coordsPointOnFeature(ft.geometry);
result.push(new_obj);
}
}
return {
type: 'FeatureCollection',
Expand All @@ -3907,7 +3914,7 @@ function render_TypoSymbols(rendering_params, new_name) {
const new_layer_data = make_geojson_pt_layer();
const layer_id = encodeId(layer_to_add);
const context_menu = new ContextMenu();
const getItems = (self_parent) => [
const getItems = self_parent => [
{ name: _tr('app_page.common.edit_style'), action: () => { make_style_box_indiv_symbol(self_parent); } },
{ name: _tr('app_page.common.delete'), action: () => { self_parent.style.display = 'none'; } }, // eslint-disable-line no-param-reassign
];
Expand All @@ -3921,17 +3928,22 @@ function render_TypoSymbols(rendering_params, new_name) {
.data(new_layer_data.features)
.enter()
.insert('image')
.attrs((d) => {
.attrs(function (d, i) {
let field_value = d.properties.symbol_field;

// Entry in the symbol map was replaced by 'undefined_category'
// when the field value was null :
if (field_value === null || field_value === '' || field_value === undefined) {
field_value = 'undefined_category';
}

// Values are stored as strings in our symbol map
const symb = rendering_params.symbols_map.get(`${field_value}`);
const symb = rendering_params.symbols_to_display.get(`${field_value}`);
const coords = global.proj(d.geometry.coordinates);

return {
// Add a unique id to each element and a class to each element for future improvement
id: `Picto_${i}`,
x: coords[0] - symb[1] / 2,
y: coords[1] - symb[1] / 2,
width: symb[1],
Expand All @@ -3949,12 +3961,14 @@ function render_TypoSymbols(rendering_params, new_name) {
data_manager.current_layers[layer_to_add] = {
n_features: data_manager.current_layers[layer_name].n_features,
renderer: 'TypoSymbols',
symbols_map: rendering_params.symbols_map,
symbols_to_display: rendering_params.symbols_to_display,
filtered_symbols: filtered_symbols,
rendered_field: field,
is_result: true,
symbol: 'image',
ref_layer_name: layer_name,
};

create_li_layer_elem(layer_to_add, nb_ft, ['Point', 'symbol'], 'result');
handle_legend(layer_to_add);
zoom_without_redraw();
Expand Down
4 changes: 2 additions & 2 deletions client/js/layers_style_popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ function createStyleBoxTypoSymbols(layer_name) {

const selection = map.select(`#${_app.layer_to_id.get(layer_name)}`).selectAll('image'),
ref_layer_name = data_manager.current_layers[layer_name].ref_layer_name,
symbols_map = data_manager.current_layers[layer_name].symbols_map,
symbols_map = data_manager.current_layers[layer_name].symbols_to_display,
rendered_field = data_manager.current_layers[layer_name].rendered_field;

const prev_settings = [],
Expand Down Expand Up @@ -237,7 +237,7 @@ function createStyleBoxTypoSymbols(layer_name) {
selection.transition()
.attrs((d) => {
const centroid = global.proj(d.geometry.coordinates),
size_symbol = symbols_map.get(d.properties.symbol_field)[1] / 2;
size_symbol = symbols_map.get(`${d.properties.symbol_field}`)[1] / 2;
return { x: centroid[0] - size_symbol, y: centroid[1] - size_symbol };
});
});
Expand Down
2 changes: 1 addition & 1 deletion client/js/legend.js
Original file line number Diff line number Diff line change
Expand Up @@ -1285,7 +1285,7 @@ export function createLegend_choro(layer, field, title, subtitle, box_gap = 0, r
// nb_class = layer_prop.color_map.size;
} else if (layer_prop.renderer.indexOf('TypoSymbols') > -1) {
data_colors_label = [];
layer_prop.symbols_map.forEach((v) => {
layer_prop.symbols_to_display.forEach((v) => {
data_colors_label.push({ value: v[2], image: v[0] });
});
// nb_class = layer_prop.symbols_map.size;
Expand Down
12 changes: 9 additions & 3 deletions client/js/map_ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,18 @@ export function reproj_symbol_layer() {
return { x: pt[0], y: pt[1] };
});
} else if (symbol === 'image') { // Reproject pictograms :
// Get previously filtered symbols from data_manager :
const filtered_symbols = data_manager.current_layers[lyr_name].filtered_symbols;
map.select(`#${global._app.layer_to_id.get(lyr_name)}`)
.selectAll(symbol)
.attrs(function (d) {
const coords = global.proj(d.geometry.coordinates),
size = +this.getAttribute('width').replace('px', '') / 2;
return { x: coords[0] - size, y: coords[1] - size };
const field = d.properties.symbol_field;
// Only render the symbols that were not filtered out :
if (!filtered_symbols.includes(`${field}`)) {
const coords = global.proj(d.geometry.coordinates),
size = +this.getAttribute('width').replace('px', '') / 2;
return { x: coords[0] - size, y: coords[1] - size };
}
});
} else if (symbol === 'circle') { // Reproject Prop Symbol :
const isDorling = !!data_manager.current_layers[lyr_name].dorling_demers;
Expand Down
20 changes: 14 additions & 6 deletions client/js/map_project.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ export function get_map_project() {
? 'sphere' : false) || (current_layer_prop.graticule ? 'graticule' : 'layer'),
nb_ft = current_layer_prop.n_features;
let selection;

layer_style_i.layer_name = layer_name;
layer_style_i.layer_type = layer_type;
layer_style_i.n_features = nb_ft;
Expand Down Expand Up @@ -437,7 +436,12 @@ export function get_map_project() {
} else if (current_layer_prop.renderer && current_layer_prop.renderer === 'TypoSymbols') {
selection = map.select(`#${layer_id}`).selectAll('image');
layer_style_i.renderer = current_layer_prop.renderer;
layer_style_i.symbols_map = [...current_layer_prop.symbols_map];

layer_style_i.symbols_to_display = [...current_layer_prop.symbols_to_display];
//layer_style_i.symbols_map = [...current_layer_prop.symbols_to_display];

// Add the filtered symbol list so we can retreive on project reload
layer_style_i.filtered_symbols = current_layer_prop.filtered_symbols;
layer_style_i.rendered_field = current_layer_prop.rendered_field;
layer_style_i.ref_layer_name = current_layer_prop.ref_layer_name;

Expand Down Expand Up @@ -1318,14 +1322,14 @@ export function apply_user_preferences(json_pref) {
at_end.push([restorePreviousPosWaffle, layer_id, _layer.current_position, _layer.symbol]);
}
} else if (_layer.renderer && _layer.renderer.startsWith('TypoSymbol')) {
const symbols_map = new Map(_layer.symbols_map);
const symbols_to_display = new Map(_layer.symbols_to_display);
const new_layer_data = {
type: 'FeatureCollection',
features: _layer.current_state.map((d) => d.data),
};

const nb_features = new_layer_data.features.length;
const context_menu = new ContextMenu();
const filtered_symbols = _layer.filtered_symbols;
const getItems = (self_parent) => [
{ name: _tr('app_page.common.edit_style'), action: () => { make_style_box_indiv_symbol(self_parent); } },
{ name: _tr('app_page.common.delete'), action: () => { self_parent.style.display = 'none'; } }, // eslint-disable-line no-param-reassign
Expand All @@ -1341,6 +1345,7 @@ export function apply_user_preferences(json_pref) {
.insert('image')
.attrs((d, j) => {
let field_value = d.properties.symbol_field;

// Entry in the symbol map was replaced by 'undefined_category' in 0.10.0
// when the field value was null :
if (
Expand All @@ -1353,10 +1358,12 @@ export function apply_user_preferences(json_pref) {
) { // Entry in the symbol map is always stored as string since 0.10.1 :
field_value = `${field_value}`;
}
const symb = symbols_map.get(field_value),
const symb = symbols_to_display.get(field_value),
prop = _layer.current_state[j],
coords = prop.pos;
return {
// Add a unique id to each element and a class to each element for future improvement
id: `Picto_${i}`,
x: coords[0] - symb[1] / 2,
y: coords[1] - symb[1] / 2,
width: prop.size,
Expand All @@ -1376,7 +1383,8 @@ export function apply_user_preferences(json_pref) {
data_manager.current_layers[layer_name] = {
n_features: nb_features,
renderer: 'TypoSymbols',
symbols_map: symbols_map,
symbols_to_display: symbols_to_display,
filtered_symbols: filtered_symbols,
rendered_field: _layer.rendered_field,
is_result: true,
symbol: 'image',
Expand Down
Loading