From 1d75a364a5b31f0b01ccba8e0ebf283b9d11d829 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tadeusz=20Miesi=C4=85c?= <tadeusz.miesiac@gmail.com>
Date: Tue, 9 Jan 2024 12:03:16 +0100
Subject: [PATCH] fix(overlays): fixed opacity for overlays generated by entity
 color

---
 package.json                                  |  4 +-
 .../getColorByAvailableProperties.test.ts     | 73 -------------------
 .../getColorByAvailableProperties.ts          | 18 -----
 .../overlaysLayer/getOverlayFeatures.ts       | 48 ------------
 .../overlaysLayer/useGetOverlayColor.test.ts  | 62 ++++++++++++++++
 .../overlaysLayer/useGetOverlayColor.ts       | 73 +++++++++++++++++++
 .../overlaysLayer/useOlMapOverlaysLayer.ts    | 36 +--------
 .../overlaysLayer/useOverlayFeatures.ts       | 49 +++++++++++++
 src/hooks/useTriColorLerp.ts                  | 44 -----------
 src/models/mocks/configurationOptionMock.ts   | 10 +++
 src/redux/configuration/configuration.mock.ts |  1 +
 ...tHexStringColorFromRGBIntWithAlpha.test.ts | 17 +++++
 .../getHexStringColorFromRGBIntWithAlpha.ts   | 16 ++++
 13 files changed, 234 insertions(+), 217 deletions(-)
 delete mode 100644 src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.test.ts
 delete mode 100644 src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.ts
 delete mode 100644 src/components/Map/MapViewer/utils/config/overlaysLayer/getOverlayFeatures.ts
 create mode 100644 src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.test.ts
 create mode 100644 src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts
 create mode 100644 src/components/Map/MapViewer/utils/config/overlaysLayer/useOverlayFeatures.ts
 delete mode 100644 src/hooks/useTriColorLerp.ts
 create mode 100644 src/utils/convert/getHexStringColorFromRGBIntWithAlpha.test.ts
 create mode 100644 src/utils/convert/getHexStringColorFromRGBIntWithAlpha.ts

diff --git a/package.json b/package.json
index 081b8f16..10e8c126 100644
--- a/package.json
+++ b/package.json
@@ -14,8 +14,8 @@
     "check-types": "tsc --pretty --noEmit",
     "prepare": "husky install",
     "postinstall": "husky install",
