diff --git a/package-lock.json b/package-lock.json
index dabf49dce6380c53f944390a58b1d5a32e3ba10b..8ac4a5d8aac76245502f5711c51d7396a93512f7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -43,6 +43,7 @@
         "@commitlint/config-conventional": "^17.7.0",
         "@testing-library/jest-dom": "^6.1.3",
         "@testing-library/react": "^14.0.0",
+        "@testing-library/user-event": "^14.5.2",
         "@types/jest": "^29.5.5",
         "@types/react-redux": "^7.1.26",
         "@types/redux-mock-store": "^1.0.6",
@@ -2150,6 +2151,19 @@
         "react-dom": "^18.0.0"
       }
     },
+    "node_modules/@testing-library/user-event": {
+      "version": "14.5.2",
+      "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz",
+      "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=12",
+        "npm": ">=6"
+      },
+      "peerDependencies": {
+        "@testing-library/dom": ">=7.21.4"
+      }
+    },
     "node_modules/@tootallnate/once": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
@@ -15495,6 +15509,13 @@
         "@types/react-dom": "^18.0.0"
       }
     },
+    "@testing-library/user-event": {
+      "version": "14.5.2",
+      "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz",
+      "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==",
+      "dev": true,
+      "requires": {}
+    },
     "@tootallnate/once": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
diff --git a/package.json b/package.json
index 4fb3ac58884eefadf31d01b6ad6a9b331d450875..cc4afb15ce32397ce7e992b86c1b14c1fe6fd3d8 100644
--- a/package.json
+++ b/package.json
@@ -57,6 +57,7 @@
     "@commitlint/config-conventional": "^17.7.0",
     "@testing-library/jest-dom": "^6.1.3",
     "@testing-library/react": "^14.0.0",
+    "@testing-library/user-event": "^14.5.2",
     "@types/jest": "^29.5.5",
     "@types/react-redux": "^7.1.26",
     "@types/redux-mock-store": "^1.0.6",
diff --git a/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.component.test.tsx b/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.component.test.tsx
index 1fb3437a0f779358067827ff463df4d3f8ca76c2..7d514e917e452c4c0f64e81846c12e3e65a7ba35 100644
--- a/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.component.test.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.component.test.tsx
@@ -1,5 +1,4 @@
-import React from 'react';
-import { render, screen, fireEvent } from '@testing-library/react';
+import { fireEvent, render, screen } from '@testing-library/react';
 
 import { CheckboxFilter } from './CheckboxFilter.component';
 
@@ -9,14 +8,16 @@ const options = [
   { id: '3', label: 'Option 3' },
 ];
 
