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

Deck-layers/currents #2986

Draft
wants to merge 13 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
SAR_DATAVIEW_SLUG,
VIIRS_MATCH_DATAVIEW_SLUG,
} from 'data/workspaces'
import { CURRENTS_DATAVIEW_ID } from 'features/dataviews/dataviews.mock'
import {
ENCOUNTER_EVENTS_SOURCE_ID,
LOITERING_EVENTS_SOURCE_ID,
Expand Down Expand Up @@ -126,6 +127,13 @@ const workspace: Workspace<WorkspaceState> = {
visible: false,
},
},
{
id: 'currents-instance',
dataviewId: CURRENTS_DATAVIEW_ID,
config: {
visible: true,
},
},
{
id: 'context-layer-graticules',
config: {
Expand Down
38 changes: 37 additions & 1 deletion apps/fishing-map/features/dataviews/dataviews.mock.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
import type { Dataview } from '@globalfishingwatch/api-types'
import { DataviewCategory } from '@globalfishingwatch/api-types'

const dataviews: Dataview[] = []
export const CURRENTS_DATAVIEW_ID = 1111111

const dataviews: Dataview[] = [
{
id: CURRENTS_DATAVIEW_ID,
name: 'Currents mock',
description: 'Currents mock',
slug: 'currents',
app: 'fishing-map',
config: {
type: 'CURRENTS',
},
datasetsConfig: [
{
params: [
{
id: 'type',
value: 'heatmap',
},
],
endpoint: '4wings-tiles',
datasetId: 'public-global-currents-uo:v20231213',
},
{
params: [
{
id: 'type',
value: 'heatmap',
},
],
endpoint: '4wings-tiles',
datasetId: 'public-global-currents-vo:v20231213',
},
],
category: DataviewCategory.Environment,
},
]

export default dataviews
21 changes: 20 additions & 1 deletion apps/fishing-map/features/map/popups/PopupByCategory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
selectApiEventStatus,
} from '../map.slice'

import CurrentsTooltipRow from './categories/CurrentsLayers'
import ReportBufferTooltip from './categories/ReportBufferLayers'
import UserContextTooltipSection from './categories/UserContextLayers'

Expand Down Expand Up @@ -204,11 +205,29 @@ function PopupByCategory({ interaction, type = 'hover' }: PopupByCategoryProps)
const contextFeatures = (features as UserLayerPickingObject[]).filter(
(feature) => feature.subcategory === DataviewType.UserContext
)
const currentsFeatures = (features as FourwingsHeatmapPickingObject[])
.filter((feature) => feature.subcategory === DataviewType.Currents)
.map((feature) => ({
...feature,
// TODO translate this
title: 'Currents',
}))
const environmentalFeatures = (
features as SliceExtendedFourwingsPickingObject[]
).filter((feature) => feature.subcategory !== DataviewType.UserContext)
).filter(
(feature) =>
feature.subcategory !== DataviewType.UserContext &&
feature.subcategory !== DataviewType.Currents
)
return (
<Fragment key={featureCategory}>
{currentsFeatures.map((currentsFeature) => (
<CurrentsTooltipRow
key={currentsFeature.id}
feature={currentsFeature}
showFeaturesDetails={type === 'click'}
/>
))}
<UserContextTooltipSection
features={contextFeatures}
showFeaturesDetails={type === 'click'}
Expand Down
55 changes: 55 additions & 0 deletions apps/fishing-map/features/map/popups/categories/CurrentsLayers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Fragment } from 'react'
import { useTranslation } from 'react-i18next'

import type { FourwingsHeatmapPickingObject } from '@globalfishingwatch/deck-layers'
import { Icon } from '@globalfishingwatch/ui-components'

import I18nNumber from 'features/i18n/i18nNumber'

import popupStyles from '../Popup.module.css'

type CurrentsTooltipRowProps = {
feature: FourwingsHeatmapPickingObject
loading?: boolean
error?: string
showFeaturesDetails: boolean
}

function metersPerSecondToKnots(speedInMps: number): number {
return speedInMps * 1.94384 // Convert m/s to knots
}

function CurrentsTooltipRow({ feature, showFeaturesDetails }: CurrentsTooltipRowProps) {
const { t } = useTranslation()
const angle = feature.sublayers.find((s) => s.id.includes('currents-vo'))?.value
const speed = feature.sublayers.find((s) => s.id.includes('currents-uo'))?.value

if (!angle || !speed) {
return null
}
return (
<Fragment>
<div className={popupStyles.popupSection}>
<span style={{ transform: `rotate(${angle})` }}>
<Icon
icon="vessel"
className={popupStyles.layerIcon}
style={{ color: feature.color, transform: `rotate(${angle - 45}deg)` }}
/>
</span>
<div className={popupStyles.popupSectionContent}>
{showFeaturesDetails && feature.title && (
<h3 className={popupStyles.popupSectionTitle}>{feature.title}</h3>
)}
{speed && (
<span>
<I18nNumber number={metersPerSecondToKnots(speed)} /> {t('common.knots', 'knots')}
</span>
)}
</div>
</div>
</Fragment>
)
}

