From 31e2ce140c7cbfdb734458b79b7ffb382e589ac8 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Thu, 1 Jun 2023 15:59:16 -0400 Subject: [PATCH 01/13] Show legend for compare layer when compare layer is different from base layer --- .../components/common/mapbox/index.tsx | 27 +++++++++++++------ .../components/common/mapbox/layer-legend.tsx | 19 +++++++++---- .../components/common/mapbox/layers/utils.ts | 15 +++++++---- parcel-resolver-veda/index.d.ts | 3 +++ 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/app/scripts/components/common/mapbox/index.tsx b/app/scripts/components/common/mapbox/index.tsx index 58a3779ea..2709602a8 100644 --- a/app/scripts/components/common/mapbox/index.tsx +++ b/app/scripts/components/common/mapbox/index.tsx @@ -28,7 +28,7 @@ import { AoiChangeListenerOverload, AoiState } from '../aoi/types'; import { getLayerComponent, resolveConfigFunctions } from './layers/utils'; import { SimpleMap } from './map'; import MapMessage from './map-message'; -import LayerLegend from './layer-legend'; +import LayerLegend, {LegendContainer} from './layer-legend'; import { useBasemap } from './map-options/use-basemap'; import { DEFAULT_MAP_STYLE_URL } from './map-options/basemaps'; import { Styles } from './layers/styles'; @@ -365,13 +365,25 @@ function MapboxMapComponent(props: MapboxMapProps, ref) { Layer legend for the active layer. */} {baseLayerResolvedData?.legend && ( - + + + + {compareLayerResolvedData?.legend && (compareLayerResolvedData.id !== baseLayerResolvedData.id) && ( + + )} + )} + {/* Maps container @@ -442,7 +454,6 @@ function MapboxMapComponent(props: MapboxMapProps, ref) { boundariesOption={boundariesOption} /> {isMapCompareLoaded && - isComparing && compareLayerResolvedData && CompareLayerComponent && ( { if (stops.length === 1) return stops[0]; @@ -44,18 +44,27 @@ const makeGradient = (stops: string[]) => { const printLegendVal = (val: string | number) => typeof val === 'number' ? formatThousands(val, { shorten: true }) : val; -const LayerLegendSelf = styled.div` +export const LegendContainer = styled.div` position: absolute; z-index: 8; bottom: ${variableGlsp()}; right: ${variableGlsp()}; display: flex; flex-flow: column nowrap; +`; + +const LayerLegendSelf = styled.div` + display: flex; + flex-flow: column nowrap; border-radius: ${themeVal('shape.rounded')}; box-shadow: ${themeVal('boxShadow.elevationB')}; background-color: ${themeVal('color.surface')}; width: 16rem; + &:not(:last-child) { + margin-bottom: ${variableGlsp(0.25)}; + } + &.reveal-enter { opacity: 0; bottom: 4rem; diff --git a/app/scripts/components/common/mapbox/layers/utils.ts b/app/scripts/components/common/mapbox/layers/utils.ts index 0e171f7ac..4cc0501d9 100644 --- a/app/scripts/components/common/mapbox/layers/utils.ts +++ b/app/scripts/components/common/mapbox/layers/utils.ts @@ -92,11 +92,13 @@ export const getCompareLayerData = ( const datasetData = datasets[datasetId]?.data; if (!datasetData) { + // eslint-disable-next-line fp/no-mutating-methods errorHints.push(`Dataset [${datasetId}] not found (compare.datasetId)`); } - const otherLayer = datasetData?.layers?.find((l) => l.id === layerId); + const otherLayer = datasetData?.layers.find((l) => l.id === layerId); if (!otherLayer) { + // eslint-disable-next-line fp/no-mutating-methods errorHints.push( `Layer [${layerId}] not found in dataset [${datasetId}] (compare.layerId)` ); @@ -112,8 +114,11 @@ export const getCompareLayerData = ( return { id: otherLayer.id, type: otherLayer.type, + name: otherLayer?.name, + description: otherLayer?.description, + legend: otherLayer?.legend, stacCol: otherLayer.stacCol, - zoomExtent: zoomExtent || otherLayer.zoomExtent, + zoomExtent: zoomExtent ?? otherLayer.zoomExtent, sourceParams: defaultsDeep({}, sourceParams, otherLayer.sourceParams), ...passThroughProps }; @@ -133,7 +138,7 @@ type Res = T extends Fn ? DatasetDatumReturnType : never : T extends any[] - ? Array> + ? Res[] : T extends object ? ObjResMap : T; @@ -143,10 +148,10 @@ export function resolveConfigFunctions( bag: DatasetDatumFnResolverBag ): Res; /* eslint-disable-next-line no-redeclare */ -export function resolveConfigFunctions>( +export function resolveConfigFunctions( datum: T, bag: DatasetDatumFnResolverBag -): Array>; +): Res[]; /* eslint-disable-next-line no-redeclare */ export function resolveConfigFunctions( datum: any, diff --git a/parcel-resolver-veda/index.d.ts b/parcel-resolver-veda/index.d.ts index 71a0fc003..ccd6813a2 100644 --- a/parcel-resolver-veda/index.d.ts +++ b/parcel-resolver-veda/index.d.ts @@ -66,8 +66,11 @@ declare module 'veda' { export interface DatasetLayerCompareNormalized extends DatasetLayerCommonCompareProps { id: string; + name?: string; + description?: string; stacCol: string; type: DatasetLayerType; + legend?: LayerLegendCategorical | LayerLegendGradient; } // TODO: Complete once known From e2b15b644315827a39b5bbea042e93ed59caac24 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Thu, 1 Jun 2023 16:09:53 -0400 Subject: [PATCH 02/13] Fix type for compare layer --- app/scripts/components/common/mapbox/layers/utils.ts | 6 +++--- parcel-resolver-veda/index.d.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/scripts/components/common/mapbox/layers/utils.ts b/app/scripts/components/common/mapbox/layers/utils.ts index 4cc0501d9..15e0226df 100644 --- a/app/scripts/components/common/mapbox/layers/utils.ts +++ b/app/scripts/components/common/mapbox/layers/utils.ts @@ -114,9 +114,9 @@ export const getCompareLayerData = ( return { id: otherLayer.id, type: otherLayer.type, - name: otherLayer?.name, - description: otherLayer?.description, - legend: otherLayer?.legend, + name: otherLayer.name, + description: otherLayer.description, + legend: otherLayer.legend, stacCol: otherLayer.stacCol, zoomExtent: zoomExtent ?? otherLayer.zoomExtent, sourceParams: defaultsDeep({}, sourceParams, otherLayer.sourceParams), diff --git a/parcel-resolver-veda/index.d.ts b/parcel-resolver-veda/index.d.ts index ccd6813a2..fae742481 100644 --- a/parcel-resolver-veda/index.d.ts +++ b/parcel-resolver-veda/index.d.ts @@ -66,8 +66,8 @@ declare module 'veda' { export interface DatasetLayerCompareNormalized extends DatasetLayerCommonCompareProps { id: string; - name?: string; - description?: string; + name: string; + description: string; stacCol: string; type: DatasetLayerType; legend?: LayerLegendCategorical | LayerLegendGradient; From 2795c47068271efcadb10aac43d5ce3b6a9bb253 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Thu, 1 Jun 2023 16:58:54 -0400 Subject: [PATCH 03/13] Edit compare layer type to reflect legend --- .../components/common/mapbox/index.tsx | 3 ++- .../components/common/mapbox/layers/utils.ts | 2 +- parcel-resolver-veda/index.d.ts | 19 +++++++++++++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/scripts/components/common/mapbox/index.tsx b/app/scripts/components/common/mapbox/index.tsx index 2709602a8..ae2e69a10 100644 --- a/app/scripts/components/common/mapbox/index.tsx +++ b/app/scripts/components/common/mapbox/index.tsx @@ -373,7 +373,8 @@ function MapboxMapComponent(props: MapboxMapProps, ref) { {...baseLayerResolvedData.legend} /> - {compareLayerResolvedData?.legend && (compareLayerResolvedData.id !== baseLayerResolvedData.id) && ( + {compareLayerResolvedData?.legend && + (compareLayerResolvedData.id !== baseLayerResolvedData.id) && ( Date: Mon, 5 Jun 2023 20:36:46 -0400 Subject: [PATCH 04/13] Wrap layers with a container --- .../common/blocks/scrollytelling/index.tsx | 16 ++++---- .../components/common/mapbox/index.tsx | 37 +++++++++---------- .../components/common/mapbox/layer-legend.tsx | 31 ++++++++++------ .../mapbox/layers/raster-timeseries.tsx | 14 ++++++- mock/datasets/no2.data.mdx | 33 ++++++++++++++++- .../air-quality-and-covid-19.discoveries.mdx | 3 +- 6 files changed, 90 insertions(+), 44 deletions(-) diff --git a/app/scripts/components/common/blocks/scrollytelling/index.tsx b/app/scripts/components/common/blocks/scrollytelling/index.tsx index f9faf26f6..e1a123a6b 100644 --- a/app/scripts/components/common/blocks/scrollytelling/index.tsx +++ b/app/scripts/components/common/blocks/scrollytelling/index.tsx @@ -34,7 +34,7 @@ import { S_FAILED, S_SUCCEEDED } from '$utils/status'; import { SimpleMap } from '$components/common/mapbox/map'; import Hug from '$styles/hug'; -import LayerLegend from '$components/common/mapbox/layer-legend'; +import LayerLegendContainer from '$components/common/mapbox/layer-legend'; import MapMessage from '$components/common/mapbox/map-message'; import { MapLoading } from '$components/common/loading-skeleton'; import { HintedError } from '$utils/hinted-error'; @@ -402,12 +402,14 @@ function Scrollytelling(props) { }} classNames='reveal' > - + )} diff --git a/app/scripts/components/common/mapbox/index.tsx b/app/scripts/components/common/mapbox/index.tsx index ae2e69a10..5acb5f60c 100644 --- a/app/scripts/components/common/mapbox/index.tsx +++ b/app/scripts/components/common/mapbox/index.tsx @@ -28,7 +28,7 @@ import { AoiChangeListenerOverload, AoiState } from '../aoi/types'; import { getLayerComponent, resolveConfigFunctions } from './layers/utils'; import { SimpleMap } from './map'; import MapMessage from './map-message'; -import LayerLegend, {LegendContainer} from './layer-legend'; +import LayerLegendContainer from './layer-legend'; import { useBasemap } from './map-options/use-basemap'; import { DEFAULT_MAP_STYLE_URL } from './map-options/basemaps'; import { Styles } from './layers/styles'; @@ -365,27 +365,24 @@ function MapboxMapComponent(props: MapboxMapProps, ref) { Layer legend for the active layer. */} {baseLayerResolvedData?.legend && ( - - - - {compareLayerResolvedData?.legend && - (compareLayerResolvedData.id !== baseLayerResolvedData.id) && ( - - )} - - )} + )} + + {/* Maps container */} diff --git a/app/scripts/components/common/mapbox/layer-legend.tsx b/app/scripts/components/common/mapbox/layer-legend.tsx index 5ab4b9659..83c7638b3 100644 --- a/app/scripts/components/common/mapbox/layer-legend.tsx +++ b/app/scripts/components/common/mapbox/layer-legend.tsx @@ -51,20 +51,16 @@ export const LegendContainer = styled.div` right: ${variableGlsp()}; display: flex; flex-flow: column nowrap; + box-shadow: ${themeVal('boxShadow.elevationB')}; + border-radius: ${themeVal('shape.rounded')}; + background-color: ${themeVal('color.surface')}; `; const LayerLegendSelf = styled.div` display: flex; flex-flow: column nowrap; - border-radius: ${themeVal('shape.rounded')}; - box-shadow: ${themeVal('boxShadow.elevationB')}; - background-color: ${themeVal('color.surface')}; width: 16rem; - - &:not(:last-child) { - margin-bottom: ${variableGlsp(0.25)}; - } - + border-bottom: 1px solid ${themeVal('color.base-100')}; &.reveal-enter { opacity: 0; bottom: 4rem; @@ -87,7 +83,7 @@ const LayerLegendSelf = styled.div` } ${WidgetItemHeader} { - padding: ${variableGlsp(0.5, 0.75)}; + padding: ${variableGlsp(0.25, 0.75)}; } `; @@ -173,7 +169,7 @@ function LayerLegend( const { id, type, title, description } = props; return ( - + )} /> - ); } -export default LayerLegend; + +function LayerLegendContainer({ layers }) { + return ( + + + {layers.map(e=> )} + + + ); +} + +export default LayerLegendContainer; + function LayerCategoricalGraphic(props: LayerLegendCategorical) { const { stops } = props; diff --git a/app/scripts/components/common/mapbox/layers/raster-timeseries.tsx b/app/scripts/components/common/mapbox/layers/raster-timeseries.tsx index c5adfe260..00a7aff26 100644 --- a/app/scripts/components/common/mapbox/layers/raster-timeseries.tsx +++ b/app/scripts/components/common/mapbox/layers/raster-timeseries.tsx @@ -45,7 +45,11 @@ interface MapLayerRasterTimeseriesProps { zoomExtent?: [number, number]; onStatusChange?: (result: { status: ActionStatus; id: string }) => void; isHidden: boolean; +<<<<<<< HEAD idSuffix?: string +======= + suffix?: string +>>>>>>> ddca7f1 (Wrap layers with a container) } export interface StacFeature { @@ -74,7 +78,11 @@ export function MapLayerRasterTimeseries(props: MapLayerRasterTimeseriesProps) { zoomExtent, onStatusChange, isHidden, +<<<<<<< HEAD idSuffix = '' +======= + suffix = '' +>>>>>>> ddca7f1 (Wrap layers with a container) } = props; const theme = useTheme(); @@ -407,7 +415,7 @@ export function MapLayerRasterTimeseries(props: MapLayerRasterTimeseriesProps) { } updateStyle({ - generatorId, + generatorId: 'raster-timeseries' + suffix, sources, layers }); @@ -421,7 +429,11 @@ export function MapLayerRasterTimeseries(props: MapLayerRasterTimeseriesProps) { points, haveSourceParamsChanged, isHidden, +<<<<<<< HEAD generatorId +======= + suffix +>>>>>>> ddca7f1 (Wrap layers with a container) ] ); diff --git a/mock/datasets/no2.data.mdx b/mock/datasets/no2.data.mdx index 8b9ee8396..968ab93a8 100644 --- a/mock/datasets/no2.data.mdx +++ b/mock/datasets/no2.data.mdx @@ -41,8 +41,8 @@ layers: - 0 - 1.5e16 compare: - datasetId: no2 - layerId: no2-monthly + datasetId: nighttime-lights + layerId: nightlights-hd-monthly mapLabel: | ::js ({ dateFns, datetime, compareDatetime }) => { return `${dateFns.format(datetime, 'LLL yyyy')} VS ${dateFns.format(compareDatetime, 'LLL yyyy')}`; @@ -60,6 +60,35 @@ layers: - "#c13b72" - "#461070" - "#050308" + - id: no2-monthly-2 + stacCol: no2-monthly + name: No2 + type: raster + description: Levels in 10¹⁵ molecules cm⁻². Darker colors indicate higher nitrogen dioxide (NO₂) levels associated and more activity. Lighter colors indicate lower levels of NO₂ and less activity. + zoomExtent: + - 0 + - 20 + sourceParams: + resampling_method: bilinear + bidx: 1 + color_formula: gamma r 1.05 + colormap_name: coolwarm + rescale: + - 0 + - 1.5e16 + legend: + unit: + label: Molecules cm3 + type: gradient + min: "Less" + max: "More" + stops: + - "#99c5e0" + - "#f9eaa9" + - "#f7765d" + - "#c13b72" + - "#461070" + - "#050308" - id: no2-monthly-diff stacCol: no2-monthly-diff name: No2 (Diff) diff --git a/mock/discoveries/air-quality-and-covid-19.discoveries.mdx b/mock/discoveries/air-quality-and-covid-19.discoveries.mdx index 97fe0186f..a5710e0df 100644 --- a/mock/discoveries/air-quality-and-covid-19.discoveries.mdx +++ b/mock/discoveries/air-quality-and-covid-19.discoveries.mdx @@ -261,11 +261,10 @@ thematics:
Date: Mon, 5 Jun 2023 20:51:21 -0400 Subject: [PATCH 05/13] Add LayerLegendContainerProps type --- .../components/common/mapbox/layer-legend.tsx | 15 ++++++++++++--- .../common/mapbox/layers/raster-timeseries.tsx | 16 ++-------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/app/scripts/components/common/mapbox/layer-legend.tsx b/app/scripts/components/common/mapbox/layer-legend.tsx index 83c7638b3..5994e10a6 100644 --- a/app/scripts/components/common/mapbox/layer-legend.tsx +++ b/app/scripts/components/common/mapbox/layer-legend.tsx @@ -22,7 +22,6 @@ import { WidgetItemHGroup } from '$styles/panel'; - interface LayerLegendCommonProps{ id: string; title: string; @@ -34,6 +33,10 @@ interface LegendSwatchProps{ stops: string | string[]; } +interface LayerLegendContainerProps { + layers: (LayerLegendCommonProps & (LayerLegendGradient | LayerLegendCategorical))[]; +} + const makeGradient = (stops: string[]) => { if (stops.length === 1) return stops[0]; const d = 100 / (stops.length - 1); @@ -85,6 +88,12 @@ const LayerLegendSelf = styled.div` ${WidgetItemHeader} { padding: ${variableGlsp(0.25, 0.75)}; } + + &:only-child { + ${WidgetItemHeader} { + padding: ${variableGlsp(0.5, 0.75)}; + } + } `; const LegendList = styled.dl` @@ -228,11 +237,11 @@ function LayerLegend( } -function LayerLegendContainer({ layers }) { +function LayerLegendContainer(props: LayerLegendContainerProps) { return ( - {layers.map(e=> )} + {props.layers.map(e=> )} ); diff --git a/app/scripts/components/common/mapbox/layers/raster-timeseries.tsx b/app/scripts/components/common/mapbox/layers/raster-timeseries.tsx index 00a7aff26..9d223097f 100644 --- a/app/scripts/components/common/mapbox/layers/raster-timeseries.tsx +++ b/app/scripts/components/common/mapbox/layers/raster-timeseries.tsx @@ -45,11 +45,7 @@ interface MapLayerRasterTimeseriesProps { zoomExtent?: [number, number]; onStatusChange?: (result: { status: ActionStatus; id: string }) => void; isHidden: boolean; -<<<<<<< HEAD - idSuffix?: string -======= - suffix?: string ->>>>>>> ddca7f1 (Wrap layers with a container) + idSuffix?: string; } export interface StacFeature { @@ -78,11 +74,7 @@ export function MapLayerRasterTimeseries(props: MapLayerRasterTimeseriesProps) { zoomExtent, onStatusChange, isHidden, -<<<<<<< HEAD idSuffix = '' -======= - suffix = '' ->>>>>>> ddca7f1 (Wrap layers with a container) } = props; const theme = useTheme(); @@ -415,7 +407,7 @@ export function MapLayerRasterTimeseries(props: MapLayerRasterTimeseriesProps) { } updateStyle({ - generatorId: 'raster-timeseries' + suffix, + generatorId, sources, layers }); @@ -429,11 +421,7 @@ export function MapLayerRasterTimeseries(props: MapLayerRasterTimeseriesProps) { points, haveSourceParamsChanged, isHidden, -<<<<<<< HEAD generatorId -======= - suffix ->>>>>>> ddca7f1 (Wrap layers with a container) ] ); From bf5a2bb4457ee7d398660305faf09780abafbe2c Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Mon, 5 Jun 2023 21:43:36 -0400 Subject: [PATCH 06/13] WIP - pass layer legend as child --- .../common/blocks/scrollytelling/index.tsx | 18 +++++------ .../components/common/mapbox/index.tsx | 32 ++++++++++--------- .../components/common/mapbox/layer-legend.tsx | 10 +++--- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/app/scripts/components/common/blocks/scrollytelling/index.tsx b/app/scripts/components/common/blocks/scrollytelling/index.tsx index e1a123a6b..c3056715c 100644 --- a/app/scripts/components/common/blocks/scrollytelling/index.tsx +++ b/app/scripts/components/common/blocks/scrollytelling/index.tsx @@ -34,7 +34,7 @@ import { S_FAILED, S_SUCCEEDED } from '$utils/status'; import { SimpleMap } from '$components/common/mapbox/map'; import Hug from '$styles/hug'; -import LayerLegendContainer from '$components/common/mapbox/layer-legend'; +import LayerLegendContainer, { LayerLegend } from '$components/common/mapbox/layer-legend'; import MapMessage from '$components/common/mapbox/map-message'; import { MapLoading } from '$components/common/loading-skeleton'; import { HintedError } from '$utils/hinted-error'; @@ -402,14 +402,14 @@ function Scrollytelling(props) { }} classNames='reveal' > - + + + )} diff --git a/app/scripts/components/common/mapbox/index.tsx b/app/scripts/components/common/mapbox/index.tsx index 5acb5f60c..6ba0aad87 100644 --- a/app/scripts/components/common/mapbox/index.tsx +++ b/app/scripts/components/common/mapbox/index.tsx @@ -28,7 +28,7 @@ import { AoiChangeListenerOverload, AoiState } from '../aoi/types'; import { getLayerComponent, resolveConfigFunctions } from './layers/utils'; import { SimpleMap } from './map'; import MapMessage from './map-message'; -import LayerLegendContainer from './layer-legend'; +import LayerLegendContainer, {LayerLegend} from './layer-legend'; import { useBasemap } from './map-options/use-basemap'; import { DEFAULT_MAP_STYLE_URL } from './map-options/basemaps'; import { Styles } from './layers/styles'; @@ -365,20 +365,22 @@ function MapboxMapComponent(props: MapboxMapProps, ref) { Layer legend for the active layer. */} {baseLayerResolvedData?.legend && ( - )} + + + {compareLayerResolvedData?.legend && + } + + )} diff --git a/app/scripts/components/common/mapbox/layer-legend.tsx b/app/scripts/components/common/mapbox/layer-legend.tsx index 5994e10a6..4f864e5a7 100644 --- a/app/scripts/components/common/mapbox/layer-legend.tsx +++ b/app/scripts/components/common/mapbox/layer-legend.tsx @@ -1,4 +1,4 @@ -import React, { Fragment } from 'react'; +import React, { ReactNode, Fragment } from 'react'; import styled from 'styled-components'; import { LayerLegendCategorical, LayerLegendGradient } from 'veda'; import { AccordionFold, AccordionManager } from '@devseed-ui/accordion'; @@ -34,7 +34,7 @@ interface LegendSwatchProps{ } interface LayerLegendContainerProps { - layers: (LayerLegendCommonProps & (LayerLegendGradient | LayerLegendCategorical))[]; + children: ReactNode | ReactNode[]; } const makeGradient = (stops: string[]) => { @@ -172,13 +172,12 @@ const LegendBody = styled(WidgetItemBodyInner)` } `; -function LayerLegend( +export function LayerLegend( props: LayerLegendCommonProps & (LayerLegendGradient | LayerLegendCategorical) ) { const { id, type, title, description } = props; return ( - - {props.layers.map(e=> )} + {props.children} + {/* {props.layers.map(e=> )} */} ); From 1d7be40f8eac43d16fb66e1a8154e50d6658aa1d Mon Sep 17 00:00:00 2001 From: Daniel da Silva Date: Tue, 6 Jun 2023 12:15:02 +0100 Subject: [PATCH 07/13] Fix legend animation --- .../common/blocks/scrollytelling/index.tsx | 55 +++++--- .../components/common/mapbox/layer-legend.tsx | 125 +++++++++--------- 2 files changed, 95 insertions(+), 85 deletions(-) diff --git a/app/scripts/components/common/blocks/scrollytelling/index.tsx b/app/scripts/components/common/blocks/scrollytelling/index.tsx index c3056715c..6cef5a2d0 100644 --- a/app/scripts/components/common/blocks/scrollytelling/index.tsx +++ b/app/scripts/components/common/blocks/scrollytelling/index.tsx @@ -34,7 +34,9 @@ import { S_FAILED, S_SUCCEEDED } from '$utils/status'; import { SimpleMap } from '$components/common/mapbox/map'; import Hug from '$styles/hug'; -import LayerLegendContainer, { LayerLegend } from '$components/common/mapbox/layer-legend'; +import LayerLegendContainer, { + LayerLegend +} from '$components/common/mapbox/layer-legend'; import MapMessage from '$components/common/mapbox/map-message'; import { MapLoading } from '$components/common/loading-skeleton'; import { HintedError } from '$utils/hinted-error'; @@ -392,27 +394,37 @@ function Scrollytelling(props) { {/* Map overlay element Layer legend for the active layer. + + The SwitchTransition animated between 2 elements, so when there's no + legend we use an empty div to ensure that there's an out animation. + We also have to set the timeout to 1 because the empty div will not + have transitions defined for it. This causes the transitionend + listener to never fire leading to an infinite wait. */} - {activeChapterLayer?.layer.legend && ( - - { - node.addEventListener('transitionend', done, false); - }} - classNames='reveal' - > - - + { + if (!activeChapterLayer) return; + node?.addEventListener('transitionend', done, false); + }} + classNames='reveal' + > + {activeChapterLayer?.layer.legend ? ( + + - - - - )} + /> + + ) : ( +
+ )} + + @@ -421,9 +433,10 @@ function Scrollytelling(props) { if (!resolvedLayer) return null; const { runtimeData, Component: LayerCmp, layer } = resolvedLayer; - const isHidden = (!activeChapterLayerId || - activeChapterLayerId !== runtimeData.id || - activeChapter.showBaseMap); + const isHidden = + !activeChapterLayerId || + activeChapterLayerId !== runtimeData.id || + activeChapter.showBaseMap; if (!LayerCmp) return null; @@ -443,7 +456,7 @@ function Scrollytelling(props) { sourceParams={layer.sourceParams} zoomExtent={layer.zoomExtent} onStatusChange={onLayerLoadSuccess} - idSuffix={'scrolly-'+ lIdx} + idSuffix={'scrolly-' + lIdx} isHidden={isHidden} /> ); diff --git a/app/scripts/components/common/mapbox/layer-legend.tsx b/app/scripts/components/common/mapbox/layer-legend.tsx index 4f864e5a7..49fd9de40 100644 --- a/app/scripts/components/common/mapbox/layer-legend.tsx +++ b/app/scripts/components/common/mapbox/layer-legend.tsx @@ -22,13 +22,13 @@ import { WidgetItemHGroup } from '$styles/panel'; -interface LayerLegendCommonProps{ +interface LayerLegendCommonProps { id: string; title: string; description: string; } -interface LegendSwatchProps{ +interface LegendSwatchProps { hasHelp?: boolean; stops: string | string[]; } @@ -57,13 +57,7 @@ export const LegendContainer = styled.div` box-shadow: ${themeVal('boxShadow.elevationB')}; border-radius: ${themeVal('shape.rounded')}; background-color: ${themeVal('color.surface')}; -`; -const LayerLegendSelf = styled.div` - display: flex; - flex-flow: column nowrap; - width: 16rem; - border-bottom: 1px solid ${themeVal('color.base-100')}; &.reveal-enter { opacity: 0; bottom: 4rem; @@ -84,6 +78,13 @@ const LayerLegendSelf = styled.div` &.reveal-exit-active { transition: bottom 240ms ease-in-out, opacity 240ms ease-in-out; } +`; + +const LayerLegendSelf = styled.div` + display: flex; + flex-flow: column nowrap; + width: 16rem; + border-bottom: 1px solid ${themeVal('color.base-100')}; ${WidgetItemHeader} { padding: ${variableGlsp(0.25, 0.75)}; @@ -178,64 +179,61 @@ export function LayerLegend( const { id, type, title, description } = props; return ( - ( - - - - {title} - {/* Subtitle */} - - - - - - - - {type === 'categorical' && ( - - )} - {type === 'gradient' && ( - - )} - - )} - renderBody={() => ( - - -
- {description || ( -

No info available for this layer.

- )} -
-
-
- )} - /> + ( + + + + {title} + {/* Subtitle */} + + + + + + + + {type === 'categorical' && ( + + )} + {type === 'gradient' && ( + + )} + + )} + renderBody={() => ( + + +
+ {description ||

No info available for this layer.

} +
+
+
+ )} + /> ); } - function LayerLegendContainer(props: LayerLegendContainerProps) { return ( @@ -249,7 +247,6 @@ function LayerLegendContainer(props: LayerLegendContainerProps) { export default LayerLegendContainer; - function LayerCategoricalGraphic(props: LayerLegendCategorical) { const { stops } = props; From 65e433995c176f89c2ab8260906efcc5586626cd Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Tue, 6 Jun 2023 09:53:57 -0400 Subject: [PATCH 08/13] Check if base and compare layer shares the same legend --- app/scripts/components/common/mapbox/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/scripts/components/common/mapbox/index.tsx b/app/scripts/components/common/mapbox/index.tsx index 6ba0aad87..b15792485 100644 --- a/app/scripts/components/common/mapbox/index.tsx +++ b/app/scripts/components/common/mapbox/index.tsx @@ -373,6 +373,7 @@ function MapboxMapComponent(props: MapboxMapProps, ref) { {...baseLayerResolvedData.legend} /> {compareLayerResolvedData?.legend && + (baseLayerResolvedData.id !== compareLayerResolvedData.id) && Date: Tue, 6 Jun 2023 10:45:42 -0400 Subject: [PATCH 09/13] Edit type --- parcel-resolver-veda/index.d.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/parcel-resolver-veda/index.d.ts b/parcel-resolver-veda/index.d.ts index 63f3a9d58..4128560ab 100644 --- a/parcel-resolver-veda/index.d.ts +++ b/parcel-resolver-veda/index.d.ts @@ -39,6 +39,9 @@ declare module 'veda' { extends DatasetLayerCommonCompareProps { stacCol: string; type: DatasetLayerType; + name: string; + description: string; + legend?: LayerLegendCategorical | LayerLegendGradient; } export interface DatasetLayerCompareInternal @@ -82,7 +85,18 @@ declare module 'veda' { description: string; } - export type DatasetLayerCompareNormalized = DatasetLayerCompareNoLegend | DatasetLayerCompareWLegend + + export interface DatasetLayerCompareNormalized + extends DatasetLayerCommonCompareProps { + id: string; + name: string; + description: string; + stacCol: string; + type: DatasetLayerType; + legend?: LayerLegendCategorical | LayerLegendGradient; + } + + // export type DatasetLayerCompareNormalized = DatasetLayerCompareNoLegend | DatasetLayerCompareWLegend // TODO: Complete once known export interface DatasetDatumFnResolverBag { From 90a970c8c8b2de369a89dc3ee7c19add7dd1dd29 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Tue, 6 Jun 2023 11:26:34 -0400 Subject: [PATCH 10/13] Edit style --- app/scripts/components/common/mapbox/layer-legend.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/scripts/components/common/mapbox/layer-legend.tsx b/app/scripts/components/common/mapbox/layer-legend.tsx index 49fd9de40..2fb39116e 100644 --- a/app/scripts/components/common/mapbox/layer-legend.tsx +++ b/app/scripts/components/common/mapbox/layer-legend.tsx @@ -94,6 +94,7 @@ const LayerLegendSelf = styled.div` ${WidgetItemHeader} { padding: ${variableGlsp(0.5, 0.75)}; } + border-bottom: 0; } `; @@ -167,7 +168,6 @@ const LegendBody = styled(WidgetItemBodyInner)` .scroll-inner { padding: ${variableGlsp(0.5, 0.75)}; } - .shadow-bottom { border-radius: ${themeVal('shape.rounded')}; } @@ -221,7 +221,7 @@ export function LayerLegend( scrollbarsProps={{ autoHeight: true, autoHeightMin: 32, - autoHeightMax: 240 + autoHeightMax: 120 }} >
From 042fa70291683860322ddcb7aecb5fc8686d163b Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Tue, 6 Jun 2023 12:12:48 -0400 Subject: [PATCH 11/13] resize map once loaded --- .../components/common/blocks/scrollytelling/index.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/scripts/components/common/blocks/scrollytelling/index.tsx b/app/scripts/components/common/blocks/scrollytelling/index.tsx index 6cef5a2d0..8d655f3b0 100644 --- a/app/scripts/components/common/blocks/scrollytelling/index.tsx +++ b/app/scripts/components/common/blocks/scrollytelling/index.tsx @@ -67,6 +67,9 @@ const TheMap = styled.div<{ topOffset: number }>` top: ${topOffset}px; height: calc(100vh - ${topOffset}px); `} + .mapboxgl-canvas { + height: 100%; + } `; const TheChapters = styled(Hug)` @@ -465,7 +468,11 @@ function Scrollytelling(props) { className='root' mapRef={mapRef} containerRef={mapContainer} - onLoad={() => setMapLoaded(true)} + onLoad={() => { + setMapLoaded(true); + // Fit the map to the container once loaded. + mapRef.current?.resize(); + }} mapOptions={mapOptions} /> From 6bcf3c8794a1c1360e131037c185026189b66f58 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Wed, 7 Jun 2023 14:17:23 -0400 Subject: [PATCH 12/13] Remove not necessary type --- parcel-resolver-veda/index.d.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/parcel-resolver-veda/index.d.ts b/parcel-resolver-veda/index.d.ts index 4128560ab..db8582ec7 100644 --- a/parcel-resolver-veda/index.d.ts +++ b/parcel-resolver-veda/index.d.ts @@ -72,20 +72,6 @@ declare module 'veda' { stacCol: string; type: DatasetLayerType; } - - interface DatasetLayerCompareNoLegend extends DatasetLayerCompareBase { - legend?: never; - name?: never; - description?: never; - } - - interface DatasetLayerCompareWLegend extends DatasetLayerCompareBase { - legend: LayerLegendCategorical | LayerLegendGradient | undefined; - name: string; - description: string; - } - - export interface DatasetLayerCompareNormalized extends DatasetLayerCommonCompareProps { id: string; From 1ca17925b7dd2a641530663024e572ef505c0d30 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Thu, 15 Jun 2023 11:13:55 -0400 Subject: [PATCH 13/13] Do not show the comparing legend when comparing is not activated, other misc edits --- .../components/common/blocks/scrollytelling/index.tsx | 3 ++- app/scripts/components/common/mapbox/index.tsx | 3 ++- app/scripts/components/common/mapbox/layer-legend.tsx | 9 +++------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/scripts/components/common/blocks/scrollytelling/index.tsx b/app/scripts/components/common/blocks/scrollytelling/index.tsx index 8d655f3b0..695a229ae 100644 --- a/app/scripts/components/common/blocks/scrollytelling/index.tsx +++ b/app/scripts/components/common/blocks/scrollytelling/index.tsx @@ -34,7 +34,8 @@ import { S_FAILED, S_SUCCEEDED } from '$utils/status'; import { SimpleMap } from '$components/common/mapbox/map'; import Hug from '$styles/hug'; -import LayerLegendContainer, { +import { + LayerLegendContainer, LayerLegend } from '$components/common/mapbox/layer-legend'; import MapMessage from '$components/common/mapbox/map-message'; diff --git a/app/scripts/components/common/mapbox/index.tsx b/app/scripts/components/common/mapbox/index.tsx index b15792485..45a7392ba 100644 --- a/app/scripts/components/common/mapbox/index.tsx +++ b/app/scripts/components/common/mapbox/index.tsx @@ -28,7 +28,7 @@ import { AoiChangeListenerOverload, AoiState } from '../aoi/types'; import { getLayerComponent, resolveConfigFunctions } from './layers/utils'; import { SimpleMap } from './map'; import MapMessage from './map-message'; -import LayerLegendContainer, {LayerLegend} from './layer-legend'; +import { LayerLegendContainer, LayerLegend } from './layer-legend'; import { useBasemap } from './map-options/use-basemap'; import { DEFAULT_MAP_STYLE_URL } from './map-options/basemaps'; import { Styles } from './layers/styles'; @@ -373,6 +373,7 @@ function MapboxMapComponent(props: MapboxMapProps, ref) { {...baseLayerResolvedData.legend} /> {compareLayerResolvedData?.legend && + isComparing && (baseLayerResolvedData.id !== compareLayerResolvedData.id) && {props.children} - {/* {props.layers.map(e=> )} */} ); } -export default LayerLegendContainer; - function LayerCategoricalGraphic(props: LayerLegendCategorical) { const { stops } = props;