Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions demo/js/ml-datasets.js
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ const testVisibility = () => {

const testGlobalVisibility = () => {
setTimeout(() => datasetsPlugin.setDatasetVisibility(false), 1000)
setTimeout(() => datasetsPlugin.setDatasetVisibility(true), 2000)
setTimeout(() => datasetsPlugin.setDatasetVisibility(true), 10000)
// setTimeout(() => datasetsPlugin.setDatasetVisibility(true, { datasetId: 'hedge-control' }), 500)
// setTimeout(() => datasetsPlugin.setStyle({ stroke: { outdoor: '#0000ff' }, }, { datasetId: 'hedge-control' }), 2000)
}
Expand Down Expand Up @@ -472,10 +472,10 @@ interactiveMap.on('datasets:ready', function () {
// testGetters()
// testInvalidApiCalls()
// testFeatureVisibility()
testSetOpacity()
// testSetOpacity()
// testSetStyle()
// testVisibility()
// testGlobalVisibility()
testGlobalVisibility()
// testRemoveAndAddDataset()
// testSetData()
})
Expand Down
1 change: 1 addition & 0 deletions plugins/beta/datasets/src/DatasetsInit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export function DatasetsInit ({ pluginConfig, pluginState, appState, mapState, m

useLayerAdapterActions('applyStyle', dispatch, pluginState, [pluginState.layerAdapterActions.applyStyle])
useLayerAdapterActions('applyDatasetVisibility', dispatch, pluginState, [pluginState.layerAdapterActions.applyDatasetVisibility])
useLayerAdapterActions('applyGlobalVisibility', dispatch, pluginState, [pluginState.layerAdapterActions.applyGlobalVisibility])
useLayerAdapterActions('applyDatasetOpacity', dispatch, pluginState, [pluginState.layerAdapterActions.applyDatasetOpacity])
useLayerAdapterActions('applyGlobalOpacity', dispatch, pluginState, [pluginState.layerAdapterActions.applyGlobalOpacity])
useLayerAdapterActions('addDataset', dispatch, pluginState, [pluginState.layerAdapterActions.addDataset])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ export class MapLibreDataset extends Dataset {
return response
}

getLayersWithVisibility () {
return this.getLayersWithValue('visibility')
}

getLayersWithOpacity () {
return this.getLayersWithValue('opacity')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ describe('MapLibreDataset', () => {
})
})

describe('getLayersWithVisibility', () => {
it('returns layerIds and visibility for a layer with sublayers', () => {
const registryDataset = datasetRegistry.getDataset('land-covers')
const layersWithVisibility = registryDataset.getLayersWithVisibility()
expect(layersWithVisibility).toEqual([
{ layerIds: ['land-covers-130-131', 'land-covers-130-131-stroke'], visibility: 'visible' },
{ layerIds: ['land-covers-332', 'land-covers-332-stroke'], visibility: 'visible' },
{ layerIds: ['land-covers-110', 'land-covers-110-stroke'], visibility: 'visible' },
{ layerIds: ['land-covers-379', 'land-covers-379-stroke'], visibility: 'none' },
{ layerIds: ['land-covers-other', 'land-covers-other-stroke'], visibility: 'visible' }
])
})
})

describe('getLayersWithOpacity', () => {
it('returns layerIds and opacity for a sublayer with no sublayers', () => {
const dataset = datasetRegistry.getDataset('existing-fields')
Expand Down
40 changes: 23 additions & 17 deletions plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,28 +289,34 @@ export default class MaplibreLayerAdapter {
})
}

/**
* Apply visibility for all layers with datasetId
* @param {string} datasetId
*/
applyDatasetVisibility (datasetId) {
const registryDataset = datasetRegistry.getDataset(datasetId)
const style = this._map.getStyle()
if (!style?.layers) {
return
}
// Covers base fill layer (datasetId) and all suffixed layers
// (-stroke, -${sublayerId}, -${sublayerId}-stroke) without needing the dataset object.
if (registryDataset.hasSublayers) {
const { sublayerIds } = registryDataset
sublayerIds.forEach(sublayerId => { this.applyDatasetVisibility(sublayerId) })
} else {
const { visibility } = registryDataset
const datasetId = registryDataset.id
style.layers.filter(layer =>
layer.id === datasetId || layer.id.startsWith(`${datasetId}-`)
).forEach(layer => {
this._map.setLayoutProperty(layer.id, 'visibility', visibility)
})
if (registryDataset) {
this._applyRegistryDatasetVisibility(registryDataset)
}
}

/**
* Apply visibility for all layers belonging to a registryDataset.
* @param {Object} registryDataset
*/
_applyRegistryDatasetVisibility (registryDataset) {
registryDataset.getLayersWithVisibility().forEach(({ layerIds, visibility }) => {
layerIds.forEach(layerId => this._map.setLayoutProperty(layerId, 'visibility', visibility))
})
}

/**
* Apply visibility for all layers
*/
applyGlobalVisibility () {
datasetRegistry.forEachDataset(registryDataset => this._applyRegistryDatasetVisibility(registryDataset))
}

_applyFeatureFilter (registryDataset) {
const layersWithFilters = registryDataset.getLayersWithFilters()
layersWithFilters.forEach(({ layerIds, filter }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export const LayersMenuCheckbox = ({ menuGroupItem, onChange }) => {
}
const datasetId = registryDataset.isSublayer ? registryDataset.parentId : registryDataset.id
const sublayerId = registryDataset.isSublayer ? registryDataset.id : undefined

const itemClass = `im-c-datasets-layers__item govuk-checkboxes govuk-checkboxes--small${registryDataset.visible ? '' : ' im-c-datasets-layers__item--checked'}`
return (
<div key={registryDataset.id} className={itemClass} data-module='govuk-checkboxes'>
Expand All @@ -20,7 +19,7 @@ export const LayersMenuCheckbox = ({ menuGroupItem, onChange }) => {
name='layers'
type='checkbox'
value={registryDataset.id}
checked={registryDataset.visible}
checked={registryDataset.isLocallyVisible}
onChange={onChange}
/>
<label className='im-c-datasets-layers__item-label govuk-label govuk-checkboxes__label' htmlFor={registryDataset.id}>
Expand Down
4 changes: 4 additions & 0 deletions plugins/beta/datasets/src/panels/Layers.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,7 @@
.im-c-datasets-layers-group:first-child .im-c-datasets-layers-group__legend {
padding-top: 0;
}

.im-c-datasets-layers .govuk-checkboxes__input[aria-disabled="true"] + .govuk-checkboxes__label {
opacity: 0.5;
}
7 changes: 5 additions & 2 deletions plugins/beta/datasets/src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const initialState = {
layerAdapterActions: {
applyStyle: [],
applyDatasetVisibility: [],
applyGlobalVisibility: [],
applyDatasetOpacity: [],
applyGlobalOpacity: [],
addDataset: [],
Expand Down Expand Up @@ -108,10 +109,12 @@ const setDatasetVisibility = (state, payload) => {
}

const setGlobalVisibility = (state, payload) => {
const { visibility } = payload
const { visible } = payload
const applyGlobalVisibility = [...state.layerAdapterActions.applyGlobalVisibility, [visible]]
return {
...state,
globals: { ...state.globals, visible: visibility !== 'hidden' }
layerAdapterActions: { ...state.layerAdapterActions, applyGlobalVisibility },
globals: { ...state.globals, visible }
}
}

Expand Down
26 changes: 24 additions & 2 deletions plugins/beta/datasets/src/registry/dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { datasetRegistry } from './datasetRegistry.js'
import { hasCustomVisualStyle } from '../defaults.js'
import { hasPattern } from '../../../../../src/utils/patternUtils.js'
import { DynamicGeoJson } from './dynamicGeoJson.js'
import { calculateOpacity } from './globalDataset.js'
import { calculateOpacity, getGlobalVisibility } from './globalDataset.js'

export class Dataset {
constructor (dataset) {
Expand All @@ -25,6 +25,7 @@ export class Dataset {
get maxZoom () { return this._datasetDefinition.maxZoom || this.parent?.maxZoom }
get showInKey () { return this._datasetDefinition.showInKey || this.parent?.showInKey || false }
get groupLabel () { return this._datasetDefinition.groupLabel }

get opacity () {
const myOpacity = this.style?.opacity
const parentOpacity = this.parent?.style?.opacity
Expand All @@ -50,11 +51,32 @@ export class Dataset {
return null // TODO - implement filter construction for esri and openLayers adapters
}

// Returns true if either the parent (if it has one) or global visibility is hidden , otherwise returns true.
// This is used to determine whether to show a tooltip
// TODO: also work out how to convey datasets hidden by zoom filter.
get isHiddenByInheritance () {
if (this.isSublayer) {
return !this.parent?.visible
}
return !getGlobalVisibility()
}

// Returns true if this dataset is visible based on its own visibility setting,
// even if globalVisibility is false or its parent is not visible.
// This is used to determine whether the dataset is rendered as checked when
// disabled in the layers menu.
get isLocallyVisible () {
if (this.isVisible) {
return true
}
return this._datasetDefinition.visible
}

get visible () {
if (this.isSublayer) {
return this._datasetDefinition.visible && (this.parent?.visible)
}
return this._datasetDefinition.visible
return this._datasetDefinition.visible && getGlobalVisibility()
}

get symbolAnchor () {
Expand Down
2 changes: 2 additions & 0 deletions plugins/beta/datasets/src/registry/globalDataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ export const calculateOpacity = (opacityValue, parentOpacityValue) => {
return calculateLocalOpacity(opacityValue, parentOpacityValue)
}
}

export const getGlobalVisibility = () => globalState.visible
Loading