export default CurrentsTooltipRow
3 changes: 2 additions & 1 deletion apps/fishing-map/features/reports/areas/AreaReport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ export default function Report() {
(d) =>
d.config?.visible === true &&
(d.config?.type === DataviewType.HeatmapAnimated ||
d.config?.type === DataviewType.HeatmapStatic)
d.config?.type === DataviewType.HeatmapStatic ||
d.config?.type === DataviewType.Currents)
),
[dataviews]
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import { formatI18nDate } from 'features/i18n/i18nDate'
import { formatI18nNumber } from 'features/i18n/i18nNumber'
import { getDatasetNameTranslated } from 'features/i18n/utils.datasets'
import ReportActivityEvolution from 'features/reports/shared/activity/ReportActivityEvolution'
import ReportCurrentsGraph from 'features/reports/shared/activity/ReportCurrentsGraph'
import {
useComputeReportTimeSeries,
useReportFeaturesLoading,
useReportFilteredFeatures,
useReportFilteredTimeSeries,
useTimeseriesStats,
} from 'features/reports/shared/activity/reports-activity-timeseries.hooks'
Expand All @@ -31,6 +33,7 @@ function ReportEnvironment() {
const timerange = useSelector(selectTimeRange)
const loading = useReportFeaturesLoading()
const layersTimeseriesFiltered = useReportFilteredTimeSeries()
const layersFilteredFeatures = useReportFilteredFeatures()
const timeseriesStats = useTimeseriesStats()
const environmentalDataviews = useSelector(selectActiveReportDataviews)
const allAvailableIntervals = getAvailableIntervalsInDataviews(environmentalDataviews)
Expand All @@ -42,6 +45,7 @@ function ReportEnvironment() {
<Fragment>
{environmentalDataviews.map((dataview, index) => {
const isDynamic = dataview.config?.type === DataviewType.HeatmapAnimated
const isCurrents = dataview.config?.type === DataviewType.Currents
const { min, mean, max } = timeseriesStats[dataview.id] || {}
const dataset = dataview.datasets?.find((d) => d.type === DatasetTypes.Fourwings)
const title = getDatasetNameTranslated(dataset)
Expand All @@ -54,7 +58,7 @@ function ReportEnvironment() {
<span>{upperFirst(t('common.average', 'Average'))} </span>
)}
<strong>{title}</strong> {unit && <span>({unit})</span>}{' '}
{isDynamic && (
{(isDynamic || isCurrents) && (
<Fragment>
{t('common.between', 'betweeen')}{' '}
<strong>{formatI18nDate(timerange.start)}</strong> {t('common.and', 'and')}{' '}
Expand All @@ -73,9 +77,27 @@ function ReportEnvironment() {
/>
)
) : null}
{isCurrents ? (
isLoading || !layersFilteredFeatures?.[index] ? (
<ReportActivityPlaceholder showHeader={false} />
) : (
<Fragment>
<ReportCurrentsGraph
color={dataview.config?.color}
data={layersFilteredFeatures?.[index]}
/>
{/* TODO: add this graph when we calculate the currents timeseries properly */}
{/* <ReportActivityEvolution
start={timerange.start}
end={timerange.end}
data={layersTimeseriesFiltered?.[index]}
/> */}
</Fragment>
)
) : null}
{!isLoading && min && mean && max && (
<p className={cx(styles.disclaimer, { [styles.marginTop]: isDynamic })}>
{isDynamic
<p className={cx(styles.disclaimer, { [styles.marginTop]: isDynamic || isCurrents })}>
{isDynamic || isCurrents
? t('analysis.statsDisclaimerDynamic', {
defaultValue:
'During this time, the minimum and maximum values at any given {{interval}} and place inside your area were {{min}} {{unit}} and {{max}} {{unit}}.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,21 @@
.graph :global(.recharts-tooltip-cursor) {
stroke: var(--color-secondary-blue);
}

.line {
stroke: var(--color-terthiary-blue);
}

.curentsArc {
stroke: var(--color-white);
stroke-width: 0.5;
}

.curentsArc:hover {
filter: brightness(90%);
}

.labels {
font: var(--font-S);
fill: var(--color-secondary-blue);
}
Loading
Loading