+const currentOptions = [{ id: '2', label: 'Option 2' }];
+
 describe('CheckboxFilter - component', () => {
   it('should render CheckboxFilter properly', () => {
-    render(<CheckboxFilter options={options} />);
+    render(<CheckboxFilter options={options} currentOptions={[]} />);
     expect(screen.getByTestId('search')).toBeInTheDocument();
   });
 
   it('should filter options based on search term', async () => {
-    render(<CheckboxFilter options={options} />);
+    render(<CheckboxFilter options={options} currentOptions={[]} />);
     const searchInput = screen.getByLabelText('search-input');
 
     fireEvent.change(searchInput, { target: { value: `Option 1` } });
@@ -28,7 +29,26 @@ describe('CheckboxFilter - component', () => {
 
   it('should handle checkbox value change', async () => {
     const onCheckedChange = jest.fn();
-    render(<CheckboxFilter options={options} onCheckedChange={onCheckedChange} />);
+    render(
+      <CheckboxFilter currentOptions={[]} options={options} onCheckedChange={onCheckedChange} />,
+    );
+    const checkbox = screen.getByLabelText('Option 1');
+
+    fireEvent.click(checkbox);
+
+    expect(onCheckedChange).toHaveBeenCalledWith([{ id: '1', label: 'Option 1' }]);
+  });
+
+  it('should handle radio value change', async () => {
+    const onCheckedChange = jest.fn();
+    render(
+      <CheckboxFilter
+        currentOptions={[]}
+        type="radio"
+        options={options}
+        onCheckedChange={onCheckedChange}
+      />,
+    );
     const checkbox = screen.getByLabelText('Option 1');
 
     fireEvent.click(checkbox);
@@ -38,7 +58,9 @@ describe('CheckboxFilter - component', () => {
 
   it('should call onFilterChange when searching new term', async () => {
     const onFilterChange = jest.fn();
-    render(<CheckboxFilter options={options} onFilterChange={onFilterChange} />);
+    render(
+      <CheckboxFilter currentOptions={[]} options={options} onFilterChange={onFilterChange} />,
+    );
     const searchInput = screen.getByLabelText('search-input');
 
     fireEvent.change(searchInput, { target: { value: 'Option 1' } });
@@ -46,7 +68,7 @@ describe('CheckboxFilter - component', () => {
     expect(onFilterChange).toHaveBeenCalledWith([{ id: '1', label: 'Option 1' }]);
   });
   it('should display message when no elements are found', async () => {
-    render(<CheckboxFilter options={options} />);
+    render(<CheckboxFilter currentOptions={[]} options={options} />);
     const searchInput = screen.getByLabelText('search-input');
 
     fireEvent.change(searchInput, { target: { value: 'Nonexistent Option' } });
@@ -55,13 +77,15 @@ describe('CheckboxFilter - component', () => {
   });
   it('should display message when options are empty', () => {
     const onFilterChange = jest.fn();
-    render(<CheckboxFilter options={[]} onFilterChange={onFilterChange} />);
+    render(<CheckboxFilter currentOptions={[]} options={[]} onFilterChange={onFilterChange} />);
 
     expect(screen.getByText('No matching elements found.')).toBeInTheDocument();
   });
   it('should handle multiple checkbox selection', () => {
     const onCheckedChange = jest.fn();
-    render(<CheckboxFilter options={options} onCheckedChange={onCheckedChange} />);
+    render(
+      <CheckboxFilter currentOptions={[]} options={options} onCheckedChange={onCheckedChange} />,
+    );
 
     const checkbox1 = screen.getByLabelText('Option 1');
     const checkbox2 = screen.getByLabelText('Option 2');
@@ -74,9 +98,33 @@ describe('CheckboxFilter - component', () => {
       { id: '2', label: 'Option 2' },
     ]);
   });
+
+  it('should handle multiple change of radio selection', () => {
+    const onCheckedChange = jest.fn();
+    render(
+      <CheckboxFilter
+        currentOptions={[]}
+        options={options}
+        onCheckedChange={onCheckedChange}
+        type="radio"
+      />,
+    );
+
+    const checkbox1 = screen.getByLabelText('Option 1');
+    const checkbox2 = screen.getByLabelText('Option 2');
+
+    fireEvent.click(checkbox1);
+    expect(onCheckedChange).toHaveBeenCalledWith([{ id: '1', label: 'Option 1' }]);
+
+    fireEvent.click(checkbox2);
+    expect(onCheckedChange).toHaveBeenCalledWith([{ id: '2', label: 'Option 2' }]);
+  });
+
   it('should handle unchecking a checkbox', () => {
     const onCheckedChange = jest.fn();
-    render(<CheckboxFilter options={options} onCheckedChange={onCheckedChange} />);
+    render(
+      <CheckboxFilter currentOptions={[]} options={options} onCheckedChange={onCheckedChange} />,
+    );
 
     const checkbox = screen.getByLabelText('Option 1');
 
@@ -86,19 +134,19 @@ describe('CheckboxFilter - component', () => {
     expect(onCheckedChange).toHaveBeenCalledWith([]);
   });
   it('should render search input when isSearchEnabled is true', () => {
-    render(<CheckboxFilter options={options} />);
+    render(<CheckboxFilter currentOptions={[]} options={options} />);
     const searchInput = screen.getByLabelText('search-input');
     expect(searchInput).toBeInTheDocument();
   });
 
   it('should not render search input when isSearchEnabled is false', () => {
-    render(<CheckboxFilter options={options} isSearchEnabled={false} />);
+    render(<CheckboxFilter currentOptions={[]} options={options} isSearchEnabled={false} />);
     const searchInput = screen.queryByLabelText('search-input');
     expect(searchInput).not.toBeInTheDocument();
   });
 
   it('should not filter options based on search input when isSearchEnabled is false', () => {
-    render(<CheckboxFilter options={options} isSearchEnabled={false} />);
+    render(<CheckboxFilter currentOptions={[]} options={options} isSearchEnabled={false} />);
     const searchInput = screen.queryByLabelText('search-input');
     expect(searchInput).not.toBeInTheDocument();
     options.forEach(option => {
@@ -106,4 +154,15 @@ describe('CheckboxFilter - component', () => {
       expect(checkboxLabel).toBeInTheDocument();
     });
   });
+
+  it('should set checked param based on currentOptions prop', async () => {
+    render(<CheckboxFilter options={options} currentOptions={currentOptions} />);
+    const option1: HTMLInputElement = screen.getByLabelText('Option 1');
+    const option2: HTMLInputElement = screen.getByLabelText('Option 2');
+    const option3: HTMLInputElement = screen.getByLabelText('Option 3');
+
+    expect(option1.checked).toBe(false);
+    expect(option2.checked).toBe(true);
+    expect(option3.checked).toBe(false);
+  });
 });
diff --git a/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.component.tsx b/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.component.tsx
index 3075991fcde8eea97215405c1116cf1eabc6832a..e02000ab89c0b39f464420e9ff7deb2a1385f205 100644
--- a/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.component.tsx
@@ -1,23 +1,27 @@
 /* eslint-disable no-magic-numbers */
+import lensIcon from '@/assets/vectors/icons/lens.svg';
 import Image from 'next/image';
 import React, { useEffect, useState } from 'react';
-import lensIcon from '@/assets/vectors/icons/lens.svg';
 import { twMerge } from 'tailwind-merge';
-
-export type CheckboxItem = { id: string; label: string };
+import { CheckboxItem } from './CheckboxFilter.types';
+import { OptionInput } from './OptionInput';
 
 type CheckboxFilterProps = {
   options: CheckboxItem[];
+  currentOptions: CheckboxItem[];
   onFilterChange?: (filteredItems: CheckboxItem[]) => void;
   onCheckedChange?: (filteredItems: CheckboxItem[]) => void;
   isSearchEnabled?: boolean;
+  type?: 'checkbox' | 'radio';
 };
 
 export const CheckboxFilter = ({
   options,
+  currentOptions = [],
   onFilterChange,
   onCheckedChange,
   isSearchEnabled = true,
+  type = 'checkbox',
 }: CheckboxFilterProps): React.ReactNode => {
   const [searchTerm, setSearchTerm] = useState('');
   const [filteredOptions, setFilteredOptions] = useState<CheckboxItem[]>(options);
@@ -47,6 +51,11 @@ export const CheckboxFilter = ({
     onCheckedChange?.(newCheckedCheckboxes);
   };
 
+  const handleRadioChange = (option: CheckboxItem): void => {
+    setCheckedCheckboxes([option]);
+    onCheckedChange?.([option]);
+  };
+
   useEffect(() => {
     setFilteredOptions(options);
   }, [options]);
@@ -86,15 +95,13 @@ export const CheckboxFilter = ({
           <ul className="columns-2 gap-8">
             {filteredOptions.map(option => (
               <li key={option.id} className="mb-5 flex items-center gap-x-2">
-                <input
-                  type="checkbox"
-                  id={option.id}
-                  className=" h-4 w-4 shrink-0 accent-primary-500"
-                  onChange={(): void => handleCheckboxChange(option)}
+                <OptionInput
+                  option={option}
+                  currentOptions={currentOptions}
+                  handleRadioChange={handleRadioChange}
+                  handleCheckboxChange={handleCheckboxChange}
+                  type={type}
                 />
-                <label htmlFor={option.id} className="break-all text-sm">
-                  {option.label}
-                </label>
               </li>
             ))}
           </ul>
diff --git a/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.types.ts b/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1f060532b1071c39b9e1897b16e18e1c8bd4b173
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/CheckboxFilter.types.ts
@@ -0,0 +1 @@
+export type CheckboxItem = { id: string; label: string };
diff --git a/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/OptionInput/OptionInput.component.tsx b/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/OptionInput/OptionInput.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..61611797079b5af037629edf9f242f96b01d0f37
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/OptionInput/OptionInput.component.tsx
@@ -0,0 +1,48 @@
+import { twMerge } from 'tailwind-merge';
+import { CheckboxItem } from '../CheckboxFilter.types';
+
+interface Props {
+  option: CheckboxItem;
+  currentOptions: CheckboxItem[];
+  type: 'checkbox' | 'radio';
+  handleCheckboxChange(option: CheckboxItem): void;
+  handleRadioChange(option: CheckboxItem): void;
+}
+
+export const OptionInput = ({
+  option,
+  currentOptions = [],
+  type,
+  handleCheckboxChange,
+  handleRadioChange,
+}: Props): React.ReactNode => {
+  const isChecked = Boolean(currentOptions.find(currentOption => currentOption.id === option.id));
+
+  const handleChange = (): void => {
+    switch (type) {
+      case 'checkbox':
+        handleCheckboxChange(option);
+        break;
+      case 'radio':
+        handleRadioChange(option);
+        break;
+      default:
+        throw new Error(`${type} is unknown option input type`);
+    }
+  };
+
+  return (
+    <label className="flex items-center gap-x-2">
+      <input
+        type={type}
+        className={twMerge(
+          'h-4 w-4 shrink-0 accent-primary-500',
+          type === 'radio' && 'rounded-full',
+        )}
+        onChange={handleChange}
+        checked={isChecked}
+      />
+      <div className="break-all text-sm">{option.label}</div>
+    </label>
+  );
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/OptionInput/index.ts b/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/OptionInput/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..55a9b8f1c138359e5af93aaf0ec5b88cc6e7eeff
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/CheckboxFilter/OptionInput/index.ts
@@ -0,0 +1 @@
+export { OptionInput } from './OptionInput.component';
diff --git a/src/components/Map/Drawer/ExportDrawer/Elements/Elements.component.test.tsx b/src/components/Map/Drawer/ExportDrawer/Elements/Elements.component.test.tsx
index 01d1989e50f63cacf6cc3ec5453cf272bd16d9af..9fa8624b161e701d4836820a0d008319f53c1aa9 100644
--- a/src/components/Map/Drawer/ExportDrawer/Elements/Elements.component.test.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/Elements/Elements.component.test.tsx
@@ -1,20 +1,21 @@
 /* eslint-disable no-magic-numbers */
+import { compartmentPathwaysDetailsFixture } from '@/models/fixtures/compartmentPathways';
+import { configurationFixture } from '@/models/fixtures/configurationFixture';
+import { modelsFixture } from '@/models/fixtures/modelsFixture';
+import { statisticsFixture } from '@/models/fixtures/statisticsFixture';
+import { apiPath } from '@/redux/apiPath';
+import { CONFIGURATION_INITIAL_STORE_MOCK } from '@/redux/configuration/configuration.mock';
+import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
 import { AppDispatch, RootState } from '@/redux/store';
+import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse';
+import { getReduxStoreWithActionsListener } from '@/utils/testing/getReduxStoreActionsListener';
 import { InitialStoreState } from '@/utils/testing/getReduxWrapperWithStore';
 import { render, screen } from '@testing-library/react';
-import { CONFIGURATION_INITIAL_STORE_MOCK } from '@/redux/configuration/configuration.mock';
-import { configurationFixture } from '@/models/fixtures/configurationFixture';
+import { HttpStatusCode } from 'axios';
 import { act } from 'react-dom/test-utils';
-import { statisticsFixture } from '@/models/fixtures/statisticsFixture';
-import { compartmentPathwaysDetailsFixture } from '@/models/fixtures/compartmentPathways';
 import { MockStoreEnhanced } from 'redux-mock-store';
-import { getReduxStoreWithActionsListener } from '@/utils/testing/getReduxStoreActionsListener';
-import { modelsFixture } from '@/models/fixtures/modelsFixture';
-import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse';
-import { apiPath } from '@/redux/apiPath';
-import { HttpStatusCode } from 'axios';
-import { Elements } from './Elements.component';
 import { ELEMENTS_COLUMNS } from '../ExportCompound/ExportCompound.constant';
+import { Elements } from './Elements.component';
 
 const mockedAxiosClient = mockNetworkNewAPIResponse();
 
@@ -37,6 +38,7 @@ const renderComponent = (
 describe('Elements - component', () => {
   it('should render all elements sections', () => {
     renderComponent({
+      ...INITIAL_STORE_STATE_MOCK,
       configuration: {
         ...CONFIGURATION_INITIAL_STORE_MOCK,
         main: {
@@ -95,6 +97,7 @@ describe('Elements - component', () => {
     const SECOND_COMPARMENT_PATHWAY_NAME = compartmentPathwaysDetailsFixture[1].name;
     const SECOND_COMPARMENT_PATHWAY_ID = compartmentPathwaysDetailsFixture[1].id;
     const { store } = renderComponent({
+      ...INITIAL_STORE_STATE_MOCK,
       configuration: {
         ...CONFIGURATION_INITIAL_STORE_MOCK,
         main: {
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/Annotations/Annotations.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Annotations/Annotations.component.tsx
index 29c91f148dff7d8eed15ac08f1c2ef797798fabe..bd065f025aeb52bd4279b9cc3b362ca902049217 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/Annotations/Annotations.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Annotations/Annotations.component.tsx
@@ -1,23 +1,24 @@
-import { useContext } from 'react';
+import { ZERO } from '@/constants/common';
+import { miramiTypesSelector } from '@/redux/configuration/configuration.selectors';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import {
   loadingStatisticsSelector,
   statisticsDataSelector,
 } from '@/redux/statistics/statistics.selectors';
-import { ZERO } from '@/constants/common';
-import { miramiTypesSelector } from '@/redux/configuration/configuration.selectors';
+import { useContext } from 'react';
 import { CheckboxFilter } from '../../CheckboxFilter';
 import { CollapsibleSection } from '../../CollapsibleSection';
 import { ExportContext } from '../ExportCompound.context';
-import { getAnnotationsCheckboxElements } from './Annotations.utils';
 import { AnnotationsType } from './Annotations.types';
+import { getAnnotationsCheckboxElements } from './Annotations.utils';
 
 type AnnotationsProps = {
   type: AnnotationsType;
 };
 
 export const Annotations = ({ type }: AnnotationsProps): React.ReactNode => {
-  const { setAnnotations } = useContext(ExportContext);
+  const { setAnnotations, data } = useContext(ExportContext);
+  const currentAnnotations = data.annotations;
   const loadingStatistics = useAppSelector(loadingStatisticsSelector);
   const statistics = useAppSelector(statisticsDataSelector);
   const miramiTypes = useAppSelector(miramiTypesSelector);
@@ -28,7 +29,11 @@ export const Annotations = ({ type }: AnnotationsProps): React.ReactNode => {
     <CollapsibleSection title="Select annotations">
       {isPending && <p>Loading...</p>}
       {!isPending && checkboxElements && checkboxElements.length > ZERO && (
-        <CheckboxFilter options={checkboxElements} onCheckedChange={setAnnotations} />
+        <CheckboxFilter
+          options={checkboxElements}
+          currentOptions={currentAnnotations}
+          onCheckedChange={setAnnotations}
+        />
       )}
     </CollapsibleSection>
   );
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/DownloadGraphics/DownloadGraphics.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/DownloadGraphics/DownloadGraphics.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..4d5833c4a7007e36b632a98cad2bcd4182bf7255
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/DownloadGraphics/DownloadGraphics.component.tsx
@@ -0,0 +1,13 @@
+import { Button } from '@/shared/Button';
+import { useContext } from 'react';
+import { ExportContext } from '../ExportCompound.context';
+
+export const DownloadGraphics = (): React.ReactNode => {
+  const { handleDownloadGraphics } = useContext(ExportContext);
+
+  return (
+    <div className="mt-6">
+      <Button onClick={handleDownloadGraphics}>Download</Button>
+    </div>
+  );
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/DownloadGraphics/index.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/DownloadGraphics/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..755e63384991acb5a730640c0cb1c04e27058bcf
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/DownloadGraphics/index.ts
@@ -0,0 +1 @@
+export { DownloadGraphics } from './DownloadGraphics.component';
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExcludedCompartmentPathways/ExcludedCompartmentPathways.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExcludedCompartmentPathways/ExcludedCompartmentPathways.component.tsx
index a66fba4e8b3867a8db0c550466eb5e572e210eb3..89007fae92f3b9ba261516041befe04ee004e3d9 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExcludedCompartmentPathways/ExcludedCompartmentPathways.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExcludedCompartmentPathways/ExcludedCompartmentPathways.component.tsx
@@ -1,17 +1,18 @@
-import { useContext } from 'react';
-import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { ZERO } from '@/constants/common';
 import {
   compartmentPathwaysDataSelector,
   loadingCompartmentPathwaysSelector,
 } from '@/redux/compartmentPathways/compartmentPathways.selectors';
-import { ZERO } from '@/constants/common';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { useContext } from 'react';
 import { CheckboxFilter } from '../../CheckboxFilter';
 import { CollapsibleSection } from '../../CollapsibleSection';
 import { ExportContext } from '../ExportCompound.context';
 import { getCompartmentPathwaysCheckboxElements } from '../utils/getCompartmentPathwaysCheckboxElements';
 
 export const ExcludedCompartmentPathways = (): React.ReactNode => {
-  const { setExcludedCompartmentPathways } = useContext(ExportContext);
+  const { setExcludedCompartmentPathways, data } = useContext(ExportContext);
+  const currentExcludedCompartmentPathways = data.excludedCompartmentPathways;
   const loadingCompartmentPathways = useAppSelector(loadingCompartmentPathwaysSelector);
   const isPending = loadingCompartmentPathways === 'pending';
   const compartmentPathways = useAppSelector(compartmentPathwaysDataSelector);
@@ -24,6 +25,7 @@ export const ExcludedCompartmentPathways = (): React.ReactNode => {
       {isCheckboxFilterVisible && (
         <CheckboxFilter
           options={checkboxElements}
+          currentOptions={currentExcludedCompartmentPathways}
           onCheckedChange={setExcludedCompartmentPathways}
         />
       )}
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
index 4936c27c1dde4cf20a7e4b86504bb457d3fe579a..52bc373224656a1994d53acf5fbda4b6a9619273 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.component.tsx
@@ -1,18 +1,28 @@
-import { ReactNode, useCallback, useMemo, useState } from 'react';
-import { useAppSelector } from '@/redux/hooks/useAppSelector';
-import { modelsIdsSelector } from '@/redux/models/models.selectors';
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { currentBackgroundSelector } from '@/redux/backgrounds/background.selectors';
+import { downloadElements, downloadNetwork } from '@/redux/export/export.thunks';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
-import { downloadNetwork, downloadElements } from '@/redux/export/export.thunks';
-import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.component';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { modelsDataSelector, modelsIdsSelector } from '@/redux/models/models.selectors';
+import { ReactNode, useCallback, useMemo, useState } from 'react';
+import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.types';
 import { Annotations } from './Annotations';
-import { ExcludedCompartmentPathways } from './ExcludedCompartmentPathways';
-import { IncludedCompartmentPathways } from './IncludedCompartmentPathways ';
 import { DownloadElements } from './DownloadElements/DownloadElements';
-import { ExportContext } from './ExportCompound.context';
-import { getNetworkDownloadBodyRequest } from './utils/getNetworkBodyRequest';
-import { getDownloadElementsBodyRequest } from './utils/getDownloadElementsBodyRequest';
+import { DownloadGraphics } from './DownloadGraphics';
 import { DownloadNetwork } from './DownloadNetwork/DownloadNetwork';
+import { ExcludedCompartmentPathways } from './ExcludedCompartmentPathways';
 import { ELEMENTS_COLUMNS, NETWORK_COLUMNS } from './ExportCompound.constant';
+import { ExportContext } from './ExportCompound.context';
+import { ImageFormat } from './ImageFormat';
+import { ImageSize } from './ImageSize';
+import { DEFAULT_IMAGE_SIZE } from './ImageSize/ImageSize.constants';
+import { ImageSize as ImageSizeType } from './ImageSize/ImageSize.types';
+import { IncludedCompartmentPathways } from './IncludedCompartmentPathways ';
+import { Submap } from './Submap';
+import { getDownloadElementsBodyRequest } from './utils/getDownloadElementsBodyRequest';
+import { getGraphicsDownloadUrl } from './utils/getGraphicsDownloadUrl';
+import { getModelExportZoom } from './utils/getModelExportZoom';
+import { getNetworkDownloadBodyRequest } from './utils/getNetworkBodyRequest';
 
 type ExportProps = {
   children: ReactNode;
@@ -20,14 +30,19 @@ type ExportProps = {
 
 export const Export = ({ children }: ExportProps): JSX.Element => {
   const dispatch = useAppDispatch();
-  const [annotations, setAnnotations] = useState<CheckboxItem[]>([]);
   const modelIds = useAppSelector(modelsIdsSelector);
+  const currentModels = useAppSelector(modelsDataSelector);
+  const currentBackground = useAppSelector(currentBackgroundSelector);
+  const [annotations, setAnnotations] = useState<CheckboxItem[]>([]);
   const [includedCompartmentPathways, setIncludedCompartmentPathways] = useState<CheckboxItem[]>(
     [],
   );
   const [excludedCompartmentPathways, setExcludedCompartmentPathways] = useState<CheckboxItem[]>(
     [],
   );
+  const [models, setModels] = useState<CheckboxItem[]>([]);
+  const [imageSize, setImageSize] = useState<ImageSizeType>(DEFAULT_IMAGE_SIZE);
+  const [imageFormats, setImageFormats] = useState<CheckboxItem[]>([]);
 
   const handleDownloadElements = useCallback(async () => {
     const body = getDownloadElementsBodyRequest({
@@ -53,15 +68,55 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
     dispatch(downloadNetwork(data));
   }, [modelIds, annotations, includedCompartmentPathways, excludedCompartmentPathways, dispatch]);
 
+  const handleDownloadGraphics = useCallback(async () => {
+    const modelId = models?.[FIRST_ARRAY_ELEMENT]?.id;
+    const model = currentModels.find(currentModel => currentModel.idObject === Number(modelId));
+
+    const url = getGraphicsDownloadUrl({
+      backgroundId: currentBackground?.id,
+      modelId: models?.[FIRST_ARRAY_ELEMENT]?.id,
+      handler: imageFormats?.[FIRST_ARRAY_ELEMENT]?.id,
+      zoom: getModelExportZoom(imageSize.width, model),
+    });
+
+    if (url) {
+      window.open(url);
+    }
+  }, [models, imageFormats, currentBackground, currentModels, imageSize.width]);
+
+  const globalContextDataValue = useMemo(
+    () => ({
+      annotations,
+      includedCompartmentPathways,
+      excludedCompartmentPathways,
+      models,
+      imageSize,
+      imageFormats,
+    }),
+    [
+      annotations,
+      includedCompartmentPathways,
+      excludedCompartmentPathways,
+      models,
+      imageSize,
+      imageFormats,
+    ],
+  );
+
   const globalContextValue = useMemo(
     () => ({
       setAnnotations,
       setIncludedCompartmentPathways,
       setExcludedCompartmentPathways,
+      setModels,
+      setImageSize,
+      setImageFormats,
       handleDownloadElements,
       handleDownloadNetwork,
+      handleDownloadGraphics,
+      data: globalContextDataValue,
     }),
-    [handleDownloadElements, handleDownloadNetwork],
+    [handleDownloadElements, handleDownloadNetwork, globalContextDataValue, handleDownloadGraphics],
   );
 
   return <ExportContext.Provider value={globalContextValue}>{children}</ExportContext.Provider>;
@@ -71,4 +126,8 @@ Export.Annotations = Annotations;
 Export.IncludedCompartmentPathways = IncludedCompartmentPathways;
 Export.ExcludedCompartmentPathways = ExcludedCompartmentPathways;
 Export.DownloadElements = DownloadElements;
+Export.Submap = Submap;
+Export.ImageSize = ImageSize;
+Export.ImageFormat = ImageFormat;
 Export.DownloadNetwork = DownloadNetwork;
+Export.DownloadGraphics = DownloadGraphics;
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.constant.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.constant.ts
index 00c556b71ce7fd73f07b0c106c4af87d8c92b32b..a07ae4c58f7b2fa3ec8ef4f652c1d4c9dbca075b 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.constant.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.constant.ts
@@ -1,3 +1,6 @@
+import { ExportContextType } from './ExportCompound.types';
+import { DEFAULT_IMAGE_SIZE } from './ImageSize/ImageSize.constants';
+
 export const ANNOTATIONS_TYPE = {
   ELEMENTS: 'Elements',
   NETWORK: 'Network',
@@ -43,3 +46,23 @@ export const NETWORK_COLUMNS = [
   'modelId',
   'mapName',
 ];
+
+export const EXPORT_CONTEXT_DEFAULT_VALUE: ExportContextType = {
+  setAnnotations: () => {},
+  setIncludedCompartmentPathways: () => {},
+  setExcludedCompartmentPathways: () => {},
+  setModels: () => {},
+  setImageSize: () => {},
+  setImageFormats: () => {},
+  handleDownloadElements: () => {},
+  handleDownloadNetwork: () => {},
+  handleDownloadGraphics: () => {},
+  data: {
+    annotations: [],
+    includedCompartmentPathways: [],
+    excludedCompartmentPathways: [],
+    models: [],
+    imageFormats: [],
+    imageSize: DEFAULT_IMAGE_SIZE,
+  },
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.context.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.context.ts
index d7d456bd94402625a34234a8f66e20e7bec1c6ee..86f005f09d4dbf9e8ec5643e825c6c0cf33f0486 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.context.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.context.ts
@@ -1,18 +1,5 @@
 import { createContext } from 'react';
-import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.component';
+import { EXPORT_CONTEXT_DEFAULT_VALUE } from './ExportCompound.constant';
+import { ExportContextType } from './ExportCompound.types';
 
-export type ExportContextType = {
-  setAnnotations: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
-  setIncludedCompartmentPathways: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
-  setExcludedCompartmentPathways: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
-  handleDownloadElements: () => void;
-  handleDownloadNetwork: () => void;
-};
-
-export const ExportContext = createContext<ExportContextType>({
-  setAnnotations: () => {},
-  setIncludedCompartmentPathways: () => {},
-  setExcludedCompartmentPathways: () => {},
-  handleDownloadElements: () => {},
-  handleDownloadNetwork: () => {},
-});
+export const ExportContext = createContext<ExportContextType>(EXPORT_CONTEXT_DEFAULT_VALUE);
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.types.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b6e70397e6d6edb1ca1a5220aebb814c3518ff4e
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ExportCompound.types.ts
@@ -0,0 +1,22 @@
+import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.types';
+import { ImageSize } from './ImageSize/ImageSize.types';
+
+export type ExportContextType = {
+  setAnnotations: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
+  setIncludedCompartmentPathways: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
+  setExcludedCompartmentPathways: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
+  setModels: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
+  setImageSize: React.Dispatch<React.SetStateAction<ImageSize>>;
+  setImageFormats: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
+  handleDownloadElements: () => void;
+  handleDownloadNetwork: () => void;
+  handleDownloadGraphics: () => void;
+  data: {
+    annotations: CheckboxItem[];
+    includedCompartmentPathways: CheckboxItem[];
+    excludedCompartmentPathways: CheckboxItem[];
+    models: CheckboxItem[];
+    imageSize: ImageSize;
+    imageFormats: CheckboxItem[];
+  };
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageFormat/ImageFormat.component.test.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageFormat/ImageFormat.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..e8c6df3921c6a70d96caeb543b922cd4e6de6ac8
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageFormat/ImageFormat.component.test.tsx
@@ -0,0 +1,131 @@
+import { configurationFixture } from '@/models/fixtures/configurationFixture';
+import {
+  CONFIGURATION_IMAGE_FORMATS_MOCK,
+  CONFIGURATION_IMAGE_FORMATS_TYPES_MOCK,
+} from '@/models/mocks/configurationFormatsMock';
+import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
+import { StoreType } from '@/redux/store';
+import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
+import { act, render, screen, waitFor } from '@testing-library/react';
+import { ImageFormat } from './ImageFormat.component';
+
+const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
+
+  return (
+    render(
+      <Wrapper>
+        <ImageFormat />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('ImageFormat - component', () => {
+  it('should display formats checkboxes when fetching data is successful', async () => {
+    renderComponent({
+      configuration: {
+        ...INITIAL_STORE_STATE_MOCK.configuration,
+        main: {
+          ...INITIAL_STORE_STATE_MOCK.configuration.main,
+          data: {
+            ...configurationFixture,
+            imageFormats: CONFIGURATION_IMAGE_FORMATS_MOCK,
+          },
+        },
+      },
+    });
+
+    expect(screen.queryByTestId('checkbox-filter')).not.toBeVisible();
+
+    const navigationButton = screen.getByTestId('accordion-item-button');
+
+    act(() => {
+      navigationButton.click();
+    });
+
+    expect(screen.getByText('Image format')).toBeInTheDocument();
+
+    await waitFor(() => {
+      expect(screen.getByTestId('checkbox-filter')).toBeInTheDocument();
+
+      CONFIGURATION_IMAGE_FORMATS_TYPES_MOCK.map(formatName =>
+        expect(screen.getByLabelText(formatName)).toBeInTheDocument(),
+      );
+    });
+  });
+
+  it('should not display formats checkboxes when fetching data fails', async () => {
+    renderComponent({
+      configuration: {
+        ...INITIAL_STORE_STATE_MOCK.configuration,
+        main: {
+          ...INITIAL_STORE_STATE_MOCK.configuration.main,
+          loading: 'failed',
+        },
+      },
+    });
+
+    expect(screen.getByText('Image format')).toBeInTheDocument();
+
+    const navigationButton = screen.getByTestId('accordion-item-button');
+
+    act(() => {
+      navigationButton.click();
+    });
+
+    expect(screen.queryByTestId('checkbox-filter')).not.toBeInTheDocument();
+  });
+
+  it('should not display formats checkboxes when fetched data is empty', async () => {
+    renderComponent({
+      configuration: {
+        ...INITIAL_STORE_STATE_MOCK.configuration,
+        main: {
+          ...INITIAL_STORE_STATE_MOCK.configuration.main,
+          data: {
+            ...configurationFixture,
+            modelFormats: [],
+            imageFormats: [],
+          },
+        },
+      },
+    });
+
+    expect(screen.getByText('Image format')).toBeInTheDocument();
+
+    const navigationButton = screen.getByTestId('accordion-item-button');
+
+    act(() => {
+      navigationButton.click();
+    });
+
+    expect(screen.queryByTestId('checkbox-filter')).not.toBeInTheDocument();
+  });
+
+  it('should display loading message when fetching data is pending', async () => {
+    renderComponent({
+      configuration: {
+        ...INITIAL_STORE_STATE_MOCK.configuration,
+        main: {
+          ...INITIAL_STORE_STATE_MOCK.configuration.main,
+          loading: 'pending',
+        },
+      },
+    });
+
+    expect(screen.getByText('Image format')).toBeInTheDocument();
+
+    const navigationButton = screen.getByTestId('accordion-item-button');
+
+    act(() => {
+      navigationButton.click();
+    });
+
+    expect(screen.getByText('Loading...')).toBeInTheDocument();
+  });
+});
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageFormat/ImageFormat.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageFormat/ImageFormat.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..48ab881789d2445fc5f67e5f6a7ffc6c0b7c85e1
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageFormat/ImageFormat.component.tsx
@@ -0,0 +1,40 @@
+import { ZERO } from '@/constants/common';
+import {
+  imageHandlersSelector,
+  loadingConfigurationMainSelector,
+} from '@/redux/configuration/configuration.selectors';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { useContext } from 'react';
+import { CheckboxFilter } from '../../CheckboxFilter';
+import { CollapsibleSection } from '../../CollapsibleSection';
+import { ExportContext } from '../ExportCompound.context';
+
+export const ImageFormat = (): React.ReactNode => {
+  const { setImageFormats, data } = useContext(ExportContext);
+  const currentImageFormats = data.imageFormats;
+  const imageHandlers = useAppSelector(imageHandlersSelector);
+  const loadingConfigurationMain = useAppSelector(loadingConfigurationMainSelector);
+  const isPending = loadingConfigurationMain === 'pending';
+
+  const mappedElementAnnotations = Object.entries(imageHandlers)
+    .filter(([, handler]) => Boolean(handler))
+    .map(([name, handler]) => ({
+      id: handler,
+      label: name,
+    }));
+
+  return (
+    <CollapsibleSection title="Image format">
+      {isPending && <p>Loading...</p>}
+      {!isPending && mappedElementAnnotations.length > ZERO && (
+        <CheckboxFilter
+          options={mappedElementAnnotations}
+          currentOptions={currentImageFormats}
+          onCheckedChange={setImageFormats}
+          type="radio"
+          isSearchEnabled={false}
+        />
+      )}
+    </CollapsibleSection>
+  );
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageFormat/index.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageFormat/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d4a3f82e0b569abf113ad6cd986ec01895009a2c
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageFormat/index.ts
@@ -0,0 +1 @@
+export { ImageFormat } from './ImageFormat.component';
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.component.test.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..8affdcd88d2778baffcfd7932cb46c13b3784dc7
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.component.test.tsx
@@ -0,0 +1,151 @@
+/* eslint-disable no-magic-numbers */
+import { StoreType } from '@/redux/store';
+import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
+import { fireEvent, render, screen } from '@testing-library/react';
+import { Export } from '../ExportCompound.component';
+import { ImageSize } from './ImageSize.component';
+import { ImageSize as ImageSizeType } from './ImageSize.types';
+
+const renderComponent = (initialStore?: InitialStoreState): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStore);
+
+  return (
+    render(
+      <Wrapper>
+        <Export>
+          <ImageSize />
+        </Export>
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('ImageSize - component', () => {
+  describe('width input', () => {
+    it('renders input with valid value', () => {
+      renderComponent();
+
+      const widthInput: HTMLInputElement = screen.getByLabelText('export graphics width input');
+      expect(widthInput).toBeInTheDocument();
+      expect(widthInput.value).toBe('600');
+    });
+
+    // MAX_WIDTH 600
+    // MAX_HEIGHT 200
+    const widthCases: [number, ImageSizeType][] = [
+      [
+        // default
+        600,
+        {
+          width: 600,
+          height: 200,
+        },
+      ],
+      [
+        // aspect ratio test
+        100,
+        {
+          width: 100,
+          height: 33,
+        },
+      ],
+      [
+        // transform to integer
+        120.2137,
+        {
+          width: 120,
+          height: 40,
+        },
+      ],
+      [
+        // max width
+        997,
+        {
+          width: 600,
+          height: 200,
+        },
+      ],
+    ];
+
+    it.each(widthCases)(
+      'handles input events by setting correct values',
+      async (newWidth, newImageSize) => {
+        renderComponent();
+
+        const widthInput: HTMLInputElement = screen.getByLabelText('export graphics width input');
+        const heightInput: HTMLInputElement = screen.getByLabelText('export graphics height input');
+
+        fireEvent.change(widthInput, { target: { value: `${newWidth}` } });
+
+        expect(widthInput).toHaveValue(newImageSize.width);
+        expect(heightInput).toHaveValue(newImageSize.height);
+      },
+    );
+  });
+
+  describe('height input', () => {
+    it('renders input', () => {
+      renderComponent();
+
+      const heightInput: HTMLInputElement = screen.getByLabelText('export graphics height input');
+      expect(heightInput).toBeInTheDocument();
+      expect(heightInput.value).toBe('200');
+    });
+
+    // MAX_WIDTH 600
+    // MAX_HEIGHT 200
+    const heightCases: [number, ImageSizeType][] = [
+      [
+        // default
+        200,
+        {
+          width: 600,
+          height: 200,
+        },
+      ],
+      [
+        // aspect ratio test
+        100,
+        {
+          width: 300,
+          height: 100,
+        },
+      ],
+      [
+        // transform to integer
+        120.2137,
+        {
+          width: 361,
+          height: 120,
+        },
+      ],
+      [
+        // max height
+        997,
+        {
+          width: 600,
+          height: 200,
+        },
+      ],
+    ];
+
+    it.each(heightCases)(
+      'handles input events by setting correct values',
+      async (newHeight, newImageSize) => {
+        renderComponent();
+
+        const widthInput: HTMLInputElement = screen.getByLabelText('export graphics width input');
+        const heightInput: HTMLInputElement = screen.getByLabelText('export graphics height input');
+
+        fireEvent.change(heightInput, { target: { value: `${newHeight}` } });
+
+        expect(widthInput).toHaveValue(newImageSize.width);
+        expect(heightInput).toHaveValue(newImageSize.height);
+      },
+    );
+  });
+});
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..1a66c44e45e0895fb78380222618fa74666cb59b
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.component.tsx
@@ -0,0 +1,37 @@
+import { CollapsibleSection } from '../../CollapsibleSection';
+import { useImageSize } from './utils/useImageSize';
+
+export const ImageSize = (): React.ReactNode => {
+  const { width, height, handleChangeHeight, handleChangeWidth } = useImageSize();
+
+  return (
+    <CollapsibleSection title="Image size">
+      <div className="flex flex-col gap-4">
+        <label className="flex h-9 items-center gap-4">
+          <span className="w-12">Width:&nbsp;</span>
+          <input
+            className="w-full rounded-[64px] border border-transparent bg-cultured px-4 py-2.5 text-xs font-medium text-font-400 outline-none  hover:border-greyscale-600 focus:border-greyscale-600"
+            name="width"
+            value={width}
+            type="number"
+            aria-label="export graphics width input"
+            onChange={(e): void => {
+              handleChangeWidth(Number(e.target.value));
+            }}
+          />
+        </label>
+        <label className="flex h-9 items-center gap-4">
+          <span className="w-12">Height:&nbsp;</span>
+          <input
+            className="w-full rounded-[64px] border border-transparent bg-cultured px-4 py-2.5 text-xs font-medium text-font-400 outline-none  hover:border-greyscale-600 focus:border-greyscale-600"
+            name="height"
+            value={height}
+            type="number"
+            aria-label="export graphics height input"
+            onChange={(e): void => handleChangeHeight(Number(e.target.value))}
+          />
+        </label>
+      </div>
+    </CollapsibleSection>
+  );
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.constants.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c60ea1d751868d12d199b243da2087c828975739
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.constants.ts
@@ -0,0 +1,14 @@
+import { ImageSize, ModelAspectRatios } from './ImageSize.types';
+
+export const DEFAULT_IMAGE_WIDTH = 600;
+export const DEFAULT_IMAGE_HEIGHT = 200;
+
+export const DEFAULT_IMAGE_SIZE: ImageSize = {
+  width: DEFAULT_IMAGE_WIDTH,
+  height: DEFAULT_IMAGE_HEIGHT,
+};
+
+export const DEFAULT_MODEL_ASPECT_RATIOS: ModelAspectRatios = {
+  vertical: DEFAULT_IMAGE_HEIGHT / DEFAULT_IMAGE_WIDTH,
+  horizontal: DEFAULT_IMAGE_WIDTH / DEFAULT_IMAGE_HEIGHT,
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.types.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a27bad68532fa7cf1974c9ef3892bffb0812fa12
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/ImageSize.types.ts
@@ -0,0 +1,9 @@
+export interface ImageSize {
+  width: number;
+  height: number;
+}
+
+export interface ModelAspectRatios {
+  vertical: number;
+  horizontal: number;
+}
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/index.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..42d58d9a6d287540e3888c4532f2a7eaf008552a
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/index.ts
@@ -0,0 +1 @@
+export { ImageSize } from './ImageSize.component';
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useExportGraphicsSelectedModel.test.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useExportGraphicsSelectedModel.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..20ac3edf4839feec27757384638b0323ad8d4ace
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useExportGraphicsSelectedModel.test.tsx
@@ -0,0 +1,98 @@
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { MODELS_MOCK_SHORT } from '@/models/mocks/modelsMock';
+import { renderHook } from '@testing-library/react';
+import { EXPORT_CONTEXT_DEFAULT_VALUE } from '../../ExportCompound.constant';
+import { getExportContextWithReduxWrapper } from '../../utils/getExportContextWithReduxWrapper';
+import { useExportGraphicsSelectedModel } from './useExportGraphicsSelectedModel';
+
+describe('useExportGraphicsSelectedModel - util', () => {
+  describe('when current selected models is empty', () => {
+    const { Wrapper } = getExportContextWithReduxWrapper(
+      {
+        ...EXPORT_CONTEXT_DEFAULT_VALUE,
+        data: {
+          ...EXPORT_CONTEXT_DEFAULT_VALUE.data,
+          models: [],
+        },
+      },
+      {
+        models: {
+          data: [],
+          loading: 'succeeded',
+          error: { name: '', message: '' },
+        },
+      },
+    );
+
+    const { result } = renderHook(() => useExportGraphicsSelectedModel(), {
+      wrapper: Wrapper,
+    });
+
+    it('should return undefined', () => {
+      expect(result.current).toBeUndefined();
+    });
+  });
+
+  describe('when current selected models has one element', () => {
+    describe('when redux models has selected model', () => {
+      const selectedModel = MODELS_MOCK_SHORT[FIRST_ARRAY_ELEMENT];
+
+      const { Wrapper } = getExportContextWithReduxWrapper(
+        {
+          ...EXPORT_CONTEXT_DEFAULT_VALUE,
+          data: {
+            ...EXPORT_CONTEXT_DEFAULT_VALUE.data,
+            models: [
+              {
+                id: selectedModel.idObject.toString(),
+                label: selectedModel.name,
+              },
+            ],
+          },
+        },
+        {
+          models: {
+            data: MODELS_MOCK_SHORT,
+            loading: 'succeeded',
+            error: { name: '', message: '' },
+          },
+        },
+      );
+
+      const { result } = renderHook(() => useExportGraphicsSelectedModel(), {
+        wrapper: Wrapper,
+      });
+
+      it('should return valid model from redux', () => {
+        expect(result.current).toEqual(selectedModel);
+      });
+    });
+
+    describe('when redux models has not selected model', () => {
+      const { Wrapper } = getExportContextWithReduxWrapper(
+        {
+          ...EXPORT_CONTEXT_DEFAULT_VALUE,
+          data: {
+            ...EXPORT_CONTEXT_DEFAULT_VALUE.data,
+            models: [],
+          },
+        },
+        {
+          models: {
+            data: MODELS_MOCK_SHORT,
+            loading: 'succeeded',
+            error: { name: '', message: '' },
+          },
+        },
+      );
+
+      const { result } = renderHook(() => useExportGraphicsSelectedModel(), {
+        wrapper: Wrapper,
+      });
+
+      it('should return undefined', () => {
+        expect(result.current).toBeUndefined();
+      });
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useExportGraphicsSelectedModel.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useExportGraphicsSelectedModel.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5ee35b4c5e7f3f698e20bcc2563ca9883ec21212
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useExportGraphicsSelectedModel.ts
@@ -0,0 +1,18 @@
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { modelsDataSelector } from '@/redux/models/models.selectors';
+import { MapModel } from '@/types/models';
+import { useContext } from 'react';
+import { useSelector } from 'react-redux';
+import { ExportContext } from '../../ExportCompound.context';
+
+export const useExportGraphicsSelectedModel = (): MapModel | undefined => {
+  const { data } = useContext(ExportContext);
+  const currentSelectedModelId = data.models?.[FIRST_ARRAY_ELEMENT]?.id;
+  const models = useSelector(modelsDataSelector);
+
+  if (!currentSelectedModelId) {
+    return undefined;
+  }
+
+  return models.find(model => model.idObject === Number(currentSelectedModelId));
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useImageSize.test.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useImageSize.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a182496ec28a34e4a70556cf03a87ac885a16b83
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useImageSize.test.ts
@@ -0,0 +1,230 @@
+/* eslint-disable no-magic-numbers */
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { MODELS_MOCK_SHORT } from '@/models/mocks/modelsMock';
+import { renderHook } from '@testing-library/react';
+import { EXPORT_CONTEXT_DEFAULT_VALUE } from '../../ExportCompound.constant';
+import { getExportContextWithReduxWrapper } from '../../utils/getExportContextWithReduxWrapper';
+import { DEFAULT_IMAGE_SIZE } from '../ImageSize.constants';
+import { ImageSize } from '../ImageSize.types';
+import { useImageSize } from './useImageSize';
+
+describe('useImageSize - hook', () => {
+  describe('when there is no selected model', () => {
+    const { Wrapper } = getExportContextWithReduxWrapper(
+      {
+        ...EXPORT_CONTEXT_DEFAULT_VALUE,
+        data: {
+          ...EXPORT_CONTEXT_DEFAULT_VALUE.data,
+          models: [],
+        },
+      },
+      {
+        models: {
+          data: [],
+          loading: 'succeeded',
+          error: { name: '', message: '' },
+        },
+      },
+    );
+
+    const { result } = renderHook(() => useImageSize(), {
+      wrapper: Wrapper,
+    });
+
+    it('should should return default image size', () => {
+      const { width, height } = result.current || {};
+      expect({ width, height }).toEqual(DEFAULT_IMAGE_SIZE);
+    });
+  });
+
+  describe('when there is a selected model', () => {
+    const selectedModel = MODELS_MOCK_SHORT[FIRST_ARRAY_ELEMENT];
+    const setImageSize = jest.fn();
+
+    const { Wrapper } = getExportContextWithReduxWrapper(
+      {
+        ...EXPORT_CONTEXT_DEFAULT_VALUE,
+        setImageSize,
+        data: {
+          ...EXPORT_CONTEXT_DEFAULT_VALUE.data,
+          models: [
+            {
+              id: selectedModel.idObject.toString(),
+              label: selectedModel.name,
+            },
+          ],
+          imageSize: DEFAULT_IMAGE_SIZE,
+        },
+      },
+      {
+        models: {
+          data: MODELS_MOCK_SHORT,
+          loading: 'succeeded',
+          error: { name: '', message: '' },
+        },
+      },
+    );
+
+    renderHook(() => useImageSize(), {
+      wrapper: Wrapper,
+    });
+
+    it('should should set size of selected model', () => {
+      expect(setImageSize).toHaveBeenCalledWith({
+        width: 26779,
+        height: 13503,
+      });
+    });
+  });
+
+  describe('when always', () => {
+    describe('handleChangeHeight', () => {
+      const selectedModel = MODELS_MOCK_SHORT[FIRST_ARRAY_ELEMENT];
+      const setImageSize = jest.fn();
+
+      const { Wrapper } = getExportContextWithReduxWrapper(
+        {
+          ...EXPORT_CONTEXT_DEFAULT_VALUE,
+          setImageSize,
+          data: {
+            ...EXPORT_CONTEXT_DEFAULT_VALUE.data,
+            models: [
+              {
+                id: selectedModel.idObject.toString(),
+                label: selectedModel.name,
+              },
+            ],
+            imageSize: DEFAULT_IMAGE_SIZE,
+          },
+        },
+        {
+          models: {
+            data: MODELS_MOCK_SHORT,
+            loading: 'succeeded',
+            error: { name: '', message: '' },
+          },
+        },
+      );
+
+      const {
+        result: {
+          current: { handleChangeHeight },
+        },
+      } = renderHook(() => useImageSize(), {
+        wrapper: Wrapper,
+      });
+
+      // MAX_WIDTH 26779.25
+      // MAX_HEIGHT 13503.0
+
+      const heightCases: [number, ImageSize][] = [
+        [
+          // aspect ratio test
+          1000,
+          {
+            width: 1983,
+            height: 1000,
+          },
+        ],
+        [
+          // transform to integer
+          997.2137,
+          {
+            width: 1978,
+            height: 997,
+          },
+        ],
+        [
+          // max height
+          26779000,
+          {
+            width: 26779,
+            height: 13503,
+          },
+        ],
+      ];
+
+      it.each(heightCases)(
+        'should set valid height and width values',
+        (newHeight, newImageSize) => {
+          handleChangeHeight(newHeight);
+
+          expect(setImageSize).toHaveBeenLastCalledWith(newImageSize);
+        },
+      );
+    });
+
+    describe('handleChangeWidth', () => {
+      const selectedModel = MODELS_MOCK_SHORT[FIRST_ARRAY_ELEMENT];
+      const setImageSize = jest.fn();
+
+      const { Wrapper } = getExportContextWithReduxWrapper(
+        {
+          ...EXPORT_CONTEXT_DEFAULT_VALUE,
+          setImageSize,
+          data: {
+            ...EXPORT_CONTEXT_DEFAULT_VALUE.data,
+            models: [
+              {
+                id: selectedModel.idObject.toString(),
+                label: selectedModel.name,
+              },
+            ],
+            imageSize: DEFAULT_IMAGE_SIZE,
+          },
+        },
+        {
+          models: {
+            data: MODELS_MOCK_SHORT,
+            loading: 'succeeded',
+            error: { name: '', message: '' },
+          },
+        },
+      );
+
+      const {
+        result: {
+          current: { handleChangeWidth },
+        },
+      } = renderHook(() => useImageSize(), {
+        wrapper: Wrapper,
+      });
+
+      // MAX_WIDTH 26779.25
+      // MAX_HEIGHT 13503.0
+
+      const widthCases: [number, ImageSize][] = [
+        [
+          // aspect ratio test
+          1000,
+          {
+            width: 1000,
+            height: 504,
+          },
+        ],
+        [
+          // transform to integer
+          997.2137,
+          {
+            width: 997,
+            height: 503,
+          },
+        ],
+        [
+          // max width
+          26779000,
+          {
+            width: 26779,
+            height: 13503,
+          },
+        ],
+      ];
+
+      it.each(widthCases)('should set valid height and width values', (newWidth, newImageSize) => {
+        handleChangeWidth(newWidth);
+
+        expect(setImageSize).toHaveBeenLastCalledWith(newImageSize);
+      });
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useImageSize.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useImageSize.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f36afdd3864b7a7d284103b19c6da8c8641f20d3
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useImageSize.ts
@@ -0,0 +1,88 @@
+import { MapModel } from '@/types/models';
+import { numberToSafeInt } from '@/utils/number/numberToInt';
+import { useCallback, useContext, useEffect } from 'react';
+import { ExportContext } from '../../ExportCompound.context';
+import { DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH } from '../ImageSize.constants';
+import { ImageSize } from '../ImageSize.types';
+import { useExportGraphicsSelectedModel } from './useExportGraphicsSelectedModel';
+import { getModelAspectRatios } from './useModelAspectRatios';
+
+interface UseImageSizeResults {
+  handleChangeWidth(width: number): void;
+  handleChangeHeight(height: number): void;
+  width: number;
+  height: number;
+}
+
+export const useImageSize = (): UseImageSizeResults => {
+  const selectedModel = useExportGraphicsSelectedModel();
+  const aspectRatios = getModelAspectRatios(selectedModel);
+  const { data, setImageSize } = useContext(ExportContext);
+  const { imageSize } = data;
+  const maxWidth = selectedModel?.width || DEFAULT_IMAGE_WIDTH;
+  const maxHeight = selectedModel?.height || DEFAULT_IMAGE_HEIGHT;
+
+  const getNormalizedImageSize = useCallback(
+    (newImageSize: ImageSize): ImageSize => {
+      const newWidth = newImageSize.width;
+      const newHeight = newImageSize.height;
+
+      const widthMinMax = Math.min(maxWidth, newWidth);
+      const heightMinMax = Math.min(maxHeight, newHeight);
+
+      const widthInt = numberToSafeInt(widthMinMax);
+      const heightInt = numberToSafeInt(heightMinMax);
+
+      return {
+        width: widthInt,
+        height: heightInt,
+      };
+    },
+    [maxWidth, maxHeight],
+  );
+
+  const setDefaultModelImageSize = useCallback(
+    (model: MapModel): void => {
+      const newImageSize = getNormalizedImageSize({
+        width: model.width,
+        height: model.height,
+      });
+
+      setImageSize(newImageSize);
+    },
+    [getNormalizedImageSize, setImageSize],
+  );
+
+  const handleChangeWidth = (width: number): void => {
+    const newImageSize = getNormalizedImageSize({
+      width,
+      height: width / aspectRatios.horizontal,
+    });
+
+    setImageSize(newImageSize);
+  };
+
+  const handleChangeHeight = (height: number): void => {
+    const newImageSize = getNormalizedImageSize({
+      height,
+      width: height / aspectRatios.vertical,
+    });
+
+    setImageSize(newImageSize);
+  };
+
+  useEffect(() => {
+    if (!selectedModel) {
+      return;
+    }
+
+    setDefaultModelImageSize(selectedModel);
+  }, [setDefaultModelImageSize, selectedModel]);
+
+  return {
+    handleChangeWidth,
+    handleChangeHeight,
+    width: imageSize.width,
+    height: imageSize.height,
+  };
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useModelAspectRatios.test.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useModelAspectRatios.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..42468de1d2911fb6f17ccca659874d892eaf7ab3
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useModelAspectRatios.test.ts
@@ -0,0 +1,45 @@
+import { MapModel } from '@/types/models';
+import { DEFAULT_MODEL_ASPECT_RATIOS } from '../ImageSize.constants';
+import { ModelAspectRatios } from '../ImageSize.types';
+import { getModelAspectRatios } from './useModelAspectRatios';
+
+describe('useModelAspectRatios - hook', () => {
+  describe('when model is not present', () => {
+    const model = undefined;
+
+    it('should return default model aspect ratio', () => {
+      const result = getModelAspectRatios(model);
+      expect(result).toEqual(DEFAULT_MODEL_ASPECT_RATIOS);
+    });
+  });
+
+  describe('when model is present', () => {
+    const modelCases: [Pick<MapModel, 'width' | 'height'>, ModelAspectRatios][] = [
+      [
+        {
+          width: 1000,
+          height: 500,
+        },
+        {
+          vertical: 0.5,
+          horizontal: 2,
+        },
+      ],
+      [
+        {
+          width: 4200,
+          height: 420,
+        },
+        {
+          vertical: 0.1,
+          horizontal: 10,
+        },
+      ],
+    ];
+
+    it.each(modelCases)('should return valid model aspect ratio', (model, expectedResult) => {
+      const result = getModelAspectRatios(model);
+      expect(result).toEqual(expectedResult);
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useModelAspectRatios.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useModelAspectRatios.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c4f23862eac2349a5f2e74ca217e03a06806d320
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/ImageSize/utils/useModelAspectRatios.ts
@@ -0,0 +1,16 @@
+import { MapModel } from '@/types/models';
+import { DEFAULT_MODEL_ASPECT_RATIOS } from '../ImageSize.constants';
+import { ModelAspectRatios } from '../ImageSize.types';
+
+export const getModelAspectRatios = (
+  model: Pick<MapModel, 'width' | 'height'> | undefined,
+): ModelAspectRatios => {
+  if (!model) {
+    return DEFAULT_MODEL_ASPECT_RATIOS;
+  }
+
+  return {
+    vertical: model.height / model.width,
+    horizontal: model.width / model.height,
+  };
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/IncludedCompartmentPathways /IncludedCompartmentPathways.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/IncludedCompartmentPathways /IncludedCompartmentPathways.component.tsx
index 40eac4ac4dcc817bff61a92139f7bcb24fba7c5b..4ef2cee4762cb803993095517e88c929323e056d 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/IncludedCompartmentPathways /IncludedCompartmentPathways.component.tsx	
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/IncludedCompartmentPathways /IncludedCompartmentPathways.component.tsx	
@@ -1,17 +1,18 @@
-import { useContext } from 'react';
+import { ZERO } from '@/constants/common';
 import {
   compartmentPathwaysDataSelector,
   loadingCompartmentPathwaysSelector,
 } from '@/redux/compartmentPathways/compartmentPathways.selectors';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
-import { ZERO } from '@/constants/common';
+import { useContext } from 'react';
 import { CheckboxFilter } from '../../CheckboxFilter';
 import { CollapsibleSection } from '../../CollapsibleSection';
 import { ExportContext } from '../ExportCompound.context';
 import { getCompartmentPathwaysCheckboxElements } from '../utils/getCompartmentPathwaysCheckboxElements';
 
 export const IncludedCompartmentPathways = (): React.ReactNode => {
-  const { setIncludedCompartmentPathways } = useContext(ExportContext);
+  const { setIncludedCompartmentPathways, data } = useContext(ExportContext);
+  const currentIncludedCompartmentPathways = data.includedCompartmentPathways;
   const loadingCompartmentPathways = useAppSelector(loadingCompartmentPathwaysSelector);
   const isPending = loadingCompartmentPathways === 'pending';
   const compartmentPathways = useAppSelector(compartmentPathwaysDataSelector);
@@ -23,6 +24,7 @@ export const IncludedCompartmentPathways = (): React.ReactNode => {
       {!isPending && checkboxElements && checkboxElements.length > ZERO && (
         <CheckboxFilter
           options={checkboxElements}
+          currentOptions={currentIncludedCompartmentPathways}
           onCheckedChange={setIncludedCompartmentPathways}
         />
       )}
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.test.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..2374285dc947b4e0fa4c66e0ab8384f2ab58571f
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.test.tsx
@@ -0,0 +1,116 @@
+/* eslint-disable no-magic-numbers */
+import { modelsFixture } from '@/models/fixtures/modelsFixture';
+import { StoreType } from '@/redux/store';
+import {
+  InitialStoreState,
+  getReduxWrapperWithStore,
+} from '@/utils/testing/getReduxWrapperWithStore';
+import { render, screen, waitFor } from '@testing-library/react';
+import { act } from 'react-dom/test-utils';
+import { Submap } from './Submap.component';
+
+const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
+
+  return (
+    render(
+      <Wrapper>
+        <Submap />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+const CHECKBOX_ELEMENT_NAME = modelsFixture[0].name;
+
+describe('Submap - component', () => {
+  it('should display submaps checkboxes when fetching data is successful', async () => {
+    renderComponent({
+      models: {
+        data: modelsFixture,
+        loading: 'succeeded',
+        error: {
+          message: '',
+          name: '',
+        },
+      },
+    });
+
+    expect(screen.queryByTestId('checkbox-filter')).not.toBeVisible();
+
+    const navigationButton = screen.getByTestId('accordion-item-button');
+
+    act(() => {
+      navigationButton.click();
+    });
+
+    expect(screen.getByText('Submap')).toBeInTheDocument();
+
+    await waitFor(() => {
+      expect(screen.getByTestId('checkbox-filter')).toBeInTheDocument();
+      expect(screen.getByLabelText('search-input')).toBeInTheDocument();
+      expect(screen.getByLabelText(CHECKBOX_ELEMENT_NAME)).toBeInTheDocument();
+    });
+  });
+  it('should not display submaps checkboxes when fetching data fails', async () => {
+    renderComponent({
+      models: {
+        data: [],
+        loading: 'failed',
+        error: {
+          message: '',
+          name: '',
+        },
+      },
+    });
+    expect(screen.getByText('Submap')).toBeInTheDocument();
+    const navigationButton = screen.getByTestId('accordion-item-button');
+    act(() => {
+      navigationButton.click();
+    });
+
+    expect(screen.queryByTestId('checkbox-filter')).not.toBeInTheDocument();
+  });
+  it('should not display submaps checkboxes when fetched data is empty', async () => {
+    renderComponent({
+      models: {
+        data: [],
+        loading: 'succeeded',
+        error: {
+          message: '',
+          name: '',
+        },
+      },
+    });
+    expect(screen.getByText('Submap')).toBeInTheDocument();
+    const navigationButton = screen.getByTestId('accordion-item-button');
+    act(() => {
+      navigationButton.click();
+    });
+
+    expect(screen.queryByTestId('checkbox-filter')).not.toBeInTheDocument();
+  });
+
+  it('should display loading message when fetching data is pending', async () => {
+    renderComponent({
+      models: {
+        data: [],
+        loading: 'pending',
+        error: {
+          message: '',
+          name: '',
+        },
+      },
+    });
+    expect(screen.getByText('Submap')).toBeInTheDocument();
+    const navigationButton = screen.getByTestId('accordion-item-button');
+    act(() => {
+      navigationButton.click();
+    });
+
+    expect(screen.getByText('Loading...')).toBeInTheDocument();
+  });
+});
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..5c5590ce5c669473922f966cfdfcc13df4269f77
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/Submap.component.tsx
@@ -0,0 +1,34 @@
+import { ZERO } from '@/constants/common';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { loadingModelsSelector, modelsDataSelector } from '@/redux/models/models.selectors';
+import { useContext } from 'react';
+import { CheckboxFilter } from '../../CheckboxFilter';
+import { CollapsibleSection } from '../../CollapsibleSection';
+import { ExportContext } from '../ExportCompound.context';
+
+export const Submap = (): React.ReactNode => {
+  const { setModels, data } = useContext(ExportContext);
+  const currentSelectedModels = data.models;
+  const models = useAppSelector(modelsDataSelector);
+  const loadingModels = useAppSelector(loadingModelsSelector);
+  const isPending = loadingModels === 'pending';
+
+  const mappedElementAnnotations = models.map(({ idObject, name }) => ({
+    id: `${idObject}`,
+    label: name,
+  }));
+
+  return (
+    <CollapsibleSection title="Submap">
+      {isPending && <p>Loading...</p>}
+      {!isPending && mappedElementAnnotations && mappedElementAnnotations.length > ZERO && (
+        <CheckboxFilter
+          options={mappedElementAnnotations}
+          currentOptions={currentSelectedModels}
+          onCheckedChange={setModels}
+          type="radio"
+        />
+      )}
+    </CollapsibleSection>
+  );
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/index.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..89fa39d0a0caeb34a8012e61e25b2b9fa9a1b7ed
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/Submap/index.ts
@@ -0,0 +1 @@
+export { Submap } from './Submap.component';
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/extractAndParseNumberIdFromCompartment.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/extractAndParseNumberIdFromCompartment.ts
index 1994a6654a7d14190c3d170502de718ee4130c09..e0cc82546fda54de629e92dbf24fa4e68d41de0e 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/extractAndParseNumberIdFromCompartment.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/extractAndParseNumberIdFromCompartment.ts
@@ -1,4 +1,4 @@
-import { CheckboxItem } from '../../CheckboxFilter/CheckboxFilter.component';
+import { CheckboxItem } from '../../CheckboxFilter/CheckboxFilter.types';
 
 export const extractAndParseNumberIdFromCompartment = (compartment: CheckboxItem): number => {
   const [, id] = compartment.id.split('-');
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getDownloadElementsBodyRequest.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getDownloadElementsBodyRequest.ts
index 0da338206a975e41432e619c0d238d9ae6d7f285..6cfb3494a9668d99be8fb6ac5152fa01bd1f5486 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getDownloadElementsBodyRequest.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getDownloadElementsBodyRequest.ts
@@ -1,4 +1,4 @@
-import { CheckboxItem } from '../../CheckboxFilter/CheckboxFilter.component';
+import { CheckboxItem } from '../../CheckboxFilter/CheckboxFilter.types';
 import { extractAndParseNumberIdFromCompartment } from './extractAndParseNumberIdFromCompartment';
 
 type DownloadBodyRequest = {
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getExportContextWithReduxWrapper.tsx b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getExportContextWithReduxWrapper.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..1d84ad2413c15fac273dbc6995b2dade33ad7928
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getExportContextWithReduxWrapper.tsx
@@ -0,0 +1,46 @@
+/* eslint-disable react/no-multi-comp */
+import { StoreType } from '@/redux/store';
+import { InitialStoreState } from '@/utils/testing/getReduxStoreActionsListener';
+import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
+import { EXPORT_CONTEXT_DEFAULT_VALUE } from '../ExportCompound.constant';
+import { ExportContext } from '../ExportCompound.context';
+import { ExportContextType } from '../ExportCompound.types';
+
+interface WrapperProps {
+  children: React.ReactNode;
+}
+
+export type ComponentWrapper = ({ children }: WrapperProps) => JSX.Element;
+
+export type GetExportContextWithReduxWrapper = (
+  contextValue?: ExportContextType,
+  initialState?: InitialStoreState,
+) => {
+  Wrapper: ComponentWrapper;
+  store: StoreType;
+};
+
+export const getExportContextWithReduxWrapper: GetExportContextWithReduxWrapper = (
+  contextValue,
+  initialState,
+) => {
+  const { Wrapper: ReduxWrapper, store } = getReduxWrapperWithStore(initialState);
+
+  const ContextWrapper: ComponentWrapper = ({ children }) => {
+    return (
+      <ExportContext.Provider value={contextValue || EXPORT_CONTEXT_DEFAULT_VALUE}>
+        {children}
+      </ExportContext.Provider>
+    );
+  };
+
+  const ContextWrapperWithRedux: ComponentWrapper = ({ children }) => {
+    return (
+      <ReduxWrapper>
+        <ContextWrapper>{children}</ContextWrapper>
+      </ReduxWrapper>
+    );
+  };
+
+  return { Wrapper: ContextWrapperWithRedux, store };
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2e6c4db9026bd78b950223fa64e5b3afe5161606
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.test.ts
@@ -0,0 +1,42 @@
+import { BASE_API_URL, PROJECT_ID } from '@/constants';
+import { GetGraphicsDownloadUrlProps, getGraphicsDownloadUrl } from './getGraphicsDownloadUrl';
+
+describe('getGraphicsDownloadUrl - util', () => {
+  const cases: [GetGraphicsDownloadUrlProps, string | undefined][] = [
+    [{}, undefined],
+    [
+      {
+        backgroundId: 50,
+      },
+      undefined,
+    ],
+    [
+      {
+        backgroundId: 50,
+        modelId: '30',
+      },
+      undefined,
+    ],
+    [
+      {
+        backgroundId: 50,
+        modelId: '30',
+        handler: 'any.handler.image',
+      },
+      undefined,
+    ],
+    [
+      {
+        backgroundId: 50,
+        modelId: '30',
+        handler: 'any.handler.image',
+        zoom: 7,
+      },
+      `${BASE_API_URL}/projects/${PROJECT_ID}/models/30:downloadImage?backgroundOverlayId=50&handlerClass=any.handler.image&zoomLevel=7`,
+    ],
+  ];
+
+  it.each(cases)('should return valid result', (input, result) => {
+    expect(getGraphicsDownloadUrl(input)).toBe(result);
+  });
+});
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c4020e9899f75685c7b732db23dd246077d433e7
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getGraphicsDownloadUrl.ts
@@ -0,0 +1,26 @@
+import { BASE_API_URL, PROJECT_ID } from '@/constants';
+
+export interface GetGraphicsDownloadUrlProps {
+  backgroundId?: number;
+  modelId?: string;
+  handler?: string;
+  zoom?: number;
+}
+
+export const getGraphicsDownloadUrl = ({
+  backgroundId,
+  modelId,
+  handler,
+  zoom,
+}: GetGraphicsDownloadUrlProps): string | undefined => {
+  const isAllElementsTruthy = [backgroundId, modelId, handler, zoom].reduce(
+    (a, b) => Boolean(a) && Boolean(b),
+    true,
+  );
+
+  if (!isAllElementsTruthy) {
+    return undefined;
+  }
+
+  return `${BASE_API_URL}/projects/${PROJECT_ID}/models/${modelId}:downloadImage?backgroundOverlayId=${backgroundId}&handlerClass=${handler}&zoomLevel=${zoom}`;
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getModelExportZoom.test.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getModelExportZoom.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..247ce802c96c25153d55fce4fc07a4eea5bbc431
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getModelExportZoom.test.ts
@@ -0,0 +1,45 @@
+/* eslint-disable no-magic-numbers */
+import { FIRST_ARRAY_ELEMENT, ZERO } from '@/constants/common';
+import { MODELS_MOCK_SHORT } from '@/models/mocks/modelsMock';
+import { getModelExportZoom } from './getModelExportZoom';
+
+describe('getModelExportZoom - util', () => {
+  describe('when there is no model', () => {
+    const model = undefined;
+    const exportWidth = 100;
+
+    it('should return return zero', () => {
+      expect(getModelExportZoom(exportWidth, model)).toBe(ZERO);
+    });
+  });
+
+  // Math.log2 of zero is -Infty
+  describe('when model width is zero', () => {
+    const model = {
+      ...MODELS_MOCK_SHORT[FIRST_ARRAY_ELEMENT],
+      width: 0,
+    };
+    const exportWidth = 100;
+
+    it('should return return zero', () => {
+      expect(getModelExportZoom(exportWidth, model)).toBe(ZERO);
+    });
+  });
+
+  describe('when model is present and model width > ZERO', () => {
+    const model = MODELS_MOCK_SHORT[FIRST_ARRAY_ELEMENT];
+
+    // MAX_WIDTH 26779.25
+    // [zoom, width]
+    const cases: [number, number][] = [
+      [2, 100], // MIN ZOOM
+      [2.7142, 420],
+      [4.5391, 1488],
+      [9, 80000000], // MAX ZOOM
+    ];
+
+    it.each(cases)('should return export zoom=%s for width=%s', (zoom, width) => {
+      expect(getModelExportZoom(width, model)).toBeCloseTo(zoom);
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getModelExportZoom.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getModelExportZoom.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c198def10be36fe02577193626180f285ede6e9b
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getModelExportZoom.ts
@@ -0,0 +1,22 @@
+import { ZERO } from '@/constants/common';
+import { MapModel } from '@/types/models';
+
+const ZOOM_BASE = 6;
+
+/*
+ * Width of exported image for zoom=1 is 128, for zoom=2 is 256, for zoom=3 is 1024
+ * So zoom level holds pattern of log2(width) with base of log2(128)=7
+ * Zoom base defined in this file is 6 as we need to provide minumum zoom of 1
+ */
+
+export const getModelExportZoom = (exportWidth: number, model?: MapModel): number => {
+  // log2 of zero is -Infty
+  if (!model || model.width === ZERO) {
+    return ZERO;
+  }
+
+  const { maxZoom, minZoom } = model;
+  const exportZoom = Math.log2(exportWidth) - ZOOM_BASE;
+
+  return Math.min(Math.max(exportZoom, minZoom), maxZoom);
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getNetworkBodyRequest.ts b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getNetworkBodyRequest.ts
index 9f83d70582058f6d5d5bd6038ec00c3858e5c65b..eadc0e8c0b9091093d92f3f0b5acf587770b036d 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getNetworkBodyRequest.ts
+++ b/src/components/Map/Drawer/ExportDrawer/ExportCompound/utils/getNetworkBodyRequest.ts
@@ -1,4 +1,4 @@
-import { CheckboxItem } from '../../CheckboxFilter/CheckboxFilter.component';
+import { CheckboxItem } from '../../CheckboxFilter/CheckboxFilter.types';
 import { extractAndParseNumberIdFromCompartment } from './extractAndParseNumberIdFromCompartment';
 
 type DownloadBodyRequest = {
diff --git a/src/components/Map/Drawer/ExportDrawer/ExportDrawer.component.tsx b/src/components/Map/Drawer/ExportDrawer/ExportDrawer.component.tsx
index 1d98f663a79aae7c2dbe4b2e954c58c32536794f..408b68c779a1f5a9e488e662ca24c9a3c0120b0a 100644
--- a/src/components/Map/Drawer/ExportDrawer/ExportDrawer.component.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/ExportDrawer.component.tsx
@@ -1,14 +1,15 @@
+import { getCompartmentPathways } from '@/redux/compartmentPathways/compartmentPathways.thunks';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { modelsIdsSelector } from '@/redux/models/models.selectors';
 import { DrawerHeading } from '@/shared/DrawerHeading';
-import { getCompartmentPathways } from '@/redux/compartmentPathways/compartmentPathways.thunks';
 import { useEffect, useState } from 'react';
-import { TabNavigator } from './TabNavigator';
 import { Elements } from './Elements';
+import { Graphics } from './Graphics';
+import { Network } from './Network';
+import { TabNavigator } from './TabNavigator';
 import { TAB_NAMES } from './TabNavigator/TabNavigator.constants';
 import { TabNames } from './TabNavigator/TabNavigator.types';
-import { Network } from './Network';
 
 export const ExportDrawer = (): React.ReactNode => {
   const modelsIds = useAppSelector(modelsIdsSelector);
@@ -30,7 +31,7 @@ export const ExportDrawer = (): React.ReactNode => {
         <TabNavigator activeTab={activeTab} onTabChange={handleTabChange} />
         {activeTab === TAB_NAMES.ELEMENTS && <Elements />}
         {activeTab === TAB_NAMES.NETWORK && <Network />}
-        {activeTab === TAB_NAMES.GRAPHICS && <div>Graphics</div>}
+        {activeTab === TAB_NAMES.GRAPHICS && <Graphics />}
       </div>
     </div>
   );
diff --git a/src/components/Map/Drawer/ExportDrawer/Graphics/Graphics.component.tsx b/src/components/Map/Drawer/ExportDrawer/Graphics/Graphics.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..547c2c14ed2b487a38bb5773552aa386ef84fadd
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/Graphics/Graphics.component.tsx
@@ -0,0 +1,14 @@
+import { Export } from '../ExportCompound';
+
+export const Graphics = (): React.ReactNode => {
+  return (
+    <div data-testid="graphics-tab">
+      <Export>
+        <Export.Submap />
+        <Export.ImageSize />
+        <Export.ImageFormat />
+        <Export.DownloadGraphics />
+      </Export>
+    </div>
+  );
+};
diff --git a/src/components/Map/Drawer/ExportDrawer/Graphics/index.ts b/src/components/Map/Drawer/ExportDrawer/Graphics/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e82824ec6623b9e6e88f9c7b1374b449878e1fa4
--- /dev/null
+++ b/src/components/Map/Drawer/ExportDrawer/Graphics/index.ts
@@ -0,0 +1 @@
+export { Graphics } from './Graphics.component';
diff --git a/src/components/Map/Drawer/ExportDrawer/Network/Network.component.test.tsx b/src/components/Map/Drawer/ExportDrawer/Network/Network.component.test.tsx
index 67321198348d16a13f633d31936ed28329b567f9..4bf77ac6c6bfd29c2bc9d3d2212198fedfee3f91 100644
--- a/src/components/Map/Drawer/ExportDrawer/Network/Network.component.test.tsx
+++ b/src/components/Map/Drawer/ExportDrawer/Network/Network.component.test.tsx
@@ -1,18 +1,19 @@
 /* eslint-disable no-magic-numbers */
+import { compartmentPathwaysDetailsFixture } from '@/models/fixtures/compartmentPathways';
+import { configurationFixture } from '@/models/fixtures/configurationFixture';
+import { modelsFixture } from '@/models/fixtures/modelsFixture';
+import { statisticsFixture } from '@/models/fixtures/statisticsFixture';
+import { apiPath } from '@/redux/apiPath';
+import { CONFIGURATION_INITIAL_STORE_MOCK } from '@/redux/configuration/configuration.mock';
+import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
 import { AppDispatch, RootState } from '@/redux/store';
+import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse';
+import { getReduxStoreWithActionsListener } from '@/utils/testing/getReduxStoreActionsListener';
 import { InitialStoreState } from '@/utils/testing/getReduxWrapperWithStore';
 import { render, screen } from '@testing-library/react';
-import { CONFIGURATION_INITIAL_STORE_MOCK } from '@/redux/configuration/configuration.mock';
-import { configurationFixture } from '@/models/fixtures/configurationFixture';
+import { HttpStatusCode } from 'axios';
 import { act } from 'react-dom/test-utils';
-import { statisticsFixture } from '@/models/fixtures/statisticsFixture';
-import { compartmentPathwaysDetailsFixture } from '@/models/fixtures/compartmentPathways';
 import { MockStoreEnhanced } from 'redux-mock-store';
-import { getReduxStoreWithActionsListener } from '@/utils/testing/getReduxStoreActionsListener';
-import { modelsFixture } from '@/models/fixtures/modelsFixture';
-import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse';
-import { apiPath } from '@/redux/apiPath';
-import { HttpStatusCode } from 'axios';
 import { NETWORK_COLUMNS } from '../ExportCompound/ExportCompound.constant';
 import { Network } from './Network.component';
 
@@ -37,6 +38,7 @@ const renderComponent = (
 describe('Network - component', () => {
   it('should render all network sections', () => {
     renderComponent({
+      ...INITIAL_STORE_STATE_MOCK,
       configuration: {
         ...CONFIGURATION_INITIAL_STORE_MOCK,
         main: {
@@ -94,6 +96,7 @@ describe('Network - component', () => {
     const SECOND_COMPARMENT_PATHWAY_NAME = compartmentPathwaysDetailsFixture[1].name;
     const SECOND_COMPARMENT_PATHWAY_ID = compartmentPathwaysDetailsFixture[1].id;
     const { store } = renderComponent({
+      ...INITIAL_STORE_STATE_MOCK,
       configuration: {
         ...CONFIGURATION_INITIAL_STORE_MOCK,
         main: {
diff --git a/src/models/mocks/configurationFormatsMock.ts b/src/models/mocks/configurationFormatsMock.ts
index 8d6d4e8afa75491a2fcafee702da4320a633f1b9..34ec36a2e7bc287f63d45eef763b1c0b22c21637 100644
--- a/src/models/mocks/configurationFormatsMock.ts
+++ b/src/models/mocks/configurationFormatsMock.ts
@@ -29,3 +29,23 @@ export const CONFIGURATION_FORMATS_MOCK: ConfigurationFormatSchema[] = [
     extension: 'gpml',
   },
 ];
+
+export const CONFIGURATION_IMAGE_FORMATS_TYPES_MOCK: string[] = ['PNG image', 'PDF', 'SVG image'];
+
+export const CONFIGURATION_IMAGE_FORMATS_MOCK: ConfigurationFormatSchema[] = [
+  {
+    name: 'PNG image',
+    handler: 'lcsb.mapviewer.converter.graphics.PngImageGenerator',
+    extension: 'png',
+  },
+  {
+    name: 'PDF',
+    handler: 'lcsb.mapviewer.converter.graphics.PdfImageGenerator',
+    extension: 'pdf',
+  },
+  {
+    name: 'SVG image',
+    handler: 'lcsb.mapviewer.converter.graphics.SvgImageGenerator',
+    extension: 'svg',
+  },
+];
diff --git a/src/redux/apiPath.ts b/src/redux/apiPath.ts
index 212660e5ee66c695f389fd6c49b7168b6ec78ecb..c6cb7455da5915358e1eb1314cc5bd2c849475ed 100644
--- a/src/redux/apiPath.ts
+++ b/src/redux/apiPath.ts
@@ -1,6 +1,6 @@
 import { PROJECT_ID } from '@/constants';
-import { PerfectSearchParams } from '@/types/search';
 import { Point } from '@/types/map';
+import { PerfectSearchParams } from '@/types/search';
 
 export const apiPath = {
   getBioEntityContentsStringWithQuery: ({
diff --git a/src/redux/backgrounds/background.selectors.ts b/src/redux/backgrounds/background.selectors.ts
index b8443ab5545da2f894ca43fe284669b56fcdf038..b815cf59b879e5cf3460cbeb092bef85612ae065 100644
--- a/src/redux/backgrounds/background.selectors.ts
+++ b/src/redux/backgrounds/background.selectors.ts
@@ -1,12 +1,12 @@
-import { createSelector } from '@reduxjs/toolkit';
 import { EMPTY_BACKGROUND_NAME } from '@/constants/backgrounds';
+import { createSelector } from '@reduxjs/toolkit';
 import { mapDataSelector } from '../map/map.selectors';
 import { rootSelector } from '../root/root.selectors';
 
 export const backgroundsSelector = createSelector(rootSelector, state => state.backgrounds);
 
 export const backgroundsDataSelector = createSelector(backgroundsSelector, backgrounds => {
-  return backgrounds.data;
+  return backgrounds?.data || [];
 });
 
 const MAIN_BACKGROUND = 0;
diff --git a/src/redux/configuration/configuration.constants.ts b/src/redux/configuration/configuration.constants.ts
index 56448d47fce6e44bf31adfe19acd78b25b340453..bcf3c906f5ab72e0012749ad77fe2d710e2cd866 100644
--- a/src/redux/configuration/configuration.constants.ts
+++ b/src/redux/configuration/configuration.constants.ts
@@ -15,3 +15,7 @@ export const GPML_HANDLER_NAME_ID = 'GPML';
 export const SBML_HANDLER_NAME_ID = 'SBML';
 export const CELL_DESIGNER_SBML_HANDLER_NAME_ID = 'CellDesigner SBML';
 export const SBGN_ML_HANDLER_NAME_ID = 'SBGN-ML';
+
+export const PNG_IMAGE_HANDLER_NAME_ID = 'PNG image';
+export const PDF_HANDLER_NAME_ID = 'PDF';
+export const SVG_IMAGE_HANDLER_NAME_ID = 'SVG image';
diff --git a/src/redux/configuration/configuration.selectors.ts b/src/redux/configuration/configuration.selectors.ts
index e4bf178be216aea6ab1233b87fb06b7c2f152d6c..25cbfbfa134c8e574480d310a96781e7bd0cc776 100644
--- a/src/redux/configuration/configuration.selectors.ts
+++ b/src/redux/configuration/configuration.selectors.ts
@@ -10,11 +10,14 @@ import {
   MIN_COLOR_VAL_NAME_ID,
   NEUTRAL_COLOR_VAL_NAME_ID,
   OVERLAY_OPACITY_NAME_ID,
+  PDF_HANDLER_NAME_ID,
+  PNG_IMAGE_HANDLER_NAME_ID,
   SBGN_ML_HANDLER_NAME_ID,
   SBML_HANDLER_NAME_ID,
   SIMPLE_COLOR_VAL_NAME_ID,
+  SVG_IMAGE_HANDLER_NAME_ID,
 } from './configuration.constants';
-import { ConfigurationHandlersIds } from './configuration.types';
+import { ConfigurationHandlersIds, ConfigurationImageHandlersIds } from './configuration.types';
 
 const configurationSelector = createSelector(rootSelector, state => state.configuration);
 const configurationOptionsSelector = createSelector(configurationSelector, state => state.options);
@@ -63,7 +66,7 @@ export const modelFormatsSelector = createSelector(
   state => state?.modelFormats,
 );
 
-export const formatsEntriesSelector = createSelector(
+export const modelFormatsEntriesSelector = createSelector(
   modelFormatsSelector,
   (modelFormats): Record<string, ConfigurationFormatSchema> => {
     return Object.fromEntries(
@@ -78,7 +81,7 @@ export const formatsEntriesSelector = createSelector(
 );
 
 export const formatsHandlersSelector = createSelector(
-  formatsEntriesSelector,
+  modelFormatsEntriesSelector,
   (formats): ConfigurationHandlersIds => {
     return {
       [GPML_HANDLER_NAME_ID]: formats[GPML_HANDLER_NAME_ID]?.handler,
@@ -89,7 +92,37 @@ export const formatsHandlersSelector = createSelector(
   },
 );
 
+export const imageFormatsSelector = createSelector(
+  configurationMainSelector,
+  state => state?.imageFormats,
+);
+
+export const imageFormatsEntriesSelector = createSelector(
+  imageFormatsSelector,
+  (modelFormats): Record<string, ConfigurationFormatSchema> => {
+    return Object.fromEntries(
+      (modelFormats || []).flat().map((format: ConfigurationFormatSchema) => [format.name, format]),
+    );
+  },
+);
+
+export const imageHandlersSelector = createSelector(
+  imageFormatsEntriesSelector,
+  (formats): ConfigurationImageHandlersIds => {
+    return {
+      [PNG_IMAGE_HANDLER_NAME_ID]: formats[PNG_IMAGE_HANDLER_NAME_ID]?.handler,
+      [PDF_HANDLER_NAME_ID]: formats[PDF_HANDLER_NAME_ID]?.handler,
+      [SVG_IMAGE_HANDLER_NAME_ID]: formats[SVG_IMAGE_HANDLER_NAME_ID]?.handler,
+    };
+  },
+);
+
 export const miramiTypesSelector = createSelector(
   configurationMainSelector,
   state => state?.miriamTypes,
 );
+
+export const loadingConfigurationMainSelector = createSelector(
+  configurationSelector,
+  state => state?.main?.loading,
+);
diff --git a/src/redux/configuration/configuration.types.ts b/src/redux/configuration/configuration.types.ts
index e797b88764723d2f18b1c2c7b2898c46d3ade799..343c8b86557ada9505aa50413a2b109b2e367569 100644
--- a/src/redux/configuration/configuration.types.ts
+++ b/src/redux/configuration/configuration.types.ts
@@ -3,8 +3,11 @@ import { Configuration } from '@/types/models';
 import {
   CELL_DESIGNER_SBML_HANDLER_NAME_ID,
   GPML_HANDLER_NAME_ID,
+  PDF_HANDLER_NAME_ID,
+  PNG_IMAGE_HANDLER_NAME_ID,
   SBGN_ML_HANDLER_NAME_ID,
   SBML_HANDLER_NAME_ID,
+  SVG_IMAGE_HANDLER_NAME_ID,
 } from './configuration.constants';
 
 export type ConfigurationMainState = FetchDataState<Configuration>;
@@ -15,3 +18,9 @@ export interface ConfigurationHandlersIds {
   [CELL_DESIGNER_SBML_HANDLER_NAME_ID]?: string;
   [SBGN_ML_HANDLER_NAME_ID]?: string;
 }
+
+export interface ConfigurationImageHandlersIds {
+  [PNG_IMAGE_HANDLER_NAME_ID]?: string;
+  [PDF_HANDLER_NAME_ID]?: string;
+  [SVG_IMAGE_HANDLER_NAME_ID]?: string;
+}
diff --git a/src/redux/models/models.selectors.ts b/src/redux/models/models.selectors.ts
index c113be0700fcc4be0e946f1e0de3241d04348fe0..652c018f1f3cdf8db33587a5c3972b3f01f87848 100644
--- a/src/redux/models/models.selectors.ts
+++ b/src/redux/models/models.selectors.ts
@@ -34,6 +34,9 @@ export const modelByIdSelector = createSelector(
 
 const MAIN_MAP = 0;
 export const mainMapModelSelector = createSelector(modelsDataSelector, models => models[MAIN_MAP]);
+
+export const loadingModelsSelector = createSelector(modelsSelector, state => state.loading);
+
 export const mainMapModelDescriptionSelector = createSelector(
   modelsDataSelector,
   models => models[MAIN_MAP].description,
diff --git a/src/utils/number/numberToInt.ts b/src/utils/number/numberToInt.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b57608e083e67663a5e6552db0d227c4cbe6319c
--- /dev/null
+++ b/src/utils/number/numberToInt.ts
@@ -0,0 +1,10 @@
+import { ZERO } from '@/constants/common';
+
+export const numberToSafeInt = (num: number): number => {
+  // zero or NaN
+  if (!num) {
+    return ZERO;
+  }
+
+  return Number(num.toFixed(ZERO));
+};