Skip to content

Commit

Permalink
Merge pull request #1510 from SigtunaGIS/origo-master-feature-alterna…
Browse files Browse the repository at this point in the history
…tive-style

Style picker for client stylin
  • Loading branch information
johnnyblasta authored Jun 1, 2022
2 parents 1172f0c + 0292b8f commit dfa70c3
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 13 deletions.
22 changes: 22 additions & 0 deletions scss/_stylepicker.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.o-stylepicker {
height: 1.25rem;
margin-right: 5px;
margin-bottom: 1.25rem;
min-width: 110px;
}

.o-stylepicker-header {
margin-right: 5px;
margin-top: 1.25rem;
}

.o-stylepicker button {
border-radius: 10px;
font-family: Arial, 'Helvetica Neue', sans-serif;
font-size: .625rem;
line-height: 1.25rem;
}

.o-stylepicker .dropdown li:hover {
color: $grey-darker;
}
1 change: 1 addition & 0 deletions scss/origo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
@import 'popover';
@import 'dropdown';
@import 'sidebar';
@import 'stylepicker';
@import 'close';
@import 'icon';
@import 'tooltip';
Expand Down
29 changes: 22 additions & 7 deletions src/controls/legend/overlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import { HeaderIcon } from '../../utils/legendmaker';
import PopupMenu from '../../ui/popupmenu';

const OverlayLayer = function OverlayLayer(options) {
let {
headerIconCls = ''
} = options;
const {
headerIconCls = '',
cls: clsSettings = '',
icon = '#o_list_24px',
iconCls = 'grey-lightest',
Expand All @@ -17,9 +15,13 @@ const OverlayLayer = function OverlayLayer(options) {
} = options;

const buttons = [];
let headerIconClass = headerIconCls;

const popupMenuItems = [];
let layerList;

const hasStylePicker = viewer.getLayerStylePicker(layer).length > 0;
const layerIconCls = `round compact icon-small relative no-shrink light ${hasStylePicker ? 'style-picker' : ''}`;
const cls = `${clsSettings} flex row align-center padding-left padding-right-smaller item`.trim();
const title = layer.get('title') || 'Titel saknas';
const name = layer.get('name');
Expand All @@ -39,7 +41,7 @@ const OverlayLayer = function OverlayLayer(options) {
let headerIcon = HeaderIcon(style, opacity);
if (!headerIcon) {
headerIcon = icon;
headerIconCls = iconCls;
headerIconClass = iconCls;
}

const eventOverlayProps = new CustomEvent('overlayproperties', {
Expand Down Expand Up @@ -68,15 +70,15 @@ const OverlayLayer = function OverlayLayer(options) {
};

const layerIcon = Button({
cls: `${headerIconCls} round compact icon-small light relative no-shrink`,
cls: `${headerIconClass} ${layerIconCls}`,
click() {
if (!secure) {
toggleVisible(layer.getVisible());
}
},
style: {
height: '1.5rem',
width: '1.5rem'
height: 'calc(1.5rem + 2px)',
width: 'calc(1.5rem + 2px)'
},
ariaLabel: 'Lager ikon',
icon: headerIcon,
Expand Down Expand Up @@ -262,6 +264,16 @@ const OverlayLayer = function OverlayLayer(options) {
el.remove();
};

const onLayerStyleChange = function onLayerStyleChange() {
const newStyle = viewer.getStyle(layer.get('styleName'));
const layerIconCmp = document.getElementById(layerIcon.getId());
let newIcon = HeaderIcon(newStyle, opacity);
headerIconClass = !newIcon ? iconCls : headerIconCls;
newIcon = !newIcon ? icon : newIcon;
layerIconCmp.className = `${headerIconClass} ${layerIconCls}`;
layerIcon.dispatch('change', { icon: newIcon });
};

return Component({
name,
getLayer,
Expand Down Expand Up @@ -300,6 +312,9 @@ const OverlayLayer = function OverlayLayer(options) {
});
document.getElementById(this.getId()).dispatchEvent(visibleEvent);
});
layer.on('change:style', () => {
onLayerStyleChange();
});
},
render() {
return `<li id="${this.getId()}" class="${cls}">${ButtonsHtml}</li>`;
Expand Down
70 changes: 67 additions & 3 deletions src/controls/legend/overlayproperties.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component, InputRange } from '../../ui';
import { Component, InputRange, Dropdown } from '../../ui';
import { Legend } from '../../utils/legendmaker';
import Style from '../../style';

const OverlayProperties = function OverlayProperties(options = {}) {
const {
Expand All @@ -15,6 +16,15 @@ const OverlayProperties = function OverlayProperties(options = {}) {
const opacityControl = layer.get('opacityControl') !== false;
const style = viewer.getStyle(layer.get('styleName'));
const legend = Legend(style, opacity);
const stylePicker = viewer.getLayerStylePicker(layer);

const legendComponent = Component({
render() {
return `<div id=${this.getId()}>${legend}</div>`;
}
});

let styleSelection;
let overlayEl;
let sliderEl;
let label = '';
Expand All @@ -31,6 +41,10 @@ const OverlayProperties = function OverlayProperties(options = {}) {
label
});

function hasStylePicker() {
return stylePicker.length > 0;
}

function extendedLegendZoom(e) {
const parentOverlay = document.getElementById(options.parent.getId());

Expand All @@ -43,14 +57,53 @@ const OverlayProperties = function OverlayProperties(options = {}) {
}
}

function renderStyleSelection() {
const html = `<div class="o-stylepicker-header text-small padding-small">Välj stil</div>${styleSelection.render()}`;
return hasStylePicker() ? html : '';
}

function getStyleDisplayName(styleName) {
const altStyle = stylePicker.find(s => s.style === styleName);
return (altStyle && altStyle.title) || styleName;
}

const onSelectStyle = (styleTitle) => {
const altStyleIndex = stylePicker.findIndex(s => s.title === styleTitle);
const altStyle = stylePicker[altStyleIndex];
styleSelection.setButtonText(styleTitle);
const newStyle = Style.createStyle({ style: altStyle.style, clusterStyleName: altStyle.clusterStyle, viewer });
const legendCmp = document.getElementById(legendComponent.getId());
legendCmp.innerHTML = Legend(viewer.getStyle(altStyle.style), opacity);
if (!layer.get('defaultStyle')) layer.setProperties({ defaultStyle: layer.get('styleName') });
layer.setProperties({ altStyleIndex });
layer.setProperties({ styleName: altStyle.style });
layer.setStyle(newStyle);
layer.dispatchEvent('change:style');
};

return Component({
onInit() {
this.addComponents([transparencySlider]);
styleSelection = Dropdown({
direction: 'up',
cls: 'o-stylepicker text-black flex',
contentCls: 'bg-grey-lighter text-smaller rounded',
buttonCls: 'bg-white border text-black box-shadow',
buttonTextCls: 'text-smaller',
text: getStyleDisplayName(layer.get('styleName')),
buttonIconCls: 'black',
ariaLabel: 'Välj stil'
});
const components = [transparencySlider];
if (hasStylePicker()) {
components.push(styleSelection);
}
this.addComponents(components);
this.on('click', (e) => {
extendedLegendZoom(e);
});
},
onRender() {
this.dispatch('render');
sliderEl = document.getElementById(transparencySlider.getId());
overlayEl = document.getElementById(this.getId());
overlayEl.addEventListener('click', (e) => {
Expand All @@ -66,10 +119,21 @@ const OverlayProperties = function OverlayProperties(options = {}) {
layer.setOpacity(sliderEl.valueAsNumber);
});
}
if (hasStylePicker()) {
styleSelection.setItems(stylePicker.map(altStyle => altStyle.title));
const styleSelectionEl = document.getElementById(styleSelection.getId());
styleSelectionEl.addEventListener('dropdown:select', (evt) => {
onSelectStyle(evt.target.textContent);
});
}
},
render() {
return `<div id="${this.getId()}" class="${cls} border-bottom">
<div class="padding-small">${legend}${transparencySlider.render()}</div>
<div class="padding-small">
${legendComponent.render()}
${renderStyleSelection()}
${transparencySlider.render()}
</div>
${abstract ? `<div class="padding-small padding-x text-small">${abstract}</div>` : ''}
</div>`;
},
Expand Down
9 changes: 8 additions & 1 deletion src/permalink/permalinkparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const layerModel = {
o: {
name: 'opacity',
dataType: 'number'
},
sn: {
name: 'altStyleIndex',
dataType: 'number'
}
};

Expand All @@ -31,12 +35,15 @@ const layers = function layers(layersStr) {
});
Object.getOwnPropertyNames(layerObject).forEach((prop) => {
const val = layerObject[prop];
if (Object.prototype.hasOwnProperty.call(layerModel, prop) && prop !== 'o') {
if (Object.prototype.hasOwnProperty.call(layerModel, prop) && prop !== 'o' && prop !== 'sn') {
const attribute = layerModel[prop];
obj[attribute.name] = urlparser.strBoolean(val);
} else if (prop === 'o') {
const attribute = layerModel[prop];
obj[attribute.name] = Number(val) / 100;
} else if (prop === 'sn') {
const attribute = layerModel[prop];
obj[attribute.name] = Number(val);
} else {
obj[prop] = val;
}
Expand Down
2 changes: 2 additions & 0 deletions src/permalink/permalinkstore.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ function getSaveLayers(layers) {
saveLayer.v = layer.getVisible() === true ? 1 : 0;
saveLayer.s = layer.get('legend') === true ? 1 : 0;
saveLayer.o = Number(layer.get('opacity')) * 100;
// Only get style for layer styles that have changed
if (layer.get('defaultStyle') && layer.get('defaultStyle') !== layer.get('styleName')) saveLayer.sn = layer.get('altStyleIndex');
if (saveLayer.s || saveLayer.v) {
saveLayer.name = layer.get('name');
if (saveLayer.name !== 'measure') {
Expand Down
5 changes: 3 additions & 2 deletions src/ui/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export default function Dropdown(options = {}) {
style: styleSettings,
direction = 'down',
text = ' ',
ariaLabel = ''
ariaLabel = '',
buttonTextCls = 'flex'
} = options;

let containerElement;
Expand Down Expand Up @@ -78,7 +79,7 @@ export default function Dropdown(options = {}) {
icon: `#ic_arrow_drop_${direction}_24px`,
iconCls: `${buttonIconCls} icon-smaller flex`,
ariaLabel,
textCls: 'flex'
textCls: buttonTextCls
});

if (direction === 'down') {
Expand Down
20 changes: 20 additions & 0 deletions src/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const Viewer = function Viewer(targetOption, options = {}) {
const center = urlParams.center || centerOption;
const zoom = urlParams.zoom || zoomOption;
const groups = flattenGroups(groupOptions);
const layerStylePicker = {};

const getCapabilitiesLayers = () => {
const capabilitiesPromises = [];
Expand Down Expand Up @@ -324,6 +325,13 @@ const Viewer = function Viewer(targetOption, options = {}) {
visible: false,
legend: false
};
// Apply changed style
if (savedLayerProps[layerName] && savedLayerProps[layerName].altStyleIndex > -1) {
const altStyle = initialProps.stylePicker[savedLayerProps[layerName].altStyleIndex];
savedProps.clusterStyle = altStyle.clusterStyle;
savedProps.style = altStyle.style;
savedProps.defaultStyle = initialProps.style;
}
savedProps.name = initialProps.name;
const mergedProps = Object.assign({}, initialProps, savedProps);
acc.push(mergedProps);
Expand Down Expand Up @@ -369,8 +377,19 @@ const Viewer = function Viewer(targetOption, options = {}) {
return false;
};

const getLayerStylePicker = function getLayerStylePicker(layer) {
return layerStylePicker[layer.get('name')] || [];
};

const addLayerStylePicker = function addLayerStylePicker(layerProps) {
if (!layerStylePicker[layerProps.name]) {
layerStylePicker[layerProps.name] = layerProps.stylePicker;
}
};

const addLayer = function addLayer(layerProps) {
const layer = Layer(layerProps, this);
addLayerStylePicker(layerProps);
map.addLayer(layer);
this.dispatch('addlayer', {
layerName: layerProps.name
Expand Down Expand Up @@ -599,6 +618,7 @@ const Viewer = function Viewer(targetOption, options = {}) {
getSearchableLayers,
getSize,
getLayer,
getLayerStylePicker,
getLayers,
getLayersByProperty,
getMap,
Expand Down

0 comments on commit dfa70c3

Please sign in to comment.