From 404edbae0758f094c539e7f071c09958bc967a0a Mon Sep 17 00:00:00 2001 From: Ahmed Farouk <93868173+ahmedfarouk2000@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:29:37 +0100 Subject: [PATCH] Feature/f 154 legend color hovering (#126) * feat: add hovering effect on legend colors * feat: update tooltip comp * feat: update legend data with hovering values * fix: replace ternarys with clsx --- src/components/Legend/GradientLegend.tsx | 48 +++++++++--- src/components/Tooltip/Tooltip.tsx | 11 ++- src/domain/constant/legend/mapLegendData.tsx | 76 +++++++++++-------- src/domain/props/ColorsData.tsx | 5 ++ .../props/GradientLegendContainerItem.ts | 4 +- src/domain/props/GradientLegendProps.ts | 4 +- src/domain/props/TooltipProps.tsx | 2 + src/operations/legends/LegendOperations.ts | 4 +- 8 files changed, 105 insertions(+), 49 deletions(-) create mode 100644 src/domain/props/ColorsData.tsx diff --git a/src/components/Legend/GradientLegend.tsx b/src/components/Legend/GradientLegend.tsx index 79a673ce..b7f9e7d5 100644 --- a/src/components/Legend/GradientLegend.tsx +++ b/src/components/Legend/GradientLegend.tsx @@ -1,13 +1,20 @@ +import clsx from 'clsx'; + +import { ColorsData } from '@/domain/props/ColorsData'; import GradientLegendProps from '@/domain/props/GradientLegendProps'; -export default function GradientLegend({ colors, startLabel, endLabel, hasNotAnalyzedPoint }: GradientLegendProps) { - const gradients: string = colors - .map((color: string, index: number) => { - const percentage = (index / (colors.length - 1)) * 100; - return `hsl(var(--nextui-${color})) ${percentage}%`; +import { Tooltip } from '../Tooltip/Tooltip'; + +export default function GradientLegend({ colorsData, startLabel, endLabel, hasNotAnalyzedPoint }: GradientLegendProps) { + const gradients: string = colorsData + .map((colorData: ColorsData, index: number) => { + const percentage = (index / (colorsData.length - 1)) * 100; + return `hsl(var(--nextui-${colorData.color})) ${percentage}%`; }) .join(', '); + const segmentWidth: number = 100 / colorsData.length; + return (
{text}
+{text}
{text}
+{text}
); return ( diff --git a/src/domain/constant/legend/mapLegendData.tsx b/src/domain/constant/legend/mapLegendData.tsx index 17cdb644..6dff0678 100644 --- a/src/domain/constant/legend/mapLegendData.tsx +++ b/src/domain/constant/legend/mapLegendData.tsx @@ -106,7 +106,15 @@ export function mapLegendData( case GlobalInsight.FOOD: legendData.push({ title: 'Prevalence of insufficient food consumption', - colors: ['fcsGradient1', 'fcsGradient2', 'fcsGradient3', 'fcsGradient4', 'fcsGradient5', 'fcsGradient6'], + colorsData: [ + { color: 'fcsGradient1', title: 'Very Low', value: '0-5%' }, + { color: 'fcsGradient2', title: 'Low', value: '5-10%' }, + { color: 'fcsGradient3', title: 'Moderately Low', value: '10-20%' }, + { color: 'fcsGradient4', title: 'Moderately High', value: '20-30%' }, + { color: 'fcsGradient5', title: 'High', value: '30-40%' }, + { color: 'fcsGradient6', title: 'Very High', value: 'Above 40%' }, + ], + startLabel: '0%', endLabel: 'above 40%', popoverInfo: ( @@ -158,17 +166,18 @@ export function mapLegendData( case GlobalInsight.RAINFALL: legendData.push({ title: 'Rainfall', - colors: [ - 'vegetationGradient1', - 'vegetationGradient2', - 'vegetationGradient3', - 'vegetationGradient4', - 'vegetationGradient5', - 'rainfallGradient6', - 'rainfallGradient7', - 'rainfallGradient8', - 'rainfallGradient9', + colorsData: [ + { color: 'vegetationGradient1', value: '<40%' }, + { color: 'vegetationGradient2', value: '40-60%' }, + { color: 'vegetationGradient3', value: '60-80%' }, + { color: 'vegetationGradient4', value: '80-90%' }, + { color: 'vegetationGradient5', value: '90-110%' }, + { color: 'rainfallGradient6', value: '110-120%' }, + { color: 'rainfallGradient7', value: '120-140%' }, + { color: 'rainfallGradient8', value: '140-180%' }, + { color: 'rainfallGradient9', value: '>180%' }, ], + startLabel: '<40%', endLabel: '>180%', popoverInfo: ( @@ -196,17 +205,18 @@ export function mapLegendData( case GlobalInsight.VEGETATION: legendData.push({ title: 'Vegetation', - colors: [ - 'vegetationGradient1', - 'vegetationGradient2', - 'vegetationGradient3', - 'vegetationGradient4', - 'vegetationGradient5', - 'vegetationGradient6', - 'vegetationGradient7', - 'vegetationGradient8', - 'vegetationGradient9', + colorsData: [ + { color: 'vegetationGradient1', value: '<50%' }, + { color: 'vegetationGradient2', value: '50-70%' }, + { color: 'vegetationGradient3', value: '70-80%' }, + { color: 'vegetationGradient4', value: '80-90%' }, + { color: 'vegetationGradient5', value: '90-110%' }, + { color: 'vegetationGradient6', value: '110-120%' }, + { color: 'vegetationGradient7', value: '120-130%' }, + { color: 'vegetationGradient8', value: '130-150%' }, + { color: 'vegetationGradient9', value: '>150%' }, ], + startLabel: '<50%', endLabel: '>150%', popoverInfo: ( @@ -236,14 +246,14 @@ export function mapLegendData( legendData.push({ title: 'Number of people in IPC/CH Phase 3 or above (millions)', hasNotAnalyzedPoint: true, - colors: [ - 'ipcGradient1', - 'ipcGradient2', - 'ipcGradient3', - 'ipcGradient4', - 'ipcGradient5', - 'ipcGradient6', - 'ipcGradient7', + colorsData: [ + { color: 'ipcGradient1', value: '0-0.099' }, + { color: 'ipcGradient2', value: '0.1-0.49' }, + { color: 'ipcGradient3', value: '0.5-0.99' }, + { color: 'ipcGradient4', value: '1.0-2.99' }, + { color: 'ipcGradient5', value: '3.0-4.99' }, + { color: 'ipcGradient6', value: '5.0-9.99' }, + { color: 'ipcGradient7', value: '>10' }, ], startLabel: '0', endLabel: '>10', @@ -356,7 +366,13 @@ export function mapLegendData( } else { legendData.push({ title: 'Risk of Inadequate Micronutrient Intake', - colors: ['ipcGradient1', 'ipcGradient2', 'ipcGradient3', 'ipcGradient4', 'ipcGradient5'], + colorsData: [ + { color: 'ipcGradient1', title: 'Lowest', value: '0-19%' }, + { color: 'ipcGradient2', title: 'Low', value: '20-39%' }, + { color: 'ipcGradient3', title: 'Moderate', value: '40-59%' }, + { color: 'ipcGradient4', title: 'High', value: '60-79%' }, + { color: 'ipcGradient5', title: 'Highest', value: '80-100%' }, + ], startLabel: '0%', endLabel: '100%', popoverInfo: ( diff --git a/src/domain/props/ColorsData.tsx b/src/domain/props/ColorsData.tsx new file mode 100644 index 00000000..786f491b --- /dev/null +++ b/src/domain/props/ColorsData.tsx @@ -0,0 +1,5 @@ +export interface ColorsData { + color: string; + title?: string; + value: string; +} diff --git a/src/domain/props/GradientLegendContainerItem.ts b/src/domain/props/GradientLegendContainerItem.ts index cc301b29..c8df3110 100644 --- a/src/domain/props/GradientLegendContainerItem.ts +++ b/src/domain/props/GradientLegendContainerItem.ts @@ -1,7 +1,9 @@ import { ReactNode } from 'react'; +import { ColorsData } from './ColorsData'; + export interface GradientLegendContainerItem { - colors: string[]; + colorsData: ColorsData[]; title: string; startLabel: string; endLabel: string; diff --git a/src/domain/props/GradientLegendProps.ts b/src/domain/props/GradientLegendProps.ts index c10256fd..bf76f913 100644 --- a/src/domain/props/GradientLegendProps.ts +++ b/src/domain/props/GradientLegendProps.ts @@ -1,5 +1,7 @@ +import { ColorsData } from './ColorsData'; + export default interface GradientLegendProps { - colors: string[]; + colorsData: ColorsData[]; startLabel: string; endLabel: string; hasNotAnalyzedPoint?: boolean; diff --git a/src/domain/props/TooltipProps.tsx b/src/domain/props/TooltipProps.tsx index 325d7473..9879bae0 100644 --- a/src/domain/props/TooltipProps.tsx +++ b/src/domain/props/TooltipProps.tsx @@ -6,4 +6,6 @@ export default interface TooltipProps { text: string; delay?: number; warning?: boolean; + titleStyle?: string; + textStyle?: string; } diff --git a/src/operations/legends/LegendOperations.ts b/src/operations/legends/LegendOperations.ts index bbe17c2a..b025e051 100644 --- a/src/operations/legends/LegendOperations.ts +++ b/src/operations/legends/LegendOperations.ts @@ -6,8 +6,8 @@ export class LegendOperations { return false; } return ( - Array.isArray((value as GradientLegendContainerItem).colors) && - (value as GradientLegendContainerItem).colors.every((color) => typeof color === 'string') + Array.isArray((value as GradientLegendContainerItem).colorsData) && + (value as GradientLegendContainerItem).colorsData.every((colorsData) => typeof colorsData.color === 'string') ); } }