Skip to content

Commit

Permalink
Merge pull request #948 from dpc-sdp/feature/map-popup
Browse files Browse the repository at this point in the history
Feature/map popup
  • Loading branch information
dylankelly authored Dec 6, 2023
2 parents 3b26eb7 + da57568 commit 18bd3a3
Show file tree
Hide file tree
Showing 15 changed files with 433 additions and 108 deletions.
21 changes: 15 additions & 6 deletions examples/nuxt-app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,25 @@ export default defineAppConfig({
},
mapPinStyleFn: {
vsbaPinIcons: (feature) => {
const projectType = feature ? feature['field_mappintype_name'][0] : ''
const projectType =
feature && feature['field_mappintype_name']
? feature['field_mappintype_name'][0]
: ''
switch (projectType) {
case 'Early childhood':
return '#7c1792'
case 'New school':
return '#8A2A2B'
case 'School upgrade':
return '#df4809'
case 'New school':
return '#ff941a'
case 'Planning project':
return '#FF9E1B'
case 'Early childhood':
return '#87189D'
case 'Tech school':
return '#00B2A9'
case 'Non-government grant':
return '#71C5E8'
default:
return '#a13434'
return '#333333'
}
}
},
Expand Down
56 changes: 33 additions & 23 deletions examples/nuxt-app/components/global/VSBAMapPopupContent.vue
Original file line number Diff line number Diff line change
@@ -1,42 +1,52 @@
<template>
<div class="vsba-map-popup-content" v-if="!hasMultiple">
<p class="rpl-type-p-small">
{{ selectedFeature[0].field_about_project_processed[0] }}
</p>
<RplTextLink
class="rpl-type-p-small rpl-u-margin-t-4"
:url="formatUrl(selectedFeature[0].url[0])"
<div class="vsba-map-popup-content">
<h4 class="rpl-type-p-small">What's happening?</h4>

<p
v-if="feature.field_project_title?.length === 1"
class="rpl-type-p-small"
>
View page
</RplTextLink>
{{ feature.title[0] }}
</p>
<RplContent v-else class="vsba-map-popup-list">
<ul>
<li v-for="project in feature.field_project_title" :key="project">
{{ project }}
</li>
</ul>
</RplContent>
<p class="rpl-type-p-small rpl-u-margin-t-3">
<RplTextLink :url="formatUrl(feature.url[0])">
View {{ feature.title[0] }}
</RplTextLink>
</p>
</div>
</template>
<script setup lang="ts">
interface Props {
selectedFeature: any
feature: any
}
const props = withDefaults(defineProps<Props>(), {})
const hasMultiple = computed(() => {
return (
Array.isArray(props.selectedFeature) && props.selectedFeature.length > 1
)
})
const formatUrl = (str) => str.replace(/\/site-(\d+)/, '')
const url = computed(() => {
if (!hasMultiple && props.selectedFeature[0].url) {
return props.selectedFeature[0].url[0].replace(/\/site-(\d+)/, '')
}
return false
})
</script>
<style>
.vsba-map-popup-content {
display: flex;
flex-direction: column;
padding: var(--rpl-sp-4);
}
.vsba-map-popup-list ul {
font-size: var(--rpl-type-size-1);
line-height: var(--rpl-type-lh-3);
letter-spacing: var(--rpl-type-ls-1);
}
.vsba-map-popup-list ul li:before {
top: 0.6rem;
}
</style>
61 changes: 43 additions & 18 deletions examples/nuxt-app/components/global/VSBAProjectAreaLayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ const props = withDefaults(defineProps<Props>(), {
areaDataKey: 'field_postcode'
})
const areas = computed(() => {
const matches = props.results.filter((itm) => {
return !itm.lat && itm[props.areaDataKey]
})
return matches
})
const mappedAreas = computed(() => {
return props.results
.filter((itm) => !itm.lat && itm[props.areaDataKey])
.map((area) => `'${area[props.areaDataKey]}'`)
return areas.value.map((area) => `'${area[props.areaDataKey]}'`)
})
const shapeFormat = new GeoJSON()
Expand All @@ -49,16 +54,16 @@ const defaultStyleFn = new Style({
}),
stroke: new Stroke({
color: props.lineColor,
width: 1
width: 2
})
})
const mouseOverStyleFn = new Style({
fill: new Fill({
color: [26, 26, 26, 0.3]
color: [26, 26, 26, 0.15]
}),
stroke: new Stroke({
color: props.lineColor,
width: 1
width: 2
})
})
Expand Down Expand Up @@ -97,21 +102,41 @@ onMounted(async () => {
}
map.on('singleclick', function (evt) {
const clickedFeatures = []
// We need to keep track of features that are clicked outside of the shape layer, so that pins can take priority over the shape
const outOfLayerClickedFeatures = []
// Get the features at the click position
const feature = map.forEachFeatureAtPixel(evt.pixel, layerFilter, {
hitTolerance: 5
})
if (feature) {
const matchingResult = props.results.find((itm) => {
return itm.field_postcode[0] === feature?.get('postcode')
})
map.forEachFeatureAtPixel(
evt.pixel,
(f, layer) => {
if (layer.get('title') === layerIdentifier) {
clickedFeatures.push(f)
} else {
outOfLayerClickedFeatures.push(f)
}
},
{
hitTolerance: 5
}
)
popup.value.isArea = true
popup.value.feature = [matchingResult]
popup.value.isOpen = true
popup.value.position = feature.getGeometry().flatCoordinates
centerOnPopup(map, popup)
if (outOfLayerClickedFeatures.length || !clickedFeatures.length) {
return
}
const feature = clickedFeatures[0]
const matchingResult = areas.value.filter((itm) => {
return itm.field_postcode[0] === feature?.get('postcode')
})
popup.value.isArea = true
popup.value.feature = Array.isArray(matchingResult)
? matchingResult
: [matchingResult]
popup.value.isOpen = true
popup.value.position = evt.coordinate
centerOnPopup(map, popup)
})
// Add a pointermove event listener to the map to detect shape hover
map.on('pointermove', function (evt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Feature: Custom Collection
And the search autocomplete request is stubbed with "/search-listing/suggestions/none" fixture
Given I am using a "macbook-16" device

@mockserver
@mockserver @focus
Scenario: Custom collection
Given the "/api/tide/elasticsearch/sdp_data_pipelines_scl/_search" network request is stubbed with fixture "/landingpage/custom-collection/response" and status 200 as alias "cslReq"
Given I visit the page "/custom-collection"
Expand Down
50 changes: 50 additions & 0 deletions examples/nuxt-app/test/fixtures/map-table/ise/aggregations
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2129,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"category": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Early childhood",
"doc_count": 274
},
{
"key": "New school",
"doc_count": 87
},
{
"key": "Non-government grant",
"doc_count": 198
},
{
"key": "Planning",
"doc_count": 13
},
{
"key": "School upgrade",
"doc_count": 991
},
{
"key": "Tech school",
"doc_count": 10
}
]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,25 @@
</template>
</template>
<template #popupContent="{ selectedFeatures }">
<component
:is="popup.content.component"
v-if="selectedFeatures && popup.content.component"
:selectedFeature="selectedFeatures"
></component>
<template v-if="selectedFeatures.length === 1">
<component
:is="popup.content.component"
v-if="popup.content.component"
:feature="selectedFeatures[0]"
></component>
</template>

<template v-if="selectedFeatures.length > 1">
<RplMapPopUpAccordion :features="selectedFeatures">
<template #feature="{ feature }">
<component
:is="popup.content.component"
v-if="popup.content.component"
:feature="feature"
></component>
</template>
</RplMapPopUpAccordion>
</template>
</template>
</RplMap>
<RplMapLegend
Expand Down
16 changes: 6 additions & 10 deletions packages/ripple-ui-core/src/styles/components/_table.css
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,19 @@
background-repeat: no-repeat;
background-position: 0 0, 100% 0;
background-image: linear-gradient(
to right,
to bottom,
var(--local-scrolling-idicator-fade),
transparent
),
linear-gradient(
to left,
var(--local-scrolling-idicator-fade),
transparent
);
background-size: calc(var(--local-scroll-indicator-width) / 2) 100%;
linear-gradient(to top, var(--local-scrolling-idicator-fade), transparent);
background-size: 100% calc (var(--local-scroll-indicator-width) / 2);

&::before,
&::after {
content: '';
z-index: -1;
position: relative;
min-width: var(--local-scroll-indicator-width);
min-height: var(--local-scroll-indicator-width);
background: var(--rpl-clr-light);
}

Expand All @@ -128,8 +124,8 @@
overflow-x: initial;
}

table {
margin: 0 calc(-1 * var(--local-scroll-indicator-width));
.rpl-map-popup__body {
margin: calc(-1 * var(--local-scroll-indicator-width)) 0;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ const overrideStyleFunction = (feature, style) => {
style.setImage(
new Icon({
src: markerIconDefaultSrc,
color: icon
color: icon,
anchor: [0.5, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction'
})
)
} else {
Expand Down
16 changes: 14 additions & 2 deletions packages/ripple-ui-maps/src/components/map/RplMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ const props = withDefaults(defineProps<Props>(), {
let color = feature.color || 'red'
const ic = new Icon({
src: markerIconDefaultSrc,
color
color,
anchor: [0.5, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction'
})
ic.load()
return ic
Expand Down Expand Up @@ -105,6 +108,7 @@ function onMapSingleClick(evt) {
if (point.features.length > 1) {
// if we click on a cluster we zoom to fit all the items in view
zoomToClusterExtent(point.features, popup, map, props.projection)
popup.value.isOpen = false
} else if (point.features.length === 1) {
// if we click on a pin we open the popup
const clickedFeature = point.features[0]
Expand All @@ -121,6 +125,10 @@ function onMapSingleClick(evt) {
centerMap(map, coordinates)
}
}
if (!point || !point.features || point.features.length === 0) {
popup.value.isOpen = false
}
}
function onMapMove(evt) {
Expand Down Expand Up @@ -200,7 +208,11 @@ function onMapMove(evt) {
</ol-vector-layer>

<slot v-if="popupType === 'popover'" name="popup" :popup="popup">
<ol-overlay :position="popup.position" positioning="top-center">
<ol-overlay
:position="popup.position"
positioning="top-center"
:stopEvent="true"
>
<RplMapPopUp
:is-open="popup.isOpen"
:is-area="popup.isArea"
Expand Down
Loading

0 comments on commit 18bd3a3

Please sign in to comment.