Skip to content
Snippets Groups Projects
Commit 52346740 authored by Adrian Orłów's avatar Adrian Orłów
Browse files

feat: add plugin data bio entities

parent 2553d2c1
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...,!136feat: add plugin data bio entities (MIN-224)
Pipeline #86658 passed
Showing
with 2589 additions and 22 deletions
### Data / BioEntities
The methods contained within 'Data / BioEntities' are used to access/modify data on content/drugs/chemicals entities, as well as pin and surface markers.
Below is a description of the methods, as well as the types they return. A description of the object types can be found in folder `/docs/types/`.
**Available data access methods include:**
- `getAllChemicals`
- gets list of searched chemicals
- returns array of `Chemical`
- `getAllContent`
- gets list of searched content
- returns array of `BioEntity`
- `getAllDrugs`
- gets list of searched drugs
- returns array of `Drug`
- `getAllMarkers`
- gets list of added markers
- returns array of `Marker`
- `getShownElements`
- gets list of all currently shown content/chemicals/drugs bioentities + markers
- returns object of
```
{
content: BioEntity[]
drugs: BioEntity[]
chemicals: BioEntity[]
markers: Marker[]
}
```
**Available data modify methods include:**
##### `clearAllElements`
- accepts single argument
- array of `string` which includes one or more of: `'drugs'`, `'chemicals'`, `'content'`, `'marker'`
- clears **all** elements of provided type(s)
- returns nothing
- example:
```ts
window.minerva.data.bioEntities.clearAllElements(['drugs', 'chemicals']);
```
##### `addSingleMarker`
- accepts single argument of object below
- **object:**
```
{
type: 'pin' OR 'surface'
id: string [optional]
color: string
opacity: number
x: number
y: number
width: number [optional]
height: number [optional]
number: number [optional]
modelId: number [optional]
}
```
- **id** - optional, if not provided uuidv4 is generated
- **color** - should be provided in hex format with hash (example: `#FF0000`)
- **opacity** - should be a float between `0` and `1` (example: `0.54`)
- **x** - x coord on the map
- **y** - y coord on the map
- **width** - width of surface [surface marker only]
- **height** - width of height [surface marker only]
- **number** - number presented on the pin [pin marker only]
- **modelId** - if marker should be visible only on single map, modelId should be provided
- adds one marker to markers list
- returns created `Marker`
- examples:
```ts
window.minerva.data.bioEntities.addSingleMarker({
type: 'surface',
color: '#106AD7',
opacity: 0.67,
x: 4438,
y: 1124,
width: 200,
height: 300,
modelId: 52,
});
```
```ts
window.minerva.data.bioEntities.addSingleMarker({
type: 'pin',
color: '#106AD7',
opacity: 1,
x: 8723,
y: 4322,
number: 43,
});
```
##### `removeSingleMarker`
- accepts single argument of `string` which represents marker `id`
- removes one marker from markers list
- returns nothing
- example:
```ts
window.minerva.data.bioEntities.removeSingleMarker('f4c068d1-9695-4f1b-928c-d0cff92164b2');
```
##### `removeAllMarkers`
- removes all markers from markers list
- returns nothing
- example:
```ts
window.minerva.data.bioEntities.removeAllMarkers();
```
```json
{
"type": "object",
"properties": {
"id": {
"type": "number"
},
"stringType": {
"type": "string"
},
"name": {
"type": "string"
},
"elementId": {
"type": "string"
},
"model": {
"type": "number"
},
"references": {
"type": "array",
"items": {
"type": "object",
"properties": {
"link": {
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"type": "null"
}
]
},
"article": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"authors": {
"type": "array",
"items": {
"type": "string"
}
},
"journal": {
"type": "string"
},
"year": {
"type": "number"
},
"link": {
"type": "string"
},
"pubmedId": {
"type": "string"
},
"citationCount": {
"type": "number"
}
},
"required": [
"title",
"authors",
"journal",
"year",
"link",
"pubmedId",
"citationCount"
],
"additionalProperties": false
},
"type": {
"type": "string"
},
"resource": {
"type": "string"
},
"id": {
"type": "number"
},
"annotatorClassName": {
"type": "string"
}
},
"required": ["link", "type", "resource", "id", "annotatorClassName"],
"additionalProperties": false
}
},
"z": {
"type": "number"
},
"notes": {
"type": "string"
},
"symbol": {
"type": ["string", "null"]
},
"homodimer": {
"type": "number"
},
"nameX": {
"type": "number"
},
"nameY": {
"type": "number"
},
"nameWidth": {
"type": "number"
},
"nameHeight": {
"type": "number"
},
"nameVerticalAlign": {
"type": "string"
},
"nameHorizontalAlign": {
"type": "string"
},
"width": {
"type": "number"
},
"height": {
"type": "number"
},
"visibilityLevel": {
"type": "string"
},
"transparencyLevel": {
"type": "string"
},
"synonyms": {
"type": "array",
"items": {
"type": "string"
}
},
"formerSymbols": {
"type": "array",
"items": {
"type": "string"
}
},
"fullName": {
"type": ["string", "null"]
},
"compartmentName": {
"type": ["string", "null"]
},
"abbreviation": {
"type": ["string", "null"]
},
"formula": {
"type": ["string", "null"]
},
"glyph": {
"anyOf": [
{
"type": "object",
"properties": {
"file": {
"type": "number"
}
},
"required": ["file"],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"activity": {
"type": "boolean"
},
"structuralState": {
"anyOf": [
{
"type": "object",
"properties": {
"value": {
"type": "string"
},
"position": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
}
},
"required": ["x", "y"],
"additionalProperties": false
},
"z": {
"type": "number"
},
"width": {
"type": "number"
},
"height": {
"type": "number"
},
"fontSize": {
"type": "number"
},
"size": {
"type": "number"
},
"center": {
"$ref": "#/properties/structuralState/anyOf/0/properties/position"
},
"borderColor": {
"type": "object",
"properties": {
"alpha": {
"type": "number"
},
"rgb": {
"type": "number"
}
},
"required": ["alpha", "rgb"],
"additionalProperties": false
},
"elementId": {
"type": "string"
}
},
"required": [
"value",
"position",
"z",
"width",
"height",
"fontSize",
"size",
"center",
"borderColor",
"elementId"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"hypothetical": {
"type": ["boolean", "null"]
},
"boundaryCondition": {
"type": "boolean"
},
"constant": {
"type": "boolean"
},
"initialAmount": {
"type": ["number", "null"]
},
"initialConcentration": {
"type": ["number", "null"]
},
"charge": {
"type": ["number", "null"]
},
"substanceUnits": {
"type": ["string", "null"]
},
"onlySubstanceUnits": {
"type": "boolean"
},
"modificationResidues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "number"
},
"idModificationResidue": {
"type": "string"
},
"name": {
"type": "string"
},
"position": {
"$ref": "#/properties/structuralState/anyOf/0/properties/position"
},
"z": {
"type": "number"
},
"borderColor": {
"$ref": "#/properties/structuralState/anyOf/0/properties/borderColor"
},
"state": {
"anyOf": [
{
"type": ["string", "number"]
},
{
"type": "null"
}
]
},
"size": {
"type": "number"
},
"elementId": {
"type": "string"
}
},
"required": [
"id",
"idModificationResidue",
"name",
"z",
"borderColor",
"size",
"elementId"
],
"additionalProperties": false
}
},
"complex": {
"type": ["number", "null"]
},
"compartment": {
"type": ["number", "null"]
},
"submodel": {
"anyOf": [
{
"type": "object",
"properties": {
"mapId": {
"type": "number"
},
"type": {
"type": "string"
}
},
"required": ["mapId", "type"],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"lineWidth": {
"type": "number"
},
"fontColor": {
"$ref": "#/properties/structuralState/anyOf/0/properties/borderColor"
},
"fontSize": {
"type": "number"
},
"fillColor": {
"$ref": "#/properties/structuralState/anyOf/0/properties/borderColor"
},
"borderColor": {
"$ref": "#/properties/structuralState/anyOf/0/properties/borderColor"
},
"smiles": {
"anyOf": [
{
"anyOf": [
{
"not": {}
},
{
"type": "string"
}
]
},
{
"type": "null"
}
]
},
"inChI": {
"type": ["string", "null"]
},
"inChIKey": {
"type": ["string", "null"]
},
"thickness": {
"type": "number"
},
"outerWidth": {
"type": "number"
},
"innerWidth": {
"type": "number"
},
"idReaction": {
"type": "string"
},
"reversible": {
"type": "boolean"
},
"mechanicalConfidenceScore": {
"type": "boolean"
},
"lowerBound": {
"type": "boolean"
},
"upperBound": {
"type": "boolean"
},
"subsystem": {
"type": "string"
},
"geneProteinReaction": {
"type": "string"
},
"kinetics": {
"type": "null"
},
"products": {
"type": "array",
"items": {
"type": "object",
"properties": {
"aliasId": {
"type": "number"
},
"stoichiometry": {
"type": ["number", "null"]
},
"type": {
"type": "string"
}
},
"required": ["aliasId", "stoichiometry"],
"additionalProperties": false
}
},
"reactants": {
"type": "array",
"items": {
"$ref": "#/properties/products/items"
}
},
"modifiers": {
"type": "array",
"items": {
"$ref": "#/properties/products/items"
}
},
"processCoordinates": {
"type": "null"
},
"line": {
"type": "object",
"properties": {
"id": {
"type": "number"
},
"width": {
"type": "number"
},
"color": {
"$ref": "#/properties/structuralState/anyOf/0/properties/borderColor"
},
"z": {
"type": "number"
},
"segments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"x1": {
"type": "number"
},
"y1": {
"type": "number"
},
"x2": {
"type": "number"
},
"y2": {
"type": "number"
}
},
"required": ["x1", "y1", "x2", "y2"],
"additionalProperties": false
}
},
"startArrow": {
"type": "object",
"properties": {
"arrowType": {
"type": "string"
},
"angle": {
"type": "number"
},
"lineType": {
"type": "string"
},
"length": {
"type": "number"
}
},
"required": ["arrowType", "angle", "lineType", "length"],
"additionalProperties": false
},
"endArrow": {
"$ref": "#/properties/line/properties/startArrow"
},
"lineType": {
"type": "string"
}
},
"required": ["id", "width", "color", "z", "segments", "startArrow", "endArrow", "lineType"],
"additionalProperties": false
},
"operators": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "number"
},
"line": {
"$ref": "#/properties/line"
},
"inputs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "number"
}
},
"required": ["id"],
"additionalProperties": false
}
},
"outputs": {
"not": {}
},
"operatorText": {
"type": "string"
},
"reactantOperator": {
"type": "boolean"
},
"productOperator": {
"type": "boolean"
},
"modifierOperator": {
"type": "boolean"
}
},
"required": [
"id",
"line",
"inputs",
"operatorText",
"reactantOperator",
"productOperator",
"modifierOperator"
],
"additionalProperties": false
}
}
},
"required": [
"id",
"stringType",
"name",
"elementId",
"model",
"references",
"z",
"notes",
"symbol",
"nameX",
"nameY",
"nameWidth",
"nameHeight",
"nameVerticalAlign",
"nameHorizontalAlign",
"width",
"height",
"visibilityLevel",
"transparencyLevel",
"synonyms",
"formerSymbols",
"fullName",
"abbreviation",
"formula",
"glyph",
"compartment",
"submodel",
"x",
"y",
"fontColor",
"fontSize",
"fillColor",
"borderColor"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
```
This diff is collapsed.
This diff is collapsed.
```ts
interface MarkerBase {
type: 'pin' | 'surface';
id: string;
color: string;
opacity: number;
x: number;
y: number;
number?: number;
modelId?: number;
}
```
...@@ -22,6 +22,9 @@ declare global { ...@@ -22,6 +22,9 @@ declare global {
plugins: { plugins: {
registerPlugin: RegisterPlugin; registerPlugin: RegisterPlugin;
}; };
data: {
bioEntities: BioEntitiesMethods;
};
}; };
} }
} }
...@@ -38,7 +38,9 @@ ...@@ -38,7 +38,9 @@
"tailwindcss": "3.3.3", "tailwindcss": "3.3.3",
"ts-deepmerge": "^6.2.0", "ts-deepmerge": "^6.2.0",
"use-debounce": "^9.0.4", "use-debounce": "^9.0.4",
"zod": "^3.22.2" "uuid": "^9.0.1",
"zod": "^3.22.2",
"zod-to-json-schema": "^3.22.4"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^17.7.1", "@commitlint/cli": "^17.7.1",
...@@ -50,6 +52,7 @@ ...@@ -50,6 +52,7 @@
"@types/jest": "^29.5.5", "@types/jest": "^29.5.5",
"@types/react-redux": "^7.1.26", "@types/react-redux": "^7.1.26",
"@types/redux-mock-store": "^1.0.6", "@types/redux-mock-store": "^1.0.6",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/eslint-plugin": "^6.7.0",
"@typescript-eslint/parser": "^6.7.0", "@typescript-eslint/parser": "^6.7.0",
"axios-mock-adapter": "^1.22.0", "axios-mock-adapter": "^1.22.0",
...@@ -1180,6 +1183,15 @@ ...@@ -1180,6 +1183,15 @@
"node": ">= 0.12" "node": ">= 0.12"
} }
}, },
"node_modules/@cypress/request/node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true,
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/@cypress/xvfb": { "node_modules/@cypress/xvfb": {
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz",
...@@ -2495,6 +2507,12 @@ ...@@ -2495,6 +2507,12 @@
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
}, },
"node_modules/@types/uuid": {
"version": "9.0.8",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
"dev": true
},
"node_modules/@types/yargs": { "node_modules/@types/yargs": {
"version": "17.0.32", "version": "17.0.32",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
...@@ -8532,6 +8550,15 @@ ...@@ -8532,6 +8550,15 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/jest-junit/node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true,
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/jest-leak-detector": { "node_modules/jest-leak-detector": {
"version": "29.7.0", "version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
...@@ -13457,10 +13484,13 @@ ...@@ -13457,10 +13484,13 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
}, },
"node_modules/uuid": { "node_modules/uuid": {
"version": "8.3.2", "version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
"dev": true, "funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": { "bin": {
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
...@@ -14004,6 +14034,14 @@ ...@@ -14004,6 +14034,14 @@
"zod": ">=3.0.0" "zod": ">=3.0.0"
} }
}, },
"node_modules/zod-to-json-schema": {
"version": "3.22.4",
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.4.tgz",
"integrity": "sha512-2Ed5dJ+n/O3cU383xSY28cuVi0BCQhF8nYqWU5paEpl7fVdqdAmiLdqLyfblbNdfOFwFfi/mqU4O1pwc60iBhQ==",
"peerDependencies": {
"zod": "^3.22.4"
}
},
"node_modules/zstddec": { "node_modules/zstddec": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.1.0.tgz", "resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.1.0.tgz",
...@@ -14850,6 +14888,12 @@ ...@@ -14850,6 +14888,12 @@
"combined-stream": "^1.0.6", "combined-stream": "^1.0.6",
"mime-types": "^2.1.12" "mime-types": "^2.1.12"
} }
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true
} }
} }
}, },
...@@ -15861,6 +15905,12 @@ ...@@ -15861,6 +15905,12 @@
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
}, },
"@types/uuid": {
"version": "9.0.8",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
"dev": true
},
"@types/yargs": { "@types/yargs": {
"version": "17.0.32", "version": "17.0.32",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
...@@ -20183,6 +20233,12 @@ ...@@ -20183,6 +20233,12 @@
"requires": { "requires": {
"ansi-regex": "^5.0.1" "ansi-regex": "^5.0.1"
} }
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true
} }
} }
}, },
...@@ -23678,10 +23734,9 @@ ...@@ -23678,10 +23734,9 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
}, },
"uuid": { "uuid": {
"version": "8.3.2", "version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
"dev": true
}, },
"v8-compile-cache-lib": { "v8-compile-cache-lib": {
"version": "3.0.1", "version": "3.0.1",
...@@ -24095,6 +24150,12 @@ ...@@ -24095,6 +24150,12 @@
"randexp": "^0.5.3" "randexp": "^0.5.3"
} }
}, },
"zod-to-json-schema": {
"version": "3.22.4",
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.4.tgz",
"integrity": "sha512-2Ed5dJ+n/O3cU383xSY28cuVi0BCQhF8nYqWU5paEpl7fVdqdAmiLdqLyfblbNdfOFwFfi/mqU4O1pwc60iBhQ==",
"requires": {}
},
"zstddec": { "zstddec": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.1.0.tgz", "resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.1.0.tgz",
......
import { GeneVariant } from '@/types/models'; import { GeneVariant } from '@/types/models';
export interface OverlayDataAxis { export interface OverlayDataAxis {
id: number; id: number | string;
title: string; title: string;
value?: number; value?: number;
color: string; color: string;
......
...@@ -74,7 +74,7 @@ describe('BioEntitiesAccordion - component', () => { ...@@ -74,7 +74,7 @@ describe('BioEntitiesAccordion - component', () => {
expect(screen.getByText('Content (10)')).toBeInTheDocument(); expect(screen.getByText('Content (10)')).toBeInTheDocument();
expect(screen.getByText('Core PD map (5)')).toBeInTheDocument(); expect(screen.getByText('Core PD map (5)')).toBeInTheDocument();
expect(screen.getByText('Histamine signaling (2)')).toBeInTheDocument(); expect(screen.getByText('Histamine signaling (3)')).toBeInTheDocument();
expect(screen.getByText('PRKN substrates (3)')).toBeInTheDocument(); expect(screen.getByText('PRKN substrates (2)')).toBeInTheDocument();
}); });
}); });
...@@ -10,7 +10,7 @@ export type PinItem = { ...@@ -10,7 +10,7 @@ export type PinItem = {
export type PinTypeWithNone = PinType | 'none'; export type PinTypeWithNone = PinType | 'none';
export type AvailableSubmaps = { export type AvailableSubmaps = {
id: number; id: number | string;
modelId: number; modelId: number;
name: string; name: string;
}; };
...@@ -59,7 +59,9 @@ export const drawNumberOnCanvas = ( ...@@ -59,7 +59,9 @@ export const drawNumberOnCanvas = (
ctx.fillText(text, x, y); ctx.fillText(text, x, y);
}; };
export const getCanvasIcon = (args: Args): HTMLCanvasElement => { export const getCanvasIcon = (
args: Omit<Args, 'value'> & { value?: number },
): HTMLCanvasElement => {
const canvas = createCanvas(PIN_SIZE); const canvas = createCanvas(PIN_SIZE);
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
if (!ctx) { if (!ctx) {
...@@ -67,7 +69,9 @@ export const getCanvasIcon = (args: Args): HTMLCanvasElement => { ...@@ -67,7 +69,9 @@ export const getCanvasIcon = (args: Args): HTMLCanvasElement => {
} }
drawPinOnCanvas(args, ctx); drawPinOnCanvas(args, ctx);
drawNumberOnCanvas(args, ctx); if (args?.value !== undefined) {
drawNumberOnCanvas({ value: args.value }, ctx);
}
return canvas; return canvas;
}; };
import { MarkerSurface } from '@/redux/markers/markers.types';
import { OverlayBioEntityRender } from '@/types/OLrendering';
import { parseSurfaceMarkersToBioEntityRender } from './parseSurfaceMarkersToBioEntityRender';
const MARKERS: MarkerSurface[] = [
{
type: 'surface',
id: '1',
color: '#000000',
opacity: 0.1,
x: 1200,
y: 500,
width: 100,
height: 50,
number: 0,
modelId: 0,
},
{
type: 'surface',
id: '2',
color: '#FF0000',
opacity: 0.67,
x: 432,
y: 2343,
width: 100,
height: 50,
number: 23,
modelId: 33,
},
{
type: 'surface',
id: '3',
color: '#FFFFFF',
opacity: 0,
x: 1,
y: 1,
width: 2,
height: 2,
number: 1,
modelId: 1,
},
];
const EXPECTED_RETURN: OverlayBioEntityRender[] = [
{
color: null,
height: 50,
hexColor: '#0000001a',
id: '1',
modelId: 0,
overlayId: 0,
type: 'rectangle',
value: 0.1,
width: 100,
x1: 1200,
x2: 1300,
y1: 550,
y2: 500,
},
{
color: null,
height: 50,
hexColor: '#FF0000ab',
id: '2',
modelId: 33,
overlayId: 0,
type: 'rectangle',
value: 0.67,
width: 100,
x1: 432,
x2: 532,
y1: 2393,
y2: 2343,
},
{
color: null,
height: 2,
hexColor: '#FFFFFF00',
id: '3',
modelId: 1,
overlayId: 0,
type: 'rectangle',
value: 0,
width: 2,
x1: 1,
x2: 3,
y1: 3,
y2: 1,
},
];
describe('parseSurfaceMarkersToBioEntityRender - util', () => {
it('returns correctly parsed markers for every element', () => {
expect(parseSurfaceMarkersToBioEntityRender(MARKERS)).toStrictEqual(EXPECTED_RETURN);
});
});
import { ZERO } from '@/constants/common';
import { MarkerSurface } from '@/redux/markers/markers.types';
import { OverlayBioEntityRender } from '@/types/OLrendering';
import { addAlphaToHexString } from '@/utils/convert/addAlphaToHexString';
export const parseSurfaceMarkersToBioEntityRender = (
markers: MarkerSurface[],
): OverlayBioEntityRender[] => {
return markers.map(({ id, modelId, x, y, width, height, color, opacity }) => ({
type: 'rectangle',
id,
x1: x,
y1: y + height,
x2: x + width,
y2: y,
width,
height,
value: opacity,
modelId: modelId || ZERO, // ignored in next steps
overlayId: ZERO, // ignored in next steps
color: null, // replaced by hexColor in next steps
hexColor: addAlphaToHexString(color, opacity),
}));
};
/* eslint-disable no-magic-numbers */ /* eslint-disable no-magic-numbers */
import { CONFIGURATION_INITIAL_STORE_MOCKS } from '@/redux/configuration/configuration.mock'; import { CONFIGURATION_INITIAL_STORE_MOCKS } from '@/redux/configuration/configuration.mock';
import { mapStateWithCurrentlySelectedMainMapFixture } from '@/redux/map/map.fixtures'; import { mapStateWithCurrentlySelectedMainMapFixture } from '@/redux/map/map.fixtures';
import { SURFACE_MARKER } from '@/redux/models/marker.mock';
import { MODELS_DATA_MOCK_WITH_MAIN_MAP } from '@/redux/models/models.mock'; import { MODELS_DATA_MOCK_WITH_MAIN_MAP } from '@/redux/models/models.mock';
import { MOCKED_OVERLAY_BIO_ENTITY_RENDER } from '@/redux/overlayBioEntity/overlayBioEntity.mock'; import { MOCKED_OVERLAY_BIO_ENTITY_RENDER } from '@/redux/overlayBioEntity/overlayBioEntity.mock';
import { OVERLAYS_PUBLIC_FETCHED_STATE_MOCK } from '@/redux/overlays/overlays.mock'; import { OVERLAYS_PUBLIC_FETCHED_STATE_MOCK } from '@/redux/overlays/overlays.mock';
...@@ -43,6 +44,9 @@ describe('useOverlayFeatures', () => { ...@@ -43,6 +44,9 @@ describe('useOverlayFeatures', () => {
models: { models: {
...MODELS_DATA_MOCK_WITH_MAIN_MAP, ...MODELS_DATA_MOCK_WITH_MAIN_MAP,
}, },
markers: {
data: [SURFACE_MARKER],
},
}); });
it('should return an array of features', () => { it('should return an array of features', () => {
...@@ -52,7 +56,7 @@ describe('useOverlayFeatures', () => { ...@@ -52,7 +56,7 @@ describe('useOverlayFeatures', () => {
wrapper: Wrapper, wrapper: Wrapper,
}); });
expect(features).toHaveLength(10); expect(features).toHaveLength(11);
// type: rectangle // type: rectangle
expect(features[0].getGeometry()?.getCoordinates()).toEqual([ expect(features[0].getGeometry()?.getCoordinates()).toEqual([
...@@ -81,5 +85,19 @@ describe('useOverlayFeatures', () => { ...@@ -81,5 +85,19 @@ describe('useOverlayFeatures', () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
expect(features[7].getStyle().getFill().getColor()).toBe('#ff0000cc'); expect(features[7].getStyle().getFill().getColor()).toBe('#ff0000cc');
// type: rectangle (marker)
expect(features[10].getGeometry()?.getCoordinates()).toEqual([
[
[-19588560, 19831740],
[-19588560, 19850446],
[-19551147, 19850446],
[-19551147, 19831740],
[-19588560, 19831740],
],
]);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
expect(features[10].getStyle().getFill().getColor()).toBe('#0000001a');
}); });
}); });
import { ZERO } from '@/constants/common'; import { ZERO } from '@/constants/common';
import { useAppSelector } from '@/redux/hooks/useAppSelector'; import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { markersSufraceOfCurrentMapDataSelector } from '@/redux/markers/markers.selectors';
import { getOverlayOrderSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector'; import { getOverlayOrderSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
import { LinePoint } from '@/types/reactions'; import { LinePoint } from '@/types/reactions';
import { usePointToProjection } from '@/utils/map/usePointToProjection'; import { usePointToProjection } from '@/utils/map/usePointToProjection';
...@@ -9,17 +10,36 @@ import type Polygon from 'ol/geom/Polygon'; ...@@ -9,17 +10,36 @@ import type Polygon from 'ol/geom/Polygon';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { createOverlayGeometryFeature } from './createOverlayGeometryFeature'; import { createOverlayGeometryFeature } from './createOverlayGeometryFeature';
import { createOverlayLineFeature } from './createOverlayLineFeature'; import { createOverlayLineFeature } from './createOverlayLineFeature';
import { createOverlaySubmapLinkRectangleFeature } from './createOverlaySubmapLinkRectangleFeature';
import { getPolygonLatitudeCoordinates } from './getPolygonLatitudeCoordinates'; import { getPolygonLatitudeCoordinates } from './getPolygonLatitudeCoordinates';
import { useGetOverlayColor } from './useGetOverlayColor'; import { parseSurfaceMarkersToBioEntityRender } from './parseSurfaceMarkersToBioEntityRender';
import { useBioEntitiesWithSubmapsLinks } from './useBioEntitiesWithSubmapLinks'; import { useBioEntitiesWithSubmapsLinks } from './useBioEntitiesWithSubmapLinks';
import { createOverlaySubmapLinkRectangleFeature } from './createOverlaySubmapLinkRectangleFeature'; import { useGetOverlayColor } from './useGetOverlayColor';
export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometry>[] => { export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometry>[] => {
const pointToProjection = usePointToProjection(); const pointToProjection = usePointToProjection();
const { getOverlayBioEntityColorByAvailableProperties } = useGetOverlayColor(); const { getOverlayBioEntityColorByAvailableProperties } = useGetOverlayColor();
const overlaysOrder = useAppSelector(getOverlayOrderSelector); const overlaysOrder = useAppSelector(getOverlayOrderSelector);
const currentMarkers = useAppSelector(markersSufraceOfCurrentMapDataSelector);
const markersRender = parseSurfaceMarkersToBioEntityRender(currentMarkers);
const bioEntities = useBioEntitiesWithSubmapsLinks(); const bioEntities = useBioEntitiesWithSubmapsLinks();
const markersFeatures = useMemo(
() =>
markersRender.map(entity => {
const color = getOverlayBioEntityColorByAvailableProperties(entity);
return createOverlayGeometryFeature(
[
...pointToProjection({ x: entity.x1, y: entity.y1 }),
...pointToProjection({ x: entity.x2, y: entity.y2 }),
],
entity?.hexColor || color,
);
}),
[getOverlayBioEntityColorByAvailableProperties, markersRender, pointToProjection],
);
const features = useMemo( const features = useMemo(
() => () =>
bioEntities.map(entity => { bioEntities.map(entity => {
...@@ -36,7 +56,9 @@ export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometr ...@@ -36,7 +56,9 @@ export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometr
overlaysOrder.find(({ id }) => id === entity.overlayId)?.index || ZERO, overlaysOrder.find(({ id }) => id === entity.overlayId)?.index || ZERO,
}); });
const color = getOverlayBioEntityColorByAvailableProperties(entity); const calculatedColor = getOverlayBioEntityColorByAvailableProperties(entity);
const hexColor = entity?.hexColor;
const color = hexColor || calculatedColor;
if (entity.type === 'submap-link') { if (entity.type === 'submap-link') {
return createOverlaySubmapLinkRectangleFeature( return createOverlaySubmapLinkRectangleFeature(
...@@ -72,5 +94,5 @@ export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometr ...@@ -72,5 +94,5 @@ export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometr
[overlaysOrder, pointToProjection, getOverlayBioEntityColorByAvailableProperties, bioEntities], [overlaysOrder, pointToProjection, getOverlayBioEntityColorByAvailableProperties, bioEntities],
); );
return features; return [...features, ...markersFeatures];
}; };
import { initialMapStateFixture } from '@/redux/map/map.fixtures';
import { PIN_MARKER } from '@/redux/models/marker.mock';
import { UsePointToProjectionResult, usePointToProjection } from '@/utils/map/usePointToProjection';
import {
GetReduxWrapperUsingSliceReducer,
getReduxWrapperWithStore,
} from '@/utils/testing/getReduxWrapperWithStore';
import { renderHook } from '@testing-library/react';
import { Feature } from 'ol';
import Style from 'ol/style/Style';
import { getMarkerSingleFeature } from './getMarkerSingleFeature';
import * as getPinStyle from './getPinStyle';
jest.mock('./getPinStyle', () => ({
__esModule: true,
...jest.requireActual('./getPinStyle'),
}));
const getPinStyleSpy = jest.spyOn(getPinStyle, 'getPinStyle');
const getPointToProjection = (
wrapper: ReturnType<GetReduxWrapperUsingSliceReducer>['Wrapper'],
): UsePointToProjectionResult => {
const { result: usePointToProjectionHook } = renderHook(() => usePointToProjection(), {
wrapper,
});
return usePointToProjectionHook.current;
};
describe('getMarkerSingleFeature - subUtil', () => {
const { Wrapper } = getReduxWrapperWithStore({
map: initialMapStateFixture,
});
const pointToProjection = getPointToProjection(Wrapper);
it('should return instance of Feature with Style type=%s', () => {
const result = getMarkerSingleFeature(PIN_MARKER, {
pointToProjection,
});
const style = result.getStyle() as Style;
expect(result).toBeInstanceOf(Feature);
expect(style).toBeInstanceOf(Style);
});
it('should run getPinStyle with valid args for type=%s', () => {
getMarkerSingleFeature(PIN_MARKER, {
pointToProjection,
});
expect(getPinStyleSpy).toHaveBeenCalledWith({
color: '#0000001a',
value: PIN_MARKER.number,
});
});
});
import { Marker } from '@/redux/markers/markers.types';
import { addAlphaToHexString } from '@/utils/convert/addAlphaToHexString';
import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
import { Feature } from 'ol';
import { getPinFeature } from './getPinFeature';
import { getPinStyle } from './getPinStyle';
export const getMarkerSingleFeature = (
marker: Marker,
{
pointToProjection,
}: {
pointToProjection: UsePointToProjectionResult;
},
): Feature => {
const feature = getPinFeature(marker, pointToProjection);
const style = getPinStyle({
color: addAlphaToHexString(marker.color, marker.opacity),
value: marker.number,
});
feature.setStyle(style);
return feature;
};
import { Marker } from '@/redux/markers/markers.types';
import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
import { Feature } from 'ol';
import { getMarkerSingleFeature } from './getMarkerSingleFeature';
export const getMarkersFeatures = (
markers: Marker[],
{
pointToProjection,
}: {
pointToProjection: UsePointToProjectionResult;
},
): Feature[] => {
return markers.map(marker =>
getMarkerSingleFeature(marker, {
pointToProjection,
}),
);
};
import { HALF } from '@/constants/dividers'; import { HALF } from '@/constants/dividers';
import { bioEntityContentFixture } from '@/models/fixtures/bioEntityContentsFixture'; import { bioEntityContentFixture } from '@/models/fixtures/bioEntityContentsFixture';
import { initialMapStateFixture } from '@/redux/map/map.fixtures'; import { initialMapStateFixture } from '@/redux/map/map.fixtures';
import { PIN_MARKER } from '@/redux/models/marker.mock';
import { usePointToProjection } from '@/utils/map/usePointToProjection'; import { usePointToProjection } from '@/utils/map/usePointToProjection';
import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore'; import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
import { renderHook } from '@testing-library/react'; import { renderHook } from '@testing-library/react';
...@@ -35,4 +36,18 @@ describe('getPinFeature - subUtil', () => { ...@@ -35,4 +36,18 @@ describe('getPinFeature - subUtil', () => {
expect([x, y]).toStrictEqual(geometryPoint); expect([x, y]).toStrictEqual(geometryPoint);
}); });
describe('when is Marker Pin', () => {
const pinMarkerResult = getPinFeature(PIN_MARKER, pointToProjection);
it('should return point parsed with point to projection', () => {
const [x, y] = pinMarkerResult.getGeometry()?.getExtent() || [];
const geometryPoint = pointToProjection({
x: PIN_MARKER.x,
y: PIN_MARKER.y,
});
expect([x, y]).toStrictEqual(geometryPoint);
});
});
}); });
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