Skip to content

Commit

Permalink
wip: implementing fragment line. TO FIX : x position of fragment label
Browse files Browse the repository at this point in the history
  • Loading branch information
gaelcartier committed Jun 18, 2024
1 parent 3c81094 commit 4906637
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 23 deletions.
3 changes: 3 additions & 0 deletions demo/Fragmentation.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { SVGMassFragmentation } from '../src/components/SVGMassFragmentation';
import { generateReactKey } from '../src/generateReactKey.js';

export default function Fragmentation({ sequence, analysisInfo, options }) {
return (
Expand All @@ -7,11 +8,13 @@ export default function Fragmentation({ sequence, analysisInfo, options }) {
border: '1px solid red',
overflow: 'clip',
}}
key={`SVG-${generateReactKey('')}`}
>
<SVGMassFragmentation
sequence={sequence}
analysisInfo={analysisInfo}
options={options}
key={`SVGMassFragmentation-${generateReactKey('')}`}
/>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion demo/data/nucleotide.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ let analysisInfo = [
];

let options = {
width: 200,
width: 300,
leftRightBorders: 50,
spaceBetweenResidues: 20,
spaceBetweenInternalLines: 12,
Expand Down
2 changes: 1 addition & 1 deletion demo/data/peptide.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const analysisInfo = [
];

const options = {
width: 400,
width: 500,
leftRightBorders: 30,
spaceBetweenResidues: 20,
spaceBetweenInternalLines: 12,
Expand Down
4 changes: 4 additions & 0 deletions demo/main.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';
import { createRoot } from 'react-dom/client';

import { generateReactKey } from '../src/generateReactKey';

import Fragmentation from './Fragmentation';
import { nucleotide } from './data/nucleotide';
import { peptide } from './data/peptide';
Expand All @@ -13,12 +15,14 @@ root.render(
sequence={peptide.sequence}
analysisInfo={peptide.analysisInfo}
options={peptide.options}
key={`fragmentation-pept-${generateReactKey('')}`}
/>
<h2>Nucléotide</h2>
<Fragmentation
sequence={nucleotide.sequence}
analysisInfo={nucleotide.analysisInfo}
options={nucleotide.options}
key={`fragmentation-nucl-${generateReactKey('')}`}
/>
</>,
);
12 changes: 10 additions & 2 deletions src/appendLines.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ function maxBreaksOnSequenceLine(breaks) {
}
return maxBreaks;
}
function totalFragments(fragements) {
let total = 0;
for (let f of fragements) {
total += f.members.length;
}
return total;
}

export function appendLines(data, options) {
const {
Expand Down Expand Up @@ -45,13 +52,14 @@ export function appendLines(data, options) {
data.height = 0;
let lastHeightBelow = 0;
for (let L of lines) {
const nbFragment = L.fragments.length;
const nbFragment = totalFragments(L.fragments);
const maxBreakAbove =
maxBreaksOnSequenceLine(L.break.filter((b) => b.fromEnd)) + 1; // 1 : sequence line height + break symbols spaces
const maxBreakBelow =
maxBreaksOnSequenceLine(L.break.filter((b) => b.fromBegin)) + 1;
L.heightBelow = maxBreakBelow * spaceBetweenInternalLines;
L.heightAbove = (maxBreakAbove + nbFragment) * spaceBetweenInternalLines;
L.heightAbove =
(maxBreakAbove + nbFragment + 1) * spaceBetweenInternalLines;
data.height += L.heightBelow + L.heightAbove;
L.totalheightAbove = lastHeightBelow + L.heightAbove;
L.y = data.height - L.heightBelow;
Expand Down
3 changes: 2 additions & 1 deletion src/appendResults.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ export function appendResults(data, analysisResult, options = {}) {
if (parts[1].match(/^[abcd][1-9]/)) {
[parts[0], parts[1]] = [parts[1], parts[0]];
}
result.to = getNumber(parts[0]) - 1;
// result.to = getNumber(parts[0]) - 1;
result.to = getNumber(parts[0]);
result.from = numberResidues - getNumber(parts[1]);
} else {
if (parts[0].match(/^[abcd][1-9]/)) {
Expand Down
55 changes: 55 additions & 0 deletions src/components/SVGFragment.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { SVGSequenceLabel } from './SVGSequenceLabel';

export function SVGFragment({
fragment,
firstIndexOnLine,
y,
indexFragment,
options,
}) {
const {
width = 600,

Check failure on line 11 in src/components/SVGFragment.jsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

'width' is assigned a value but never used
leftRightBorders = 50,
spaceBetweenResidues = 30,
spaceBetweenInternalLines = 12,
strokeWidth = 2,
labelFontFamily = 'Verdana',

Check failure on line 16 in src/components/SVGFragment.jsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

'labelFontFamily' is assigned a value but never used
labelSize = 8,

Check failure on line 17 in src/components/SVGFragment.jsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

'labelSize' is assigned a value but never used
} = options;
const xStart =
leftRightBorders +
(fragment.from - firstIndexOnLine) * spaceBetweenResidues;
const xEnd =
leftRightBorders + (fragment.to - firstIndexOnLine) * spaceBetweenResidues;
const yLine = y - indexFragment * spaceBetweenInternalLines;
console.log(xStart, xEnd, (xEnd - xStart) / 2);
return (
<>
{fragment.members.map((member, index) => (
<>
<line
x1={xStart}
y1={yLine - index * spaceBetweenInternalLines}
x2={xEnd}
y2={yLine - index * spaceBetweenInternalLines}
strokeLinecap="round"
strokeWidth={strokeWidth}
stroke={fragment.color}
key={`SVGFragment-${xStart}${xEnd}${index}`}

Check warning on line 38 in src/components/SVGFragment.jsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Do not use Array index in keys
/>
<SVGSequenceLabel
x={Math.trunc((xEnd - xStart) / 2)}
// x={xEnd}
y={yLine - index * spaceBetweenInternalLines - strokeWidth}
label={member.type}
charge={member.charge}
similarity={Math.trunc(member.similarity * 100)}
textColor={member.textColor}
options={options}
key={`fragmentLabel${member.type}${String(index)}`}
/>
</>
))}
</>
);
}
1 change: 1 addition & 0 deletions src/components/SVGFragmentLabel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export function SVGFragmentLabel(x, y, label, charge, similarity, options) {}

Check warning on line 1 in src/components/SVGFragmentLabel.jsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Unexpected empty function 'SVGFragmentLabel'
40 changes: 38 additions & 2 deletions src/components/SVGMassFragmentation.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import React from 'react';
import { createRoot } from 'react-dom/client';

import { appendLines } from '../appendLines.js';
import { appendResidues } from '../appendResidues.js';
import { appendResults, sortResults } from '../appendResults.js';
import { generateReactKey } from '../generateReactKey.js';

import { SVGSequence } from './SVGSequence.jsx';
import { SVGSequenceBreak } from './SVGSequenceBreak.jsx';
import { SVGSequenceFragments } from './SVGSequenceFragments.jsx';

function maxSequenceBreakAbove(breaks) {
let max = 0;
for (let b of breaks) {
if (b.members.length > max) max = b.members.length;
}
return max;
}

function initMassFragmentationData(sequence, analysisResults, options = {}) {
const { parsing, merge, filter } = options;
Expand All @@ -18,14 +30,27 @@ function initMassFragmentationData(sequence, analysisResults, options = {}) {
}

export function SVGMassFragmentation({ sequence, analysisInfo, options }) {
const {
width = 600,
leftRightBorders = 50,
spaceBetweenResidues = 30,
spaceBetweenInternalLines = 12,
strokeWidth = 2,
labelFontFamily = 'Verdana',
labelSize = 8,
parsing,
merge,
filter,
} = options;
const data = initMassFragmentationData(sequence, analysisInfo, options);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox={`0 0 ${options.width} ${data.height}`}
key={`SVG-${generateReactKey('')}`}
>
{data.lines.map((line, index) => (
<>
<React.Fragment key={`SVGLine-${index}`}>

Check warning on line 53 in src/components/SVGMassFragmentation.jsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Do not use Array index in keys
<SVGSequence
sequence={line.residues}
y={line.y}
Expand All @@ -39,7 +64,18 @@ export function SVGMassFragmentation({ sequence, analysisInfo, options }) {
options={options}
key={generateReactKey(`sequenceBreak-${index}`)}
/>
</>
<SVGSequenceFragments
fragments={line.fragments}
firstIndexOnLine={line.from}
y={
line.y -
(maxSequenceBreakAbove(line.break.filter((b) => b.fromEnd)) + 1) *
spaceBetweenInternalLines
}
options={options}
key={`SVGFragments-${index}`}

Check warning on line 76 in src/components/SVGMassFragmentation.jsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Do not use Array index in keys
/>
</React.Fragment>
))}
</svg>
);
Expand Down
8 changes: 4 additions & 4 deletions src/components/SVGSequenceBreakFromBegin.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SVGSequenceBreakLabel } from './SVGSequenceBreakLabel';
import { SVGSequenceLabel } from './SVGSequenceLabel';

export function SVGSequenceBreakFromBegin({
sequenceBreak,
Expand All @@ -11,7 +11,6 @@ export function SVGSequenceBreakFromBegin({
spaceBetweenResidues = 30,
spaceBetweenInternalLines = 12,
strokeWidth = 2,
labelSize = 8,
} = options;
const xStart = leftRightBorders + 1.5 * spaceBetweenResidues - strokeWidth;
const x = xStart + indexOnLine * spaceBetweenResidues;
Expand All @@ -36,12 +35,13 @@ export function SVGSequenceBreakFromBegin({
stroke={sequenceBreak.color}
/>
{sequenceBreak.members.map((m, index) => (
<SVGSequenceBreakLabel
<SVGSequenceLabel
x={x}
y={String(Number(y) + 15 + index * labelSize)}
y={String(Number(y) + 15 + index * spaceBetweenInternalLines)}
label={m.type}
charge={m.charge}
similarity={Math.trunc(m.similarity * 100)}
textColor={m.textColor}
options={options}
key={`breakLabelFromBegin${m.type}${String(index)}`}
/>
Expand Down
8 changes: 4 additions & 4 deletions src/components/SVGSequenceBreakFromEnd.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SVGSequenceBreakLabel } from './SVGSequenceBreakLabel';
import { SVGSequenceLabel } from './SVGSequenceLabel';

export function SVGSequenceBreakFromEnd({
sequenceBreak,
Expand All @@ -11,7 +11,6 @@ export function SVGSequenceBreakFromEnd({
spaceBetweenResidues = 30,
spaceBetweenInternalLines = 12,
strokeWidth = 2,
labelSize = 8,
} = options;
const xStart = leftRightBorders + 1.5 * spaceBetweenResidues + strokeWidth;
const x = xStart + indexOnLine * spaceBetweenResidues;
Expand All @@ -36,12 +35,13 @@ export function SVGSequenceBreakFromEnd({
stroke={sequenceBreak.color}
/>
{sequenceBreak.members.map((m, index) => (
<SVGSequenceBreakLabel
<SVGSequenceLabel
x={x}
y={String(Number(y) - 15 - index * labelSize)}
y={String(Number(y) - 15 - index * spaceBetweenInternalLines)}
label={m.type}
charge={m.charge}
similarity={Math.trunc(m.similarity * 100)}
textColor={m.textColor}
options={options}
key={`breakLabelFromEnd${m.type}${String(index)}`}
/>
Expand Down
37 changes: 37 additions & 0 deletions src/components/SVGSequenceFragments.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { SVGFragment } from './SVGFragment';

export function SVGSequenceFragments({
fragments,
firstIndexOnLine,
y,
options,
}) {
const {
width = 600,
leftRightBorders = 50,
spaceBetweenResidues = 30,
spaceBetweenInternalLines = 12,
strokeWidth = 2,
labelFontFamily = 'Verdana',
labelSize = 8,
} = options;
let indexFragment = 0;
return (
<>
{fragments.map((fragment, index) => {
let iF = indexFragment;
indexFragment += fragment.members.length;
return (
<SVGFragment
fragment={fragment}
firstIndexOnLine={firstIndexOnLine}
y={y}
indexFragment={iF}
options={options}
key={`SVGFragment-${index}`}

Check warning on line 31 in src/components/SVGSequenceFragments.jsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Do not use Array index in keys
/>
);
})}
</>
);
}
Original file line number Diff line number Diff line change
@@ -1,42 +1,41 @@
export function SVGSequenceBreakLabel({
export function SVGSequenceLabel({
x,
y,
label,
charge,
similarity,
textColor,
options,
}) {
const { labelFontFamily = 'Verdana', labelSize = 12 } = options;
const fontSize = String((2 * Number(labelSize)) / 3);
// console.log(x);
return (
<>
<text
fill="#999999"
fill={textColor}
fontFamily={labelFontFamily}
fontSize={fontSize}
fontWeight="bold"
textAnchor="end"
svgjs:data="{'leading':'1.3'}"
x={x}
y={y}
>
{label}
</text>
<text
fill="#999999"
fill={textColor}
fontFamily={labelFontFamily}
fontSize={String(Number(fontSize) / 2)}
svgjs:data="{'leading':'1.3'}"
x={x}
y={String(Number(y) - 4)}
y={String(Number(y) - fontSize / 2)}
>
{charge}
</text>
<text
fill="#999999"
fill={textColor}
fontFamily={labelFontFamily}
fontSize={String(Number(fontSize) / 2)}
svgjs:data="{'leading':'1.3'}"
x={x}
y={y}
>
Expand Down

0 comments on commit 4906637

Please sign in to comment.