From 4906637d620b2249ae4ff84598eead6e71fca312 Mon Sep 17 00:00:00 2001 From: gcartier Date: Tue, 18 Jun 2024 15:33:43 +0200 Subject: [PATCH] wip: implementing fragment line. TO FIX : x position of fragment label --- demo/Fragmentation.jsx | 3 + demo/data/nucleotide.js | 2 +- demo/data/peptide.js | 2 +- demo/main.jsx | 4 ++ src/appendLines.js | 12 +++- src/appendResults.js | 3 +- src/components/SVGFragment.jsx | 55 +++++++++++++++++++ src/components/SVGFragmentLabel.jsx | 1 + src/components/SVGMassFragmentation.jsx | 40 +++++++++++++- src/components/SVGSequenceBreakFromBegin.jsx | 8 +-- src/components/SVGSequenceBreakFromEnd.jsx | 8 +-- src/components/SVGSequenceFragments.jsx | 37 +++++++++++++ ...nceBreakLabel.jsx => SVGSequenceLabel.jsx} | 15 +++-- 13 files changed, 167 insertions(+), 23 deletions(-) create mode 100644 src/components/SVGFragment.jsx create mode 100644 src/components/SVGFragmentLabel.jsx create mode 100644 src/components/SVGSequenceFragments.jsx rename src/components/{SVGSequenceBreakLabel.jsx => SVGSequenceLabel.jsx} (73%) diff --git a/demo/Fragmentation.jsx b/demo/Fragmentation.jsx index c031a18..6242e80 100644 --- a/demo/Fragmentation.jsx +++ b/demo/Fragmentation.jsx @@ -1,4 +1,5 @@ import { SVGMassFragmentation } from '../src/components/SVGMassFragmentation'; +import { generateReactKey } from '../src/generateReactKey.js'; export default function Fragmentation({ sequence, analysisInfo, options }) { return ( @@ -7,11 +8,13 @@ export default function Fragmentation({ sequence, analysisInfo, options }) { border: '1px solid red', overflow: 'clip', }} + key={`SVG-${generateReactKey('')}`} > ); diff --git a/demo/data/nucleotide.js b/demo/data/nucleotide.js index 4ed6d2e..d074ddc 100644 --- a/demo/data/nucleotide.js +++ b/demo/data/nucleotide.js @@ -48,7 +48,7 @@ let analysisInfo = [ ]; let options = { - width: 200, + width: 300, leftRightBorders: 50, spaceBetweenResidues: 20, spaceBetweenInternalLines: 12, diff --git a/demo/data/peptide.js b/demo/data/peptide.js index 586edfe..5db5b8a 100644 --- a/demo/data/peptide.js +++ b/demo/data/peptide.js @@ -23,7 +23,7 @@ const analysisInfo = [ ]; const options = { - width: 400, + width: 500, leftRightBorders: 30, spaceBetweenResidues: 20, spaceBetweenInternalLines: 12, diff --git a/demo/main.jsx b/demo/main.jsx index c1085d5..4fc963e 100644 --- a/demo/main.jsx +++ b/demo/main.jsx @@ -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'; @@ -13,12 +15,14 @@ root.render( sequence={peptide.sequence} analysisInfo={peptide.analysisInfo} options={peptide.options} + key={`fragmentation-pept-${generateReactKey('')}`} />

Nucléotide

, ); diff --git a/src/appendLines.js b/src/appendLines.js index 229e18a..011bb6d 100644 --- a/src/appendLines.js +++ b/src/appendLines.js @@ -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 { @@ -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; diff --git a/src/appendResults.js b/src/appendResults.js index d50eb7a..5d8a269 100644 --- a/src/appendResults.js +++ b/src/appendResults.js @@ -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]/)) { diff --git a/src/components/SVGFragment.jsx b/src/components/SVGFragment.jsx new file mode 100644 index 0000000..7c28a01 --- /dev/null +++ b/src/components/SVGFragment.jsx @@ -0,0 +1,55 @@ +import { SVGSequenceLabel } from './SVGSequenceLabel'; + +export function SVGFragment({ + fragment, + firstIndexOnLine, + y, + indexFragment, + options, +}) { + const { + width = 600, + leftRightBorders = 50, + spaceBetweenResidues = 30, + spaceBetweenInternalLines = 12, + strokeWidth = 2, + labelFontFamily = 'Verdana', + labelSize = 8, + } = 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) => ( + <> + + + + ))} + + ); +} diff --git a/src/components/SVGFragmentLabel.jsx b/src/components/SVGFragmentLabel.jsx new file mode 100644 index 0000000..b70c22d --- /dev/null +++ b/src/components/SVGFragmentLabel.jsx @@ -0,0 +1 @@ +export function SVGFragmentLabel(x, y, label, charge, similarity, options) {} diff --git a/src/components/SVGMassFragmentation.jsx b/src/components/SVGMassFragmentation.jsx index aac0819..625591e 100644 --- a/src/components/SVGMassFragmentation.jsx +++ b/src/components/SVGMassFragmentation.jsx @@ -1,3 +1,6 @@ +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'; @@ -5,6 +8,15 @@ 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; @@ -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 ( {data.lines.map((line, index) => ( - <> + - + b.fromEnd)) + 1) * + spaceBetweenInternalLines + } + options={options} + key={`SVGFragments-${index}`} + /> + ))} ); diff --git a/src/components/SVGSequenceBreakFromBegin.jsx b/src/components/SVGSequenceBreakFromBegin.jsx index ded3ed7..2d4f76c 100644 --- a/src/components/SVGSequenceBreakFromBegin.jsx +++ b/src/components/SVGSequenceBreakFromBegin.jsx @@ -1,4 +1,4 @@ -import { SVGSequenceBreakLabel } from './SVGSequenceBreakLabel'; +import { SVGSequenceLabel } from './SVGSequenceLabel'; export function SVGSequenceBreakFromBegin({ sequenceBreak, @@ -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; @@ -36,12 +35,13 @@ export function SVGSequenceBreakFromBegin({ stroke={sequenceBreak.color} /> {sequenceBreak.members.map((m, index) => ( - diff --git a/src/components/SVGSequenceBreakFromEnd.jsx b/src/components/SVGSequenceBreakFromEnd.jsx index dbcdad2..b6351e3 100644 --- a/src/components/SVGSequenceBreakFromEnd.jsx +++ b/src/components/SVGSequenceBreakFromEnd.jsx @@ -1,4 +1,4 @@ -import { SVGSequenceBreakLabel } from './SVGSequenceBreakLabel'; +import { SVGSequenceLabel } from './SVGSequenceLabel'; export function SVGSequenceBreakFromEnd({ sequenceBreak, @@ -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; @@ -36,12 +35,13 @@ export function SVGSequenceBreakFromEnd({ stroke={sequenceBreak.color} /> {sequenceBreak.members.map((m, index) => ( - diff --git a/src/components/SVGSequenceFragments.jsx b/src/components/SVGSequenceFragments.jsx new file mode 100644 index 0000000..3a5bd0a --- /dev/null +++ b/src/components/SVGSequenceFragments.jsx @@ -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 ( + + ); + })} + + ); +} diff --git a/src/components/SVGSequenceBreakLabel.jsx b/src/components/SVGSequenceLabel.jsx similarity index 73% rename from src/components/SVGSequenceBreakLabel.jsx rename to src/components/SVGSequenceLabel.jsx index d6cc089..5d81983 100644 --- a/src/components/SVGSequenceBreakLabel.jsx +++ b/src/components/SVGSequenceLabel.jsx @@ -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 ( <> {label} {charge}