Skip to content
Snippets Groups Projects
Commit bdb57b39 authored by mateusz-winiarczyk's avatar mateusz-winiarczyk
Browse files

feat(submap): display summary overlay for submaps links (MIN-197)

parent 05ee0572
No related branches found
No related tags found
2 merge requests!223reset the pin numbers before search results are fetch (so the results will be...,!126feat(submap): display summary overlay for submaps links (MIN-197)
Showing
with 827 additions and 13 deletions
......@@ -33,6 +33,8 @@ const localStorageMock = (() => {
};
})();
global.structuredClone = val => JSON.parse(JSON.stringify(val));
Object.defineProperty(global, 'localStorage', {
value: localStorageMock,
});
import Polygon, { fromExtent } from 'ol/geom/Polygon';
import Feature from 'ol/Feature';
export const createFeatureFromExtent = ([xMin, yMin, xMax, yMax]: number[]): Feature<Polygon> =>
new Feature({ geometry: fromExtent([xMin, yMin, xMax, yMax]) });
import { Fill, Stroke, Style } from 'ol/style';
import { fromExtent } from 'ol/geom/Polygon';
import Feature from 'ol/Feature';
import type Polygon from 'ol/geom/Polygon';
const createFeatureFromExtent = ([xMin, yMin, xMax, yMax]: number[]): Feature<Polygon> =>
new Feature({ geometry: fromExtent([xMin, yMin, xMax, yMax]) });
import { createFeatureFromExtent } from './createFeatureFromExtent';
const getBioEntityOverlayFeatureStyle = (color: string): Style =>
new Style({ fill: new Fill({ color }), stroke: new Stroke({ color: 'black', width: 1 }) });
......
/* eslint-disable no-magic-numbers */
import Feature from 'ol/Feature';
import { createOverlaySubmapLinkRectangleFeature } from './createOverlaySubmapLinkRectangleFeature';
const COLOR = '#FFFFFFcc';
const CASES = [
[
[0, 0, 0, 0],
[0, 0, 0, 0],
],
[
[0, 0, 100, 100],
[0, 0, 100, 100],
],
[
[100, 0, 230, 100],
[100, 0, 230, 100],
],
[
[-50, 0, 0, 50],
[-50, 0, 0, 50],
],
];
describe('createOverlaySubmapLinkRectangleFeature - util', () => {
it.each(CASES)('should return Feature instance', points => {
const feature = createOverlaySubmapLinkRectangleFeature(points, COLOR);
expect(feature).toBeInstanceOf(Feature);
});
it.each(CASES)('should return Feature instance with valid style and stroke', points => {
const feature = createOverlaySubmapLinkRectangleFeature(points, COLOR);
const style = feature.getStyle();
expect(style).toMatchObject({
fill_: { color_: COLOR },
stroke_: {
color_: COLOR,
width_: 1,
},
});
});
it('should return object with transparent fill and black stroke color when color is null', () => {
const feature = createOverlaySubmapLinkRectangleFeature([0, 0, 0, 0], null);
const style = feature.getStyle();
expect(style).toMatchObject({
fill_: { color_: 'transparent' },
stroke_: {
color_: 'black',
width_: 1,
},
});
});
it.each(CASES)('should return Feature instance with valid geometry', (points, extent) => {
const feature = createOverlaySubmapLinkRectangleFeature(points, COLOR);
const geometry = feature.getGeometry();
expect(geometry?.getExtent()).toEqual(extent);
});
it('should throw error if extent is not valid', () => {
expect(() => createOverlaySubmapLinkRectangleFeature([100, 100, 0, 0], COLOR)).toThrow();
});
});
/* eslint-disable no-magic-numbers */
import Feature from 'ol/Feature';
import type Polygon from 'ol/geom/Polygon';
import { createFeatureFromExtent } from './createFeatureFromExtent';
import { getOverlaySubmapLinkRectangleFeatureStyle } from './getOverlaySubmapLinkRectangleFeatureStyle';
export const createOverlaySubmapLinkRectangleFeature = (
[xMin, yMin, xMax, yMax]: number[],
color: string | null,
): Feature<Polygon> => {
const feature = createFeatureFromExtent([xMin, yMin, xMax, yMax]);
feature.setStyle(getOverlaySubmapLinkRectangleFeatureStyle(color));
return feature;
};
/* eslint-disable no-magic-numbers */
import { Fill, Stroke, Style } from 'ol/style';
import { getOverlaySubmapLinkRectangleFeatureStyle } from './getOverlaySubmapLinkRectangleFeatureStyle';
const COLORS = ['#000000', '#FFFFFF', '#F5F5F5', '#C0C0C0', '#C0C0C0aa', '#C0C0C0bb'];
describe('getOverlaySubmapLinkRectangleFeatureStyle - util', () => {
it.each(COLORS)('should return Style object', color => {
const result = getOverlaySubmapLinkRectangleFeatureStyle(color);
expect(result).toBeInstanceOf(Style);
});
it.each(COLORS)('should set valid color values for fill', color => {
const result = getOverlaySubmapLinkRectangleFeatureStyle(color);
const fill = result.getFill();
expect(fill).toBeInstanceOf(Fill);
expect(fill?.getColor()).toBe(color);
});
it.each(COLORS)('should set valid color values for fill', color => {
const result = getOverlaySubmapLinkRectangleFeatureStyle(color);
const stroke = result.getStroke();
expect(stroke).toBeInstanceOf(Stroke);
expect(stroke?.getColor()).toBe(color);
expect(stroke?.getWidth()).toBe(1);
});
it('should set transparent fill and black stroke if color is null', () => {
const result = getOverlaySubmapLinkRectangleFeatureStyle(null);
const stroke = result.getStroke();
expect(stroke).toBeInstanceOf(Stroke);
expect(stroke?.getColor()).toBe('black');
expect(stroke?.getWidth()).toBe(1);
const fill = result.getFill();
expect(fill).toBeInstanceOf(Fill);
expect(fill?.getColor()).toBe('transparent');
});
});
/* eslint-disable no-magic-numbers */
import { Fill, Stroke, Style } from 'ol/style';
export const getOverlaySubmapLinkRectangleFeatureStyle = (color: string | null): Style =>
new Style({
fill: new Fill({ color: color || 'transparent' }),
stroke: new Stroke({ color: color || 'black', width: 1 }),
zIndex: color ? 0 : 1,
});
/* eslint-disable no-magic-numbers, no-param-reassign */
import type { SubmapLinkRectangle } from './useBioEntitiesWithSubmapLinks';
export const getSubmapLinkRectangle = (
submapsLinksRectangles: SubmapLinkRectangle[],
submapLinkRectangle: SubmapLinkRectangle,
index: number,
submapLinksRectanglesGroup: SubmapLinkRectangle[],
rectangleHeight: number,
): void => {
if (index === 0) {
submapsLinksRectangles.push({
...structuredClone(submapLinkRectangle),
amount: 0,
value: Infinity,
});
}
if (index !== 0) {
submapLinkRectangle.y2 = submapLinksRectanglesGroup[index - 1].y1;
}
submapLinkRectangle.y1 = submapLinkRectangle.y2 + rectangleHeight;
submapLinkRectangle.height = rectangleHeight;
submapsLinksRectangles.push(submapLinkRectangle);
};
import type { OverlayBioEntityRender } from '@/types/OLrendering';
import type { GroupedSubmapsLinksRectangles } from './useBioEntitiesWithSubmapLinks';
export const groupSubmapLinksRectanglesById = (
data: OverlayBioEntityRender[],
): GroupedSubmapsLinksRectangles => {
const submapsLinksRectangles = structuredClone(data);
const groupedSubmapsLinksRectanglesById: GroupedSubmapsLinksRectangles = {};
submapsLinksRectangles.forEach(submapLinkRectangle => {
const { id, overlayId } = submapLinkRectangle;
const groupId = `${id}-${overlayId}`;
if (!groupedSubmapsLinksRectanglesById[groupId]) {
groupedSubmapsLinksRectanglesById[groupId] = [];
}
const matchedSubmapLinkRectangle = groupedSubmapsLinksRectanglesById[groupId].find(element => {
const hasAllRequiredValueProperties = element.value && submapLinkRectangle.value;
const isValueEqual =
hasAllRequiredValueProperties && element.value === submapLinkRectangle.value;
const hasAllRequiredColorProperties = element.color && submapLinkRectangle.color;
const isColorEqual =
hasAllRequiredColorProperties &&
element.color?.alpha === submapLinkRectangle?.color?.alpha &&
element.color?.rgb === submapLinkRectangle?.color?.rgb;
if (isValueEqual || isColorEqual) return true;
return false;
});
if (!matchedSubmapLinkRectangle) {
groupedSubmapsLinksRectanglesById[groupId].push({
...structuredClone(submapLinkRectangle),
amount: 1,
});
} else {
matchedSubmapLinkRectangle.amount += 1;
}
});
return groupedSubmapsLinksRectanglesById;
};
/* eslint-disable no-magic-numbers */
import { getReduxStoreWithActionsListener } from '@/utils/testing/getReduxStoreActionsListener';
import { renderHook } from '@testing-library/react';
import { CONFIGURATION_INITIAL_STORE_MOCKS } from '@/redux/configuration/configuration.mock';
import { PUBLIC_OVERLAYS_MOCK } from '@/redux/overlays/overlays.mock';
import { mapStateWithCurrentlySelectedMainMapFixture } from '@/redux/map/map.fixtures';
import {
MOCKED_OVERLAY_SUBMAPS_LINKS_WITH_DIFFERENT_COLORS,
MOCKED_OVERLAY_SUBMAPS_LINKS_WITH_SAME_COLORS,
OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK,
} from '@/redux/overlayBioEntity/overlayBioEntity.mock';
import { MODELS_DATA_MOCK_WITH_MAIN_MAP } from '@/redux/models/models.mock';
import { useBioEntitiesWithSubmapsLinks } from './useBioEntitiesWithSubmapLinks';
const RESULT_SUBMAP_LINKS_DIFFERENT_VALUES = [
{
type: 'submap-link',
id: 97,
modelId: 52,
amount: 0,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: Infinity,
color: null,
},
{
type: 'submap-link',
amount: 1,
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2025.5,
y2: 2000.5,
overlayId: 12,
height: 25,
value: 0.8,
color: null,
},
{
type: 'submap-link',
amount: 1,
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2050.5,
y2: 2025.5,
overlayId: 12,
height: 25,
value: 0.5,
color: null,
},
{
type: 'submap-link',
amount: 1,
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2075.5,
y2: 2050.5,
overlayId: 12,
height: 25,
value: 0.4,
color: null,
},
{
type: 'submap-link',
amount: 1,
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2075.5,
overlayId: 12,
height: 25,
value: null,
color: {
alpha: 255,
rgb: -2348283,
},
},
{
type: 'rectangle',
id: 1,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 3128.653195488725,
y2: 3088.653195488725,
overlayId: 12,
height: 10,
value: 0,
color: null,
},
];
export const RESULT_SUBMAP_LINKS_SAME_COLORS = [
{
type: 'submap-link',
amount: 0,
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: Infinity,
color: null,
},
{
type: 'submap-link',
amount: 2,
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2050.5,
y2: 2000.5,
overlayId: 12,
height: 50,
value: 23,
color: null,
},
{
type: 'submap-link',
amount: 2,
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2050.5,
overlayId: 12,
height: 50,
value: null,
color: {
alpha: 255,
rgb: -2348283,
},
},
{
type: 'rectangle',
id: 1,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 3128.653195488725,
y2: 3088.653195488725,
overlayId: 12,
height: 10,
value: 0,
color: null,
},
];
describe('useBioEntitiesWithSubmapsLinks', () => {
it('should return bioEntities without submaps links if no submaps links are present', () => {
const { Wrapper } = getReduxStoreWithActionsListener({
overlayBioEntity: {
...OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK,
overlaysId: PUBLIC_OVERLAYS_MOCK.map(o => o.idObject),
},
configuration: CONFIGURATION_INITIAL_STORE_MOCKS,
map: mapStateWithCurrentlySelectedMainMapFixture,
});
const {
result: { current },
} = renderHook(() => useBioEntitiesWithSubmapsLinks(), {
wrapper: Wrapper,
});
expect(current).toEqual([]);
});
describe('submap links with the same ID and overlayID but different values or colors', () => {
it('should create submap link with Infinity value, for displaying black border of submap link', () => {
const { Wrapper } = getReduxStoreWithActionsListener({
overlayBioEntity: {
overlaysId: [12],
data: {
12: {
52: MOCKED_OVERLAY_SUBMAPS_LINKS_WITH_DIFFERENT_COLORS,
},
},
},
configuration: CONFIGURATION_INITIAL_STORE_MOCKS,
map: mapStateWithCurrentlySelectedMainMapFixture,
models: {
...MODELS_DATA_MOCK_WITH_MAIN_MAP,
},
});
const {
result: { current },
} = renderHook(() => useBioEntitiesWithSubmapsLinks(), {
wrapper: Wrapper,
});
expect(current[0]).toEqual({
type: 'submap-link',
amount: 0,
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: Infinity,
color: null,
});
});
it('should modify height, coordinates and return in sorted order to create submap link from several submap link rectangles', () => {
const { Wrapper } = getReduxStoreWithActionsListener({
overlayBioEntity: {
overlaysId: [12],
data: {
12: {
52: MOCKED_OVERLAY_SUBMAPS_LINKS_WITH_DIFFERENT_COLORS,
},
},
},
configuration: CONFIGURATION_INITIAL_STORE_MOCKS,
map: mapStateWithCurrentlySelectedMainMapFixture,
models: {
...MODELS_DATA_MOCK_WITH_MAIN_MAP,
},
});
const {
result: { current },
} = renderHook(() => useBioEntitiesWithSubmapsLinks(), {
wrapper: Wrapper,
});
expect(current).toStrictEqual(RESULT_SUBMAP_LINKS_DIFFERENT_VALUES);
});
});
describe('submap links with the same ID and overlayID and the same values or colors', () => {
it('should create submap link with Infinity value, for displaying black border of submap link', () => {
const { Wrapper } = getReduxStoreWithActionsListener({
overlayBioEntity: {
overlaysId: [12],
data: {
12: {
52: MOCKED_OVERLAY_SUBMAPS_LINKS_WITH_SAME_COLORS,
},
},
},
configuration: CONFIGURATION_INITIAL_STORE_MOCKS,
map: mapStateWithCurrentlySelectedMainMapFixture,
models: {
...MODELS_DATA_MOCK_WITH_MAIN_MAP,
},
});
const {
result: { current },
} = renderHook(() => useBioEntitiesWithSubmapsLinks(), {
wrapper: Wrapper,
});
expect(current[0]).toEqual({
type: 'submap-link',
amount: 0,
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: Infinity,
color: null,
});
});
it('should modify height, coordinates and return in sorted order to create submap link from several submap link rectangles', () => {
const { Wrapper } = getReduxStoreWithActionsListener({
overlayBioEntity: {
overlaysId: [12],
data: {
12: {
52: MOCKED_OVERLAY_SUBMAPS_LINKS_WITH_SAME_COLORS,
},
},
},
configuration: CONFIGURATION_INITIAL_STORE_MOCKS,
map: mapStateWithCurrentlySelectedMainMapFixture,
models: {
...MODELS_DATA_MOCK_WITH_MAIN_MAP,
},
});
const {
result: { current },
} = renderHook(() => useBioEntitiesWithSubmapsLinks(), {
wrapper: Wrapper,
});
expect(current).toStrictEqual(RESULT_SUBMAP_LINKS_SAME_COLORS);
});
});
});
/* eslint-disable no-magic-numbers */
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { overlayBioEntitiesForCurrentModelSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
import { useCallback, useMemo } from 'react';
import type { OverlayBioEntityRender } from '@/types/OLrendering';
import { useGetOverlayColor } from './useGetOverlayColor';
import { getSubmapLinkRectangle } from './getSubmapLinkRectangle';
import { groupSubmapLinksRectanglesById } from './groupSubmapLinksRectanglesById';
export type SubmapLinkRectangle = OverlayBioEntityRender & {
amount: number;
};
export type GroupedSubmapsLinksRectangles = {
[id: string]: SubmapLinkRectangle[];
};
export const useBioEntitiesWithSubmapsLinks = (): OverlayBioEntityRender[] => {
const { getOverlayBioEntityColorByAvailableProperties } = useGetOverlayColor();
const bioEntities = useAppSelector(overlayBioEntitiesForCurrentModelSelector);
const submapsLinks = useMemo(
() => bioEntities.filter(bioEntity => bioEntity.type === 'submap-link'),
[bioEntities],
);
const bioEntitiesWithoutSubmapsLinks = useMemo(
() => bioEntities.filter(bioEntity => bioEntity.type !== 'submap-link'),
[bioEntities],
);
const sortSubmapLinksRectanglesByColor = useCallback(
(submapLinksRectangles: SubmapLinkRectangle[]): void => {
submapLinksRectangles.sort((a, b) => {
const firstSubmapLinkRectangleColor = getOverlayBioEntityColorByAvailableProperties(a);
const secondSubmapLinkRectangleColor = getOverlayBioEntityColorByAvailableProperties(b);
if (firstSubmapLinkRectangleColor === secondSubmapLinkRectangleColor) {
return 0;
}
return firstSubmapLinkRectangleColor < secondSubmapLinkRectangleColor ? -1 : 1;
});
},
[getOverlayBioEntityColorByAvailableProperties],
);
const calculateSubmapsLinksRectanglesPosition = useCallback(
(
groupedSubmapsLinksRectanglesById: GroupedSubmapsLinksRectangles,
): OverlayBioEntityRender[] => {
const submapsLinksRectangles: SubmapLinkRectangle[] = [];
// eslint-disable-next-line no-restricted-syntax, guard-for-in
for (const id in groupedSubmapsLinksRectanglesById) {
const submapLinksRectanglesGroup = groupedSubmapsLinksRectanglesById[id];
sortSubmapLinksRectanglesByColor(submapLinksRectanglesGroup);
const submapLinkRectanglesTotalHeight = submapLinksRectanglesGroup[0].height;
const submapLinkRectanglesAmount = submapLinksRectanglesGroup.reduce(
(accumulator: number, currentValue) => accumulator + currentValue.amount,
0,
);
submapLinksRectanglesGroup.forEach((submapLinkRectangle, index) => {
const ratio = submapLinkRectangle.amount / submapLinkRectanglesAmount;
const rectangleHeight = ratio * submapLinkRectanglesTotalHeight;
getSubmapLinkRectangle(
submapsLinksRectangles,
submapLinkRectangle,
index,
submapLinksRectanglesGroup,
rectangleHeight,
);
});
}
return submapsLinksRectangles;
},
[sortSubmapLinksRectanglesByColor],
);
const groupedSubmapLinksRectanglesById = useMemo(
() => groupSubmapLinksRectanglesById(submapsLinks),
[submapsLinks],
);
const submapsLinksRectangles = useMemo(
() => calculateSubmapsLinksRectanglesPosition(groupedSubmapLinksRectanglesById),
[groupedSubmapLinksRectanglesById, calculateSubmapsLinksRectanglesPosition],
);
return [...submapsLinksRectangles, ...bioEntitiesWithoutSubmapsLinks];
};
/* eslint-disable no-magic-numbers */
import { ZERO } from '@/constants/common';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import {
getOverlayOrderSelector,
overlayBioEntitiesForCurrentModelSelector,
} from '@/redux/overlayBioEntity/overlayBioEntity.selector';
import { getOverlayOrderSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
import { LinePoint } from '@/types/reactions';
import { usePointToProjection } from '@/utils/map/usePointToProjection';
import type Feature from 'ol/Feature';
......@@ -14,12 +12,14 @@ import { createOverlayGeometryFeature } from './createOverlayGeometryFeature';
import { createOverlayLineFeature } from './createOverlayLineFeature';
import { getPolygonLatitudeCoordinates } from './getPolygonLatitudeCoordinates';
import { useGetOverlayColor } from './useGetOverlayColor';
import { createOverlaySubmapLinkRectangleFeature } from './createOverlaySubmapLinkRectangleFeature';
import { useBioEntitiesWithSubmapsLinks } from './useBioEntitiesWithSubmapLinks';
export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometry>[] => {
const pointToProjection = usePointToProjection();
const { getOverlayBioEntityColorByAvailableProperties } = useGetOverlayColor();
const overlaysOrder = useAppSelector(getOverlayOrderSelector);
const bioEntities = useAppSelector(overlayBioEntitiesForCurrentModelSelector);
const bioEntities = useBioEntitiesWithSubmapsLinks();
const features = useMemo(
() =>
......@@ -39,6 +39,16 @@ export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometr
const color = getOverlayBioEntityColorByAvailableProperties(entity);
if (entity.type === 'submap-link') {
return createOverlaySubmapLinkRectangleFeature(
[
...pointToProjection({ x: xMin, y: entity.y1 }),
...pointToProjection({ x: xMax, y: entity.y2 }),
],
entity.value === Infinity ? null : color,
);
}
if (entity.type === 'rectangle') {
return createOverlayGeometryFeature(
[
......@@ -60,7 +70,7 @@ export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometr
},
);
}),
[overlaysOrder, bioEntities, pointToProjection, getOverlayBioEntityColorByAvailableProperties],
[overlaysOrder, pointToProjection, getOverlayBioEntityColorByAvailableProperties, bioEntities],
);
return features;
......
......@@ -51,7 +51,7 @@ export const apiPath = {
getConfigurationOptions: (): string => 'configuration/options/',
getConfiguration: (): string => 'configuration/',
getOverlayBioEntity: ({ overlayId, modelId }: { overlayId: number; modelId: number }): string =>
`projects/${PROJECT_ID}/overlays/${overlayId}/models/${modelId}/bioEntities/`,
`projects/${PROJECT_ID}/overlays/${overlayId}/models/${modelId}/bioEntities/?includeIndirect=true`,
createOverlay: (projectId: string): string => `projects/${projectId}/overlays/`,
createOverlayFile: (): string => `files/`,
uploadOverlayFileContent: (fileId: number): string => `files/${fileId}:uploadContent`,
......
......@@ -78,3 +78,159 @@ export const MOCKED_OVERLAY_BIO_ENTITY_RENDER: OverlayBioEntityRender[] = [
color: null,
},
];
export const MOCKED_OVERLAY_SUBMAPS_LINKS_WITH_SAME_COLORS: OverlayBioEntityRender[] = [
{
type: 'rectangle',
id: 1,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 3128.653195488725,
y2: 3088.653195488725,
overlayId: 12,
height: 10,
value: 0,
color: null,
},
{
type: 'submap-link',
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: 23,
color: null,
},
{
type: 'submap-link',
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: 23,
color: null,
},
{
type: 'submap-link',
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: null,
color: {
alpha: 255,
rgb: -2348283,
},
},
{
type: 'submap-link',
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: null,
color: {
alpha: 255,
rgb: -2348283,
},
},
];
export const MOCKED_OVERLAY_SUBMAPS_LINKS_WITH_DIFFERENT_COLORS: OverlayBioEntityRender[] = [
{
type: 'rectangle',
id: 1,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 3128.653195488725,
y2: 3088.653195488725,
overlayId: 12,
height: 10,
value: 0,
color: null,
},
{
type: 'submap-link',
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: 0.4,
color: null,
},
{
type: 'submap-link',
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: 0.5,
color: null,
},
{
type: 'submap-link',
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: 0.8,
color: null,
},
{
type: 'submap-link',
id: 97,
modelId: 52,
width: 30,
x1: 18412,
x2: 18492,
y1: 2100.5,
y2: 2000.5,
overlayId: 12,
height: 100,
value: null,
color: {
alpha: 255,
rgb: -2348283,
},
},
];
......@@ -3,7 +3,7 @@ import { overlayBioEntitySchema } from '@/models/overlayBioEntitySchema';
import { OverlayBioEntityRender } from '@/types/OLrendering';
import { OverlayBioEntity } from '@/types/models';
import { getOverlayReactionCoordsFromLine } from '@/utils/overlays/getOverlayReactionCoords';
import { isBioEntity, isReaction } from '@/utils/overlays/overlaysElementsTypeGuards';
import { isBioEntity, isReaction, isSubmapLink } from '@/utils/overlays/overlaysElementsTypeGuards';
import { z } from 'zod';
export const parseOverlayBioEntityToOlRenderingFormat = (
......@@ -18,6 +18,24 @@ export const parseOverlayBioEntityToOlRenderingFormat = (
* Every reaction line is a different entity after reduce
*/
if (isSubmapLink(entity)) {
acc.push({
type: 'submap-link',
id: entity.left.id,
modelId: entity.left.model,
x1: entity.left.x,
y1: entity.left.y + entity.left.height,
x2: entity.left.x + entity.left.width,
y2: entity.left.y,
width: entity.left.width,
height: entity.left.height,
value: entity.right.value,
overlayId,
color: entity.right.color,
});
return acc;
}
if (isBioEntity(entity)) {
acc.push({
type: 'rectangle',
......
import { Color, GeneVariant } from './models';
export type OverlayBioEntityRenderType = 'line' | 'rectangle';
export type OverlayBioEntityRenderType = 'line' | 'rectangle' | 'submap-link';
export type OverlayBioEntityRender = {
id: number;
......
......@@ -12,3 +12,8 @@ export const isReaction = (e: OverlayBioEntity): e is OverlayElementWithReaction
export const isBioEntity = (e: OverlayBioEntity): e is OverlayElementWithBioEntity =>
(e.left as OverlayLeftBioEntity).x !== undefined &&
(e.left as OverlayLeftBioEntity).y !== undefined;
export const isSubmapLink = (e: OverlayBioEntity): e is OverlayElementWithBioEntity =>
(e.left as OverlayLeftBioEntity).x !== undefined &&
(e.left as OverlayLeftBioEntity).y !== undefined &&
(e.left as OverlayLeftBioEntity).submodel !== undefined;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment