diff --git a/packages/app/src/domain/variants/data-selection/get-variant-bar-chart-data.ts b/packages/app/src/domain/variants/data-selection/get-variant-bar-chart-data.ts index 04f31e1605..64cd45edcb 100644 --- a/packages/app/src/domain/variants/data-selection/get-variant-bar-chart-data.ts +++ b/packages/app/src/domain/variants/data-selection/get-variant-bar-chart-data.ts @@ -28,8 +28,8 @@ export function getVariantBarChartData(variants: NlVariants) { return EMPTY_VALUES; } - const values = firstVariantInList.values.map((value, index) => { - const item = { + const values: VariantChartValue[] = firstVariantInList.values.map((value, index) => { + const item: VariantChartValue = { is_reliable: true, date_start_unix: value.date_start_unix, date_end_unix: value.date_end_unix, diff --git a/packages/app/src/domain/variants/logic/reorder-and-filter.ts b/packages/app/src/domain/variants/logic/reorder-and-filter.ts index 7224789670..983bb63249 100644 --- a/packages/app/src/domain/variants/logic/reorder-and-filter.ts +++ b/packages/app/src/domain/variants/logic/reorder-and-filter.ts @@ -17,9 +17,7 @@ const hasMetricProperty = (config: any): config is { metricProperty: string } => * @param selectionOptions - Currently selected variants */ export const reorderAndFilter = (context: TooltipData, selectionOptions: P[]) => { - const metricAmount = context.config.length; - const totalMetricAmount = selectionOptions.length; - const hasSelectedMetrics = metricAmount !== totalMetricAmount; // Check whether the user has selected any variants from the interactive legend. + const hasSelectedMetrics = context.config.length !== selectionOptions.length; // Check whether the user has selected any variants from the interactive legend. /* Filter out any variants that have an occcurrence value of 0 */ const filteredValues = Object.fromEntries( diff --git a/packages/app/src/domain/variants/logic/use-bar-config.ts b/packages/app/src/domain/variants/logic/use-bar-config.ts index 3d95b3bbf7..7b559dc156 100644 --- a/packages/app/src/domain/variants/logic/use-bar-config.ts +++ b/packages/app/src/domain/variants/logic/use-bar-config.ts @@ -1,7 +1,8 @@ -import { ColorMatch, VariantChartValue, StackedBarConfig, VariantDynamicLabels, VariantsOverTimeGraphText } from '~/domain/variants/data-selection/types'; +import { ColorMatch, VariantChartValue, VariantDynamicLabels, VariantsOverTimeGraphText } from '~/domain/variants/data-selection/types'; import { useMemo } from 'react'; import { getValuesInTimeframe, TimeframeOption } from '@corona-dashboard/common'; import { isPresent } from 'ts-is-present'; +import { BarSeriesDefinition } from '~/components/time-series-chart/logic'; const extractVariantNamesFromValues = (values: VariantChartValue[]) => { return values @@ -12,17 +13,15 @@ const extractVariantNamesFromValues = (values: VariantChartValue[]) => { /** * Create configuration labels for interactive legend - * @param values - * @param selectedOptions - * @param variantLabels - * @param tooltipLabels - * @param colors - * @param timeframe - * @param today + * @param values - Chart data + * @param variantLabels - Mnemonic labels for variants + * @param tooltipLabels - SiteText for other variants + * @param colors - Colors for variants + * @param timeframe - Selected timeframe + * @param today - Date of today */ export const useBarConfig = ( values: VariantChartValue[], - selectedOptions: (keyof VariantChartValue)[], variantLabels: VariantDynamicLabels, tooltipLabels: VariantsOverTimeGraphText, colors: ColorMatch[], @@ -44,7 +43,7 @@ export const useBarConfig = ( .filter((keyName) => activeVariantsInTimeframeNames.includes(keyName)) .reverse(); - const barChartConfig: StackedBarConfig[] = []; + const barChartConfig: BarSeriesDefinition[] = []; listOfVariantCodes.forEach((variantKey) => { const variantCodeName = variantKey.split('_').slice(0, -1).join('_'); @@ -57,23 +56,19 @@ export const useBarConfig = ( if (variantDynamicLabel) { const barChartConfigEntry = { + type: 'bar', metricProperty: variantMetricPropertyName, color: color, label: variantDynamicLabel, + fillOpacity: 1, shape: 'gapped-area', + hideInLegend: true, }; - barChartConfig.push(barChartConfigEntry as StackedBarConfig); + barChartConfig.push(barChartConfigEntry as BarSeriesDefinition); } }); - const selectOptions: StackedBarConfig[] = [...barChartConfig]; - - if (selectedOptions.length > 0) { - const selection = barChartConfig.filter((selectedConfig) => selectedOptions.includes(selectedConfig.metricProperty)); - return [selection, selectOptions]; - } else { - return [barChartConfig, selectOptions]; - } - }, [values, tooltipLabels.tooltip_labels.other_percentage, variantLabels, colors, selectedOptions, timeframe, today]); + return barChartConfig; + }, [values, tooltipLabels.tooltip_labels.other_percentage, variantLabels, colors, timeframe, today]); }; diff --git a/packages/app/src/domain/variants/variants-stacked-bar-chart-tile.tsx b/packages/app/src/domain/variants/variants-stacked-bar-chart-tile.tsx index 6dbc183d15..aad029ebbb 100644 --- a/packages/app/src/domain/variants/variants-stacked-bar-chart-tile.tsx +++ b/packages/app/src/domain/variants/variants-stacked-bar-chart-tile.tsx @@ -1,21 +1,21 @@ -import { ChartTile, MetadataProps } from '~/components'; +import { ChartTile, MetadataProps, TimeSeriesChart } from '~/components'; import { Spacer } from '~/components/base'; -import { TimeframeOption, TimeframeOptionsList } from '@corona-dashboard/common'; +import { DAY_IN_SECONDS, TimeframeOption, TimeframeOptionsList } from '@corona-dashboard/common'; import { useState } from 'react'; -import { ColorMatch, StackedBarConfig, VariantChartValue, VariantDynamicLabels, VariantsOverTimeGraphText } from '~/domain/variants/data-selection/types'; -import { StackedBarTooltipData, StackedChart } from '~/components/stacked-chart'; +import { ColorMatch, VariantChartValue, VariantDynamicLabels, VariantsOverTimeGraphText } from '~/domain/variants/data-selection/types'; import { useBarConfig } from '~/domain/variants/logic/use-bar-config'; -import { InteractiveLegend } from '~/components/interactive-legend'; +import { InteractiveLegend, SelectOption } from '~/components/interactive-legend'; import { useList } from '~/utils/use-list'; import { TooltipSeriesList } from '~/components/time-series-chart/components/tooltip/tooltip-series-list'; import { space } from '~/style/theme'; import { useCurrentDate } from '~/utils/current-date-context'; import { reorderAndFilter } from '~/domain/variants/logic/reorder-and-filter'; +import { getBoundaryDateStartUnix } from '~/utils'; +import { useIntl } from '~/intl'; interface VariantsStackedBarChartTileProps { title: string; description: string; - helpText: string; values: VariantChartValue[]; tooltipLabels: VariantsOverTimeGraphText; variantLabels: VariantDynamicLabels; @@ -36,14 +36,20 @@ const alwaysEnabled: (keyof VariantChartValue)[] = []; * @param metadata - Metadata block * @constructor */ -export const VariantsStackedBarChartTile = ({ title, description, helpText, tooltipLabels, values, variantLabels, variantColors, metadata }: VariantsStackedBarChartTileProps) => { +export const VariantsStackedBarChartTile = ({ title, description, tooltipLabels, values, variantLabels, variantColors, metadata }: VariantsStackedBarChartTileProps) => { const today = useCurrentDate(); - + const { commonTexts } = useIntl(); const { list, toggle, clear } = useList(alwaysEnabled); + const [variantTimeFrame, setVariantTimeFrame] = useState(TimeframeOption.THIRTY_DAYS); + const barSeriesConfig = useBarConfig(values, variantLabels, tooltipLabels, variantColors, variantTimeFrame, today); + + const text = commonTexts.variants_page; - const [variantTimeFrame, setVariantTimeFrame] = useState(TimeframeOption.THREE_MONTHS); + const interactiveLegendOptions: SelectOption[] = barSeriesConfig; - const [barChartConfig, selectionOptions] = useBarConfig(values, list, variantLabels, tooltipLabels, variantColors, variantTimeFrame, today); + const filteredBarConfig = barSeriesConfig.filter((configItem) => list.includes(configItem.metricProperty) || list.length === 0); + + const underReportedDateStart = getBoundaryDateStartUnix(values, 1); const hasTwoColumns = list.length === 0 || list.length > 4; @@ -53,22 +59,30 @@ export const VariantsStackedBarChartTile = ({ title, description, helpText, tool description={description} metadata={metadata} timeframeOptions={TimeframeOptionsList} - timeframeInitialValue={TimeframeOption.THREE_MONTHS} + timeframeInitialValue={TimeframeOption.THIRTY_DAYS} onSelectTimeframe={setVariantTimeFrame} > - + - ( - >(data, selectionOptions)} hasTwoColumns={hasTwoColumns} /> - )} + formatTooltip={(data) => (data, interactiveLegendOptions)} hasTwoColumns={hasTwoColumns} />} + dataOptions={{ + timespanAnnotations: [ + { + start: underReportedDateStart + DAY_IN_SECONDS / 2, + end: Infinity, + label: text.bar_chart_legend_inaccurate, + shortLabel: text.tooltip_labels.innacurate, + }, + ], + }} /> ); diff --git a/packages/app/src/pages/landelijk/varianten.tsx b/packages/app/src/pages/landelijk/varianten.tsx index 0e569c9728..d01e4ab58e 100644 --- a/packages/app/src/pages/landelijk/varianten.tsx +++ b/packages/app/src/pages/landelijk/varianten.tsx @@ -21,6 +21,7 @@ import { useState } from 'react'; import { getArchivedVariantChartData, getVariantBarChartData, getVariantOrderColors, getVariantTableData } from '~/domain/variants/data-selection'; import { VariantsStackedAreaTile, VariantsStackedBarChartTile, VariantsTableTile } from '~/domain/variants'; import { VariantDynamicLabels } from '~/domain/variants/data-selection/types'; +import { NlVariantsVariant } from '@corona-dashboard/common'; const pageMetrics = ['variants', 'named_difference']; @@ -75,7 +76,6 @@ export default function CovidVariantenPage(props: StaticProps(pageText, selectLokalizeTexts); - const [isArchivedContentShown, setIsArchivedContentShown] = useState(false); const metadata = { @@ -86,9 +86,12 @@ export default function CovidVariantenPage(props: StaticProps namedDifferenceEntry.variant_code !== 'other_variants').length; const totalVariants = data.variants - ? data.variants!.values.reduce((accumulator, currentVariant) => (currentVariant.last_value.occurrence > 0 ? 1 + accumulator : accumulator), 0) + ? data.variants!.values.reduce( + (accumulator, currentVariant: NlVariantsVariant) => + currentVariant.last_value.occurrence > 0 && currentVariant.variant_code !== 'other_variants' ? 1 + accumulator : accumulator, + 0 + ) : NaN; const sampleThresholdPassed = data.variants ? data.variants!.values[0].last_value.sample_size > 100 : false; @@ -154,7 +157,6 @@ export default function CovidVariantenPage(props: StaticProps