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

Style picker for client stylin #1510

Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
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
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 @@ -239,6 +241,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 @@ -277,6 +289,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
71 changes: 68 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,52 @@ 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'
});
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 +118,23 @@ 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);
});
styleSelectionEl.setAttribute('aria-label', 'Välj stil');
styleSelectionEl.setAttribute('aria-labelledby', 'Välj stil');
}
},
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 @@ -61,6 +61,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 @@ -327,6 +328,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 @@ -372,8 +380,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 @@ -598,6 +617,7 @@ const Viewer = function Viewer(targetOption, options = {}) {
getSearchableLayers,
getSize,
getLayer,
getLayerStylePicker,
getLayers,
getLayersByProperty,
getMap,
Expand Down