-    "test": "jest --config ./jest.config.ts --transformIgnorePatterns 'node_modules/(?!@toolz/allow-react)/'",
-    "test:watch": "jest --watch --config ./jest.config.ts --transformIgnorePatterns 'node_modules/(?!(ol|geotiff|quick-lru|.*\\.mjs$))'",
+    "test": "jest --config ./jest.config.ts --transformIgnorePatterns 'node_modules/(?!(ol|geotiff|quick-lru|color-space|color-rgba|color-parse|.*\\.mjs$))'",
+    "test:watch": "jest --watch --config ./jest.config.ts --transformIgnorePatterns 'node_modules/(?!(ol|geotiff|quick-lru|color-space|color-rgba|color-parse|.*\\.mjs$))'",
     "test:ci": "jest --config ./jest.config.ts --collectCoverage --coverageDirectory=\"./coverage\" --ci --reporters=default --reporters=jest-junit --watchAll=false --passWithNoTests --transformIgnorePatterns 'node_modules/(?!(ol|geotiff|quick-lru|color-space|color-rgba|color-parse|.*\\.mjs$))'",
     "test:coverage": "jest --watchAll --coverage --config ./jest.config.ts --transformIgnorePatterns 'node_modules/(?!(ol|geotiff|quick-lru|.*\\.mjs$))'",
     "test:coveragee": "jest --coverage --transformIgnorePatterns 'node_modules/(?!(ol|geotiff|quick-lru|.*\\.mjs$))'",
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.test.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.test.ts
deleted file mode 100644
index 6b71e37e..00000000
--- a/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.test.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import { OverlayBioEntityRender } from '@/types/OLrendering';
-import { getColorByAvailableProperties } from './getColorByAvailableProperties';
-
-describe('getColorByAvailableProperties', () => {
-  const ENTITY: OverlayBioEntityRender = {
-    id: 0,
-    modelId: 0,
-    x1: 0,
-    y1: 0,
-    x2: 0,
-    y2: 0,
-    width: 0,
-    height: 0,
-    value: null,
-    overlayId: 0,
-    color: null,
-  };
-
-  const getHexTricolorGradientColorWithAlpha = jest.fn().mockReturnValue('#FFFFFF');
-  const defaultColor = '#000000';
-
-  beforeEach(() => {
-    jest.clearAllMocks();
-  });
-
-  it('should return the result of getHexTricolorGradientColorWithAlpha if entity has a value equal to 0', () => {
-    const entity = { ...ENTITY, value: 0 };
-    const result = getColorByAvailableProperties(
-      entity,
-      getHexTricolorGradientColorWithAlpha,
-      defaultColor,
-    );
-
-    expect(result).toEqual('#FFFFFF');
-    expect(getHexTricolorGradientColorWithAlpha).toHaveBeenCalledWith(entity.value);
-  });
-
-  it('should return the result of getHexTricolorGradientColorWithAlpha if entity has a value', () => {
-    const entity = { ...ENTITY, value: -0.2137 };
-    const result = getColorByAvailableProperties(
-      entity,
-      getHexTricolorGradientColorWithAlpha,
-      defaultColor,
-    );
-
-    expect(result).toEqual('#FFFFFF');
-    expect(getHexTricolorGradientColorWithAlpha).toHaveBeenCalledWith(entity.value);
-  });
-
-  it('should return the result of convertDecimalToHex if entity has a color', () => {
-    const entity = { ...ENTITY, color: { rgb: -65536, alpha: 0 } }; // red  color
-
-    const result = getColorByAvailableProperties(
-      entity,
-      getHexTricolorGradientColorWithAlpha,
-      defaultColor,
-    );
-
-    expect(result).toEqual('#ff0000');
-    expect(getHexTricolorGradientColorWithAlpha).not.toHaveBeenCalled();
-  });
-
-  it('should return the default color if entity has neither a value nor a color', () => {
-    const result = getColorByAvailableProperties(
-      ENTITY,
-      getHexTricolorGradientColorWithAlpha,
-      defaultColor,
-    );
-
-    expect(result).toEqual('#000000');
-    expect(getHexTricolorGradientColorWithAlpha).not.toHaveBeenCalled();
-  });
-});
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.ts
deleted file mode 100644
index 6cbc9883..00000000
--- a/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { ZERO } from '@/constants/common';
-import type { GetHex3ColorGradientColorWithAlpha } from '@/hooks/useTriColorLerp';
-import { OverlayBioEntityRender } from '@/types/OLrendering';
-import { convertDecimalToHexColor } from '@/utils/convert/convertDecimalToHex';
-
-export const getColorByAvailableProperties = (
-  entity: OverlayBioEntityRender,
-  getHexTricolorGradientColorWithAlpha: GetHex3ColorGradientColorWithAlpha,
-  defaultColor: string,
-): string => {
-  if (typeof entity.value === 'number') {
-    return getHexTricolorGradientColorWithAlpha(entity.value || ZERO);
-  }
-  if (entity.color) {
-    return convertDecimalToHexColor(entity.color.rgb);
-  }
-  return defaultColor;
-};
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/getOverlayFeatures.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/getOverlayFeatures.ts
deleted file mode 100644
index 45723ea8..00000000
--- a/src/components/Map/MapViewer/utils/config/overlaysLayer/getOverlayFeatures.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import type { GetHex3ColorGradientColorWithAlpha } from '@/hooks/useTriColorLerp';
-import { OverlayBioEntityRender } from '@/types/OLrendering';
-import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
-import type Feature from 'ol/Feature';
-import type Polygon from 'ol/geom/Polygon';
-import { OverlayOrder } from '@/redux/overlayBioEntity/overlayBioEntity.utils';
-import { ZERO } from '@/constants/common';
-import { createOverlayGeometryFeature } from './createOverlayGeometryFeature';
-import { getColorByAvailableProperties } from './getColorByAvailableProperties';
-import { getPolygonLatitudeCoordinates } from './getPolygonLatitudeCoordinates';
-
-type GetOverlayFeaturesProps = {
-  bioEntities: OverlayBioEntityRender[];
-  pointToProjection: UsePointToProjectionResult;
-  getHex3ColorGradientColorWithAlpha: GetHex3ColorGradientColorWithAlpha;
-  defaultColor: string;
-  overlaysOrder: OverlayOrder[];
-};
-
-export const getOverlayFeatures = ({
-  bioEntities,
-  pointToProjection,
-  getHex3ColorGradientColorWithAlpha,
-  defaultColor,
-  overlaysOrder,
-}: GetOverlayFeaturesProps): Feature<Polygon>[] =>
-  bioEntities.map(entity => {
-    /**
-     * Depending on number of active overlays
-     * it's required to calculate xMin and xMax coordinates of the polygon
-     * so "entity" might be devided equali between active overlays
-     */
-    const { xMin, xMax } = getPolygonLatitudeCoordinates({
-      width: entity.width,
-      nOverlays: overlaysOrder.length,
-      xMin: entity.x1,
-      overlayIndexBasedOnOrder:
-        overlaysOrder.find(({ id }) => id === entity.overlayId)?.index || ZERO,
-    });
-
-    return createOverlayGeometryFeature(
-      [
-        ...pointToProjection({ x: xMin, y: entity.y1 }),
-        ...pointToProjection({ x: xMax, y: entity.y2 }),
-      ],
-      getColorByAvailableProperties(entity, getHex3ColorGradientColorWithAlpha, defaultColor),
-    );
-  });
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.test.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.test.ts
new file mode 100644
index 00000000..b580a998
--- /dev/null
+++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.test.ts
@@ -0,0 +1,62 @@
+import { renderHook } from '@testing-library/react';
+import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
+import { CONFIGURATION_INITIAL_STORE_MOCKS } from '@/redux/configuration/configuration.mock';
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import { useGetOverlayColor } from './useGetOverlayColor';
+
+describe('useOverlayFeatures - hook', () => {
+  const { Wrapper } = getReduxWrapperWithStore({
+    configuration: {
+      ...CONFIGURATION_INITIAL_STORE_MOCKS,
+    },
+  });
+  const {
+    result: {
+      current: { getOverlayBioEntityColorByAvailableProperties },
+    },
+  } = renderHook(() => useGetOverlayColor(), {
+    wrapper: Wrapper,
+  });
+
+  describe('getOverlayBioEntityColorByAvailableProperties - function', () => {
+    const ENTITY: OverlayBioEntityRender = {
+      id: 0,
+      modelId: 0,
+      x1: 0,
+      y1: 0,
+      x2: 0,
+      y2: 0,
+      width: 0,
+      height: 0,
+      value: null,
+      overlayId: 0,
+      color: null,
+    };
+
+    it('should return color based on value', () => {});
+
+    it('should return the correct result if entity has a value equal to 0', () => {
+      const entity = { ...ENTITY, value: 0 };
+
+      expect(getOverlayBioEntityColorByAvailableProperties(entity)).toEqual('#FFFFFFcc');
+    });
+
+    it('should return the result if entity has a value', () => {
+      const entity = { ...ENTITY, value: -0.2137 };
+
+      expect(getOverlayBioEntityColorByAvailableProperties(entity)).toEqual('#FFC9C9cc');
+    });
+
+    it('should return the correct result if entity has a color but no value', () => {
+      const entity = { ...ENTITY, color: { rgb: -65536, alpha: 0 } }; // red  color
+
+      expect(getOverlayBioEntityColorByAvailableProperties(entity)).toEqual('#ff0000cc');
+    });
+
+    it('should return the default color if entity has neither a value nor a color', () => {
+      const entity = { ...ENTITY };
+
+      expect(getOverlayBioEntityColorByAvailableProperties(entity)).toEqual('#00FF00cc');
+    });
+  });
+});
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts
new file mode 100644
index 00000000..64518c5e
--- /dev/null
+++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts
@@ -0,0 +1,73 @@
+import { useCallback, useMemo } from 'react';
+import { WHITE_HEX_OPACITY_0 } from '@/constants/hexColors';
+import {
+  maxColorValSelector,
+  minColorValSelector,
+  neutralColorValSelector,
+  overlayOpacitySelector,
+  simpleColorValSelector,
+} from '@/redux/configuration/configuration.selectors';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { getHexTricolorGradientColorWithAlpha } from '@/utils/convert/getHexTricolorGradientColorWithAlpha';
+import { ONE, ZERO } from '@/constants/common';
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import { addAlphaToHexString } from '@/utils/convert/addAlphaToHexString';
+import { getHexStringColorFromRGBIntWithAlpha } from '@/utils/convert/getHexStringColorFromRGBIntWithAlpha';
+
+type GetOverlayBioEntityColorByAvailableProperties = (entity: OverlayBioEntityRender) => string;
+
+type UseTriColorLerpReturn = {
+  getOverlayBioEntityColorByAvailableProperties: GetOverlayBioEntityColorByAvailableProperties;
+};
+
+export const useGetOverlayColor = (): UseTriColorLerpReturn => {
+  const minColorValHexString = useAppSelector(minColorValSelector) || '';
+  const maxColorValHexString = useAppSelector(maxColorValSelector) || '';
+  const neutralColorValHexString = useAppSelector(neutralColorValSelector) || '';
+  const overlayOpacityValue = useAppSelector(overlayOpacitySelector) || ONE;
+  const simpleColorValue = useAppSelector(simpleColorValSelector) || WHITE_HEX_OPACITY_0;
+
+  const getHex3ColorGradientColorWithAlpha = useCallback(
+    (position: number) =>
+      getHexTricolorGradientColorWithAlpha({
+        leftColor: minColorValHexString,
+        middleColor: neutralColorValHexString,
+        rightColor: maxColorValHexString,
+        position,
+        alpha: Number(overlayOpacityValue),
+      }),
+    [minColorValHexString, neutralColorValHexString, maxColorValHexString, overlayOpacityValue],
+  );
+
+  const getHexColorFromRGBIntWithAlpha = useCallback(
+    (rgbInt: number) =>
+      getHexStringColorFromRGBIntWithAlpha({ rgbInt, alpha: Number(overlayOpacityValue) }),
+    [overlayOpacityValue],
+  );
+
+  const defaultColorHex = useMemo(
+    () => addAlphaToHexString(simpleColorValue, Number(overlayOpacityValue)),
+    [simpleColorValue, overlayOpacityValue],
+  );
+
+  /**
+   * Entity might have 3 properties that indicates color:
+   * value - which value from [-1,1] range and needs to interpolate between minColorVal, neutralColorVal and maxColorVal
+   * color - which is integer representation of color and needs to be converted to hex string
+   * defaultColor - which is hex string representation of color. It occurs when color and value are not available
+   */
+  const getOverlayBioEntityColorByAvailableProperties = useCallback(
+    (entity: OverlayBioEntityRender) => {
+      if (typeof entity.value === 'number') {
+        return getHex3ColorGradientColorWithAlpha(entity.value || ZERO);
+      }
+      if (entity.color) {
+        return getHexColorFromRGBIntWithAlpha(entity.color.rgb);
+      }
+      return defaultColorHex;
+    },
+    [getHex3ColorGradientColorWithAlpha, getHexColorFromRGBIntWithAlpha, defaultColorHex],
+  );
+
+  return { getOverlayBioEntityColorByAvailableProperties };
+};
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/useOlMapOverlaysLayer.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/useOlMapOverlaysLayer.ts
index fc361c6b..1fb0084b 100644
--- a/src/components/Map/MapViewer/utils/config/overlaysLayer/useOlMapOverlaysLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/useOlMapOverlaysLayer.ts
@@ -3,14 +3,7 @@ import VectorLayer from 'ol/layer/Vector';
 import VectorSource from 'ol/source/Vector';
 import { Feature } from 'ol';
 import { useMemo } from 'react';
