UNPKG

sbgn-renderer

Version:

A library that renders SBGN

236 lines (181 loc) 7.55 kB
const memoize = require('lodash.memoize'); const baseShapes = require('./baseShapes'); const auxiliaryItems = require('./auxiliaryItems'); const svgStr = require('../util/svg').svgStr; const getUnitInfos = require('../util/sbgn').getUnitInfos; const getStateVars = require('../util/sbgn').getStateVars; const hasClonemarker = require('../util/sbgn').hasClonemarker; const isMultimer = require('../util/sbgn').isMultimer; const dimensions = require('../dimensions'); const entityPoolNodes = { unspecifiedEntity (node) { const {w: nw, h: nh} = dimensions.get(node); const styleMap = new Map() .set('stroke', '#6A6A6A') .set('stroke-width', '2') .set('fill', 'none'); let shapeArgs = [nw / 2, nh / 2, ( nh - 2 ) / 2, ( nw - 2 ) / 2]; let unspecEntitySvg = ` ${baseShapes.ellipse(...shapeArgs, styleMap)} ${hasClonemarker(node) ? auxiliaryItems.cloneMarker(nw, nh, baseShapes.ellipse, shapeArgs) : ''} `; return svgStr(unspecEntitySvg, nw, nh, 0, 0, nw, nh); }, simpleChemical (node) { const {w: nw, h: nh} = dimensions.get(node); const styleMap = new Map() .set('stroke', '#6A6A6A') .set('stroke-width', '2') .set('fill', 'white') .set('fill-opacity', '1'); const multimerShapeArgs = [(nw + 3) / 2, (nh + 3) / 2, (Math.min(nw, nh) - 2 - 5) / 2]; let shapeArgs = [(nw) / 2, (nh) / 2, (Math.min(nh, nw) - 2) / 2]; const uInfos = getUnitInfos(node); if (uInfos.length > 0) { shapeArgs = [(nw) / 2, (nh) / 2, (Math.min(nh, nw) - 2 - 5) / 2]; } if (isMultimer(node)) { shapeArgs = [(nw - 3) / 2, (nh - 3) / 2, (Math.min(nh, nw) - 2 - 7) / 2]; } const simpleChemicalSvg = ` ${isMultimer(node) ? auxiliaryItems.multimer(baseShapes.circle, multimerShapeArgs) : ''} ${baseShapes.circle(...shapeArgs, styleMap)} ${hasClonemarker(node) ? auxiliaryItems.cloneMarker(nw, nh, baseShapes.circle, shapeArgs) : ''} ${uInfos.length > 0 ? auxiliaryItems.unitOfInformation((nw / 2), 1, 0.4*nw, 0.2*nh, uInfos[0]) : ''} `; return svgStr(simpleChemicalSvg, nw, nh, 0, 0, nw, nh); }, macromolecule(node) { const {w: nw, h: nh} = dimensions.get(node); const styleMap = new Map() .set('stroke', '#6A6A6A') .set('stroke-width', '2') .set('fill', 'none') .set('fill', 'white') .set('fill-opacity', '1'); const multimerShapeArgs = [15, 10, .8*nw, .8*nh]; let shapeArgs = [5, 5, nw - 10, nh - 10]; const uInfos = getUnitInfos(node); const sVars = getStateVars(node); if (uInfos.length > 0) { shapeArgs = [5, 5, .9*nw, .9*nh]; } if (sVars.length > 0) { shapeArgs[3] = .85*nh; } if (isMultimer(node)) { shapeArgs = [5, 5, .83*nw, .78*nh]; } let macromoleculeSvg = ` ${isMultimer(node) ? auxiliaryItems.multimer(baseShapes.roundRectangle, multimerShapeArgs) : ''} ${baseShapes.roundRectangle(...shapeArgs, styleMap)} ${hasClonemarker(node) ? auxiliaryItems.cloneMarker(nw - 3, nh - 3, baseShapes.roundRectangle, shapeArgs) : ''} ${uInfos.length > 0 ? auxiliaryItems.unitOfInformation((nw / 3), 1, 0.4*nw, 0.2*nh, uInfos[0]) : ''} ${sVars.length > 0 ? auxiliaryItems.stateVariable((2 * nw / 4), nh - (0.225*nh / 2), 0.1*nh, sVars[0]) : ''} `; return svgStr(macromoleculeSvg, nw, nh, 0, 0, nw, nh); }, nucleicAcidFeature (node) { const {w: nw, h: nh} = dimensions.get(node); const styleMap = new Map() .set('stroke', '#6A6A6A') .set('stroke-width', '2') .set('fill', 'none') .set('fill', 'white') .set('fill-opacity', '1'); const multimerShapeArgs = [15, 10, .8*nw, .8*nh]; let shapeArgs = [1.5, 1.5, nw - 3, nh - 3]; const uInfos = getUnitInfos(node); const sVars = getStateVars(node); if (uInfos.length > 0) { shapeArgs = [5, 5, .9*nw, .88*nh]; } if (sVars.length > 0) { shapeArgs[3] = .85*nh; } if (isMultimer(node)) { shapeArgs = [5, 5, .83*nw, .78*nh]; } let nucleicAcidFeatureSvg = ` ${isMultimer(node) ? auxiliaryItems.multimer(baseShapes.roundBottomRectangle, multimerShapeArgs) : ''} ${baseShapes.roundBottomRectangle(...shapeArgs, styleMap)} ${hasClonemarker(node) ? auxiliaryItems.cloneMarker(nw, nh, baseShapes.roundBottomRectangle, shapeArgs) : ''} ${uInfos.length > 0 ? auxiliaryItems.unitOfInformation((nw / 3), 1, 0.4*nw, 0.2*nh, uInfos[0]) : ''} ${sVars.length > 0 ? auxiliaryItems.stateVariable((2 * nw / 4), nh - (0.225*nh / 2), 0.1*nh, sVars[0]) : ''} `; return svgStr(nucleicAcidFeatureSvg, nw, nh, 0, 0, nw, nh); }, complex (node) { const auxItemWidth = 60; const auxItemHeight = 24; const uInfos = getUnitInfos(node); const sVars = getStateVars(node); const style = new Map() .set('stroke', '#555555') .set('stroke-width', '6'); const cloneMarkerSvg = svgStr( hasClonemarker(node) ? auxiliaryItems.compoundCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '', auxItemWidth, auxItemHeight, 0, 0, auxItemWidth, auxItemHeight ); const uInfoSvg = svgStr( uInfos.length > 0 ? auxiliaryItems.compoundUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight, uInfos[0]) : '', auxItemWidth, auxItemHeight, 0, 0, auxItemWidth, auxItemHeight ); const sVarSvg = svgStr( sVars.length > 0 ? auxiliaryItems.compoundStateVar(2, 0, auxItemWidth - 5, auxItemHeight, sVars[0]) : '', auxItemWidth, auxItemHeight, 0, 0, auxItemWidth, auxItemHeight ); const topLine = svgStr( uInfos.length + sVars.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight, 0, 0, auxItemWidth, auxItemHeight ); const bottomLine = svgStr( hasClonemarker(node) ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight, 0, 0, auxItemWidth, auxItemHeight ); return [bottomLine, topLine, cloneMarkerSvg, uInfoSvg, sVarSvg]; // ordering of svg images matters }, sourceAndSink (node) { const {w: nw, h: nh} = dimensions.get(node); const centerX = nw / 2; const centerY = nh / 2; const radius = (nw - 2) / 2; const styleMap = new Map() .set('stroke', '#6A6A6A') .set('stroke-linecap', 'square') .set('stroke-width', '1.5') .set('fill', 'none'); const shapeArgs = [centerX, centerY, radius]; const sourceAndSinkSvg = ` ${baseShapes.circle(...shapeArgs, styleMap)} ${hasClonemarker(node) ? auxiliaryItems.cloneMarker(nw, nh, baseShapes.circle, shapeArgs) : ''} ${baseShapes.line(0, nh, nw, 0, styleMap)} `; return svgStr(sourceAndSinkSvg, nw, nh, 0, 0, nw, nh); }, perturbingAgent (node) { const {w: nw, h: nh} = dimensions.get(node); const styleMap = new Map() .set('stroke', '#6A6A6A') .set('stroke-width', '2') .set('fill', 'none'); let shapeArgs = [1, 1, nw - 4, nh - 2]; const uInfos = getUnitInfos(node); if (uInfos.length > 0) { shapeArgs = [5, 5, .9*nw, .9*nh]; } const perturbingAgentSvg = ` ${baseShapes.concaveHexagon(...shapeArgs, styleMap)} ${hasClonemarker(node) ? auxiliaryItems.cloneMarker(nw - 3, nh - 3, baseShapes.concaveHexagon, shapeArgs) : ''} ${uInfos.length > 0 ? auxiliaryItems.unitOfInformation((nw / 3), 1, 0.4*nw, 0.2*nh, uInfos[0]) : ''} `; return svgStr(perturbingAgentSvg, nw, nh, 0, 0, nw, nh); } }; module.exports = entityPoolNodes;