-import { usePointToProjection } from '@/utils/map/usePointToProjection';
-import { useTriColorLerp } from '@/hooks/useTriColorLerp';
-import { useAppSelector } from '@/redux/hooks/useAppSelector';
-import {
-  getOverlayOrderSelector,
-  overlayBioEntitiesForCurrentModelSelector,
-} from '@/redux/overlayBioEntity/overlayBioEntity.selector';
-import { getOverlayFeatures } from './getOverlayFeatures';
+import { useOverlayFeatures } from './useOverlayFeatures';
 
 /**
  * Prerequisites: "view" button triggers opening overlays -> it triggers downloading overlayBioEntityData for given overlay for ALL available submaps(models)
@@ -27,34 +20,13 @@ import { getOverlayFeatures } from './getOverlayFeatures';
  */
 
 export const useOlMapOverlaysLayer = (): VectorLayer<VectorSource<Feature<Geometry>>> => {
-  const pointToProjection = usePointToProjection();
-  const { getHex3ColorGradientColorWithAlpha, defaultColorHex } = useTriColorLerp();
-  const bioEntities = useAppSelector(overlayBioEntitiesForCurrentModelSelector);
-  const overlaysOrder = useAppSelector(getOverlayOrderSelector);
-
-  const features = useMemo(
-    () =>
-      getOverlayFeatures({
-        bioEntities,
-        pointToProjection,
-        getHex3ColorGradientColorWithAlpha,
-        defaultColor: defaultColorHex,
-        overlaysOrder,
-      }),
-    [
-      bioEntities,
-      getHex3ColorGradientColorWithAlpha,
-      pointToProjection,
-      defaultColorHex,
-      overlaysOrder,
-    ],
-  );
+  const overlaysFeatures = useOverlayFeatures();
 
   const vectorSource = useMemo(() => {
     return new VectorSource({
-      features,
+      features: overlaysFeatures,
     });
-  }, [features]);
+  }, [overlaysFeatures]);
 
   const overlaysLayer = useMemo(
     () =>
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/useOverlayFeatures.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/useOverlayFeatures.ts
new file mode 100644
index 00000000..06985195
--- /dev/null
+++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/useOverlayFeatures.ts
@@ -0,0 +1,49 @@
+import { useMemo } from 'react';
+import { usePointToProjection } from '@/utils/map/usePointToProjection';
+import type Feature from 'ol/Feature';
+import type Polygon from 'ol/geom/Polygon';
+import { ZERO } from '@/constants/common';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import {
+  getOverlayOrderSelector,
+  overlayBioEntitiesForCurrentModelSelector,
+} from '@/redux/overlayBioEntity/overlayBioEntity.selector';
+import { createOverlayGeometryFeature } from './createOverlayGeometryFeature';
+import { getPolygonLatitudeCoordinates } from './getPolygonLatitudeCoordinates';
+import { useGetOverlayColor } from './useGetOverlayColor';
+
+export const useOverlayFeatures = (): Feature<Polygon>[] => {
+  const pointToProjection = usePointToProjection();
+  const { getOverlayBioEntityColorByAvailableProperties } = useGetOverlayColor();
+  const overlaysOrder = useAppSelector(getOverlayOrderSelector);
+  const bioEntities = useAppSelector(overlayBioEntitiesForCurrentModelSelector);
+
+  const features = useMemo(
+    () =>
+      bioEntities.map(entity => {
+        /**
+         * Depending on number of active overlays
+         * it's required to calculate xMin and xMax coordinates of the polygon
+         * so "entity" might be devided equality between active overlays
+         */
+        const { xMin, xMax } = getPolygonLatitudeCoordinates({
+          width: entity.width,
+          nOverlays: overlaysOrder.length,
+          xMin: entity.x1,
+          overlayIndexBasedOnOrder:
+            overlaysOrder.find(({ id }) => id === entity.overlayId)?.index || ZERO,
+        });
+
+        return createOverlayGeometryFeature(
+          [
+            ...pointToProjection({ x: xMin, y: entity.y1 }),
+            ...pointToProjection({ x: xMax, y: entity.y2 }),
+          ],
+          getOverlayBioEntityColorByAvailableProperties(entity),
+        );
+      }),
+    [overlaysOrder, bioEntities, pointToProjection, getOverlayBioEntityColorByAvailableProperties],
+  );
+
+  return features;
+};
diff --git a/src/hooks/useTriColorLerp.ts b/src/hooks/useTriColorLerp.ts
deleted file mode 100644
index f872b09c..00000000
--- a/src/hooks/useTriColorLerp.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { useCallback } from 'react';
-import { WHITE_HEX_OPACITY_0 } from '@/constants/hexColors';
-import {
-  maxColorValSelector,
-  minColorValSelector,
-  neutralColorValSelector,
-  overlayOpacitySelector,
-  simpleColorValSelector,
-} from '@/redux/configuration/configuration.selectors';
-import { useAppSelector } from '@/redux/hooks/useAppSelector';
-import { getHexTricolorGradientColorWithAlpha } from '@/utils/convert/getHexTricolorGradientColorWithAlpha';
-import { ONE } from '@/constants/common';
-import { addAlphaToHexString } from '../utils/convert/addAlphaToHexString';
-
-export type GetHex3ColorGradientColorWithAlpha = (position: number) => string;
-
-type UseTriColorLerpReturn = {
-  getHex3ColorGradientColorWithAlpha: GetHex3ColorGradientColorWithAlpha;
-  defaultColorHex: string;
-};
-
-export const useTriColorLerp = (): UseTriColorLerpReturn => {
-  const minColorValHexString = useAppSelector(minColorValSelector) || '';
-  const maxColorValHexString = useAppSelector(maxColorValSelector) || '';
-  const neutralColorValHexString = useAppSelector(neutralColorValSelector) || '';
-  const overlayOpacityValue = useAppSelector(overlayOpacitySelector) || ONE;
-  const simpleColorValue = useAppSelector(simpleColorValSelector) || WHITE_HEX_OPACITY_0;
-
-  const getHex3ColorGradientColorWithAlpha = useCallback(
-    (position: number) =>
-      getHexTricolorGradientColorWithAlpha({
-        leftColor: minColorValHexString,
-        middleColor: neutralColorValHexString,
-        rightColor: maxColorValHexString,
-        position,
-        alpha: Number(overlayOpacityValue),
-      }),
-    [minColorValHexString, neutralColorValHexString, maxColorValHexString, overlayOpacityValue],
-  );
-
-  const defaultColorHex = addAlphaToHexString(simpleColorValue, Number(overlayOpacityValue));
-
-  return { getHex3ColorGradientColorWithAlpha, defaultColorHex };
-};
diff --git a/src/models/mocks/configurationOptionMock.ts b/src/models/mocks/configurationOptionMock.ts
index f658402e..c1e6a1e5 100644
--- a/src/models/mocks/configurationOptionMock.ts
+++ b/src/models/mocks/configurationOptionMock.ts
@@ -5,6 +5,7 @@ export const CONFIGURATION_OPTIONS_TYPES_MOCK: string[] = [
   'MAX_COLOR_VAL',
   'SIMPLE_COLOR_VAL',
   'NEUTRAL_COLOR_VAL',
+  'OVERLAY_OPACITY',
 ];
 
 export const CONFIGURATION_OPTIONS_COLOURS_MOCK: ConfigurationOption[] = [
@@ -44,4 +45,13 @@ export const CONFIGURATION_OPTIONS_COLOURS_MOCK: ConfigurationOption[] = [
     value: 'FFFFFF',
     group: 'Overlays',
   },
+  {
+    idObject: 33,
+    type: 'OVERLAY_OPACITY',
+    valueType: 'DOUBLE',
+    commonName: 'Opacity used when drawing data overlays (value between 0.0-1.0)',
+    isServerSide: false,
+    value: '0.8',
+    group: 'Overlays',
+  },
 ];
diff --git a/src/redux/configuration/configuration.mock.ts b/src/redux/configuration/configuration.mock.ts
index d3719904..63800550 100644
--- a/src/redux/configuration/configuration.mock.ts
+++ b/src/redux/configuration/configuration.mock.ts
@@ -29,6 +29,7 @@ export const CONFIGURATION_INITIAL_STORE_MOCKS: ConfigurationState = {
       [CONFIGURATION_OPTIONS_TYPES_MOCK[1]]: CONFIGURATION_OPTIONS_COLOURS_MOCK[1],
       [CONFIGURATION_OPTIONS_TYPES_MOCK[2]]: CONFIGURATION_OPTIONS_COLOURS_MOCK[2],
       [CONFIGURATION_OPTIONS_TYPES_MOCK[3]]: CONFIGURATION_OPTIONS_COLOURS_MOCK[3],
+      [CONFIGURATION_OPTIONS_TYPES_MOCK[4]]: CONFIGURATION_OPTIONS_COLOURS_MOCK[4],
     },
     loading: 'idle',
     error: DEFAULT_ERROR,
diff --git a/src/utils/convert/getHexStringColorFromRGBIntWithAlpha.test.ts b/src/utils/convert/getHexStringColorFromRGBIntWithAlpha.test.ts
new file mode 100644
index 00000000..6b25bbe2
--- /dev/null
+++ b/src/utils/convert/getHexStringColorFromRGBIntWithAlpha.test.ts
@@ -0,0 +1,17 @@
+import { getHexStringColorFromRGBIntWithAlpha } from './getHexStringColorFromRGBIntWithAlpha';
+
+const OPACITY_80 = 0.8;
+
+describe('getHexTricolorGradientColorWithAlpha ', () => {
+  it('should return the correct result with input with negative rgb integer', () => {
+    expect(getHexStringColorFromRGBIntWithAlpha({ rgbInt: -3342388, alpha: OPACITY_80 })).toEqual(
+      '#ccffcccc',
+    );
+  });
+
+  it('should return the correct result with input with positive rgb integer', () => {
+    expect(getHexStringColorFromRGBIntWithAlpha({ rgbInt: 57, alpha: OPACITY_80 })).toEqual(
+      '#000039cc',
+    );
+  });
+});
diff --git a/src/utils/convert/getHexStringColorFromRGBIntWithAlpha.ts b/src/utils/convert/getHexStringColorFromRGBIntWithAlpha.ts
new file mode 100644
index 00000000..1317bd89
--- /dev/null
+++ b/src/utils/convert/getHexStringColorFromRGBIntWithAlpha.ts
@@ -0,0 +1,16 @@
+import { convertDecimalToHexColor } from './convertDecimalToHex';
+import { addAlphaToHexString } from './addAlphaToHexString';
+
+type GetHexStringColorFromRGBIntWithAlphaProps = {
+  rgbInt: number;
+  alpha: number;
+};
+
+export const getHexStringColorFromRGBIntWithAlpha = ({
+  rgbInt,
+  alpha,
+}: GetHexStringColorFromRGBIntWithAlphaProps): string => {
+  const hexStringColor = convertDecimalToHexColor(rgbInt);
+  const hexStringColorWithAlpha = addAlphaToHexString(hexStringColor, alpha);
+  return hexStringColorWithAlpha;
+};
-- 
GitLab