diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..0a20249
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "closure-compiler"]
+ path = closure-compiler
+ url = https://github.com/google/closure-compiler.git
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..275c227
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,17 @@
+all: closure-compiler/build/compiler.jar js/fornac.js
+
+js/fornac.js: src/*.js
+ java -jar closure-compiler/build/compiler.jar --compilation_level=SIMPLE_OPTIMIZATIONS --js_output_file=js/fornac.js src/*.js
+
+closure-compiler/build/compiler.jar: closure-compiler/*
+ git submodule init closure-compiler
+ git submodule update closure-compiler
+ cd closure-compiler; ant jar
+
+release: js/fornac.js
+ zip fornac-release.zip js/fornac.js css/fornac.css example.html README.md
+
+clean:
+ rm -f closure-compiler/build/compiler.jar js/fornac.js fornac-release.zip
+
+.PHONY: all
diff --git a/README.md b/README.md
index e69de29..510f2b4 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,57 @@
+# FornaContainer
+
+In many situations, the user interaction is superfluous and the desired goal is to simply display a secondary structure on a web page. This is a common scenario in, for example, servers that predict a secondary structure. The output, a dot-bracket string can simply be added to a `FornaContainer` object to display.
+
+## Trivial Example
+
+Below is an example of a simple web page which uses a `FornaContainer` to show a simple RNA molecule:
+
+![blah blah](https://raw.githubusercontent.com/pkerpedjiev/fornac/develop/doc/img/forna-container-screenshot.png "An example of the FornaContainer")
+
+The code for creating this web page is rather straightforward. After importing some necessary javascript files, we create a container using `new FornaContainer("#rna_ss", {'applyForce': false})`, passing in `#rna_ss` as the id of the `div` which will hold the container and then populate it with a structure and sequence using `container.addRNA`:
+
+```html
+
+
+
+This is an RNA container.
+
+This after the RNA container.
+
+
+
+
+
+
+```
+## Options
+
+The `FornaContainer` supports a number of options to allow users to customize how the RNA will be presented.
+
+### applyForce
+
+Indicate whether the force-directed layout will be applied to the displayed molecule. Enabling this option allows users to change the layout of the molecule by selecting and dragging the individual nucleotide nodes
+
+### allowPanningAndZooming
+
+Allow users to zoom in and pan the display. If this is enabled then pressing the 'c' key on the keyboard will center the view.
+
+### Installation
+
+You need [ANT](http://ant.apache.org/), [Java](http://java.com) and [GNU Make](https://www.gnu.org/software/make/) installed if you want to produce a release javascript file (compressed and optimized). Then just type:
+```sh
+$ make
+```
+Optionally, you can just cat all javascript files into one file:
+```sh
+$ cat src/*.js > js/fornac.js
+```
+Do not forget to run the unit tests in `test.html` to check for regressions!
diff --git a/closure-compiler b/closure-compiler
new file mode 160000
index 0000000..377d901
--- /dev/null
+++ b/closure-compiler
@@ -0,0 +1 @@
+Subproject commit 377d9016a6316d174f9bd9bc1db0d33ee6ede187
diff --git a/css/fornac.css b/css/fornac.css
new file mode 100644
index 0000000..633f329
--- /dev/null
+++ b/css/fornac.css
@@ -0,0 +1,125 @@
+svg {
+ display: block;
+ min-width: 100%;
+ width: 100%;
+ min-height: 100%;
+}
+
+circle.node {
+ stroke: #ccc;
+ stroke-width: 1px;
+ opacity: 1;
+ fill: white;
+}
+
+circle.node.label {
+ stroke: transparent;
+ stroke-width: 0;
+ fill: white;
+}
+
+circle.outline_node {
+ stroke-width: 1px;
+ fill: red;
+}
+
+circle.protein {
+ fill: gray;
+ fill-opacity: 0.5;
+ stroke-width: 4;
+}
+
+circle.hidden_outline {
+ stroke-width: 0px;
+}
+
+
+line.link {
+ stroke: #999;
+ stroke-opacity: 0.8;
+ stroke-width: 2;
+}
+
+line.basepair {
+ stroke: red;
+}
+
+line.intermolecule {
+ stroke: blue;
+}
+
+line.chain_chain {
+ stroke-dasharray: 3,3;
+}
+
+line.fake {
+ stroke: green;
+}
+
+.transparent {
+ fill: transparent;
+ stroke-width: 0;
+ stroke-opacity: 0;
+ opacity: 0;
+ visibility: hidden;
+}
+
+.drag_line {
+ stroke: #999;
+ stroke-width: 2;
+ pointer-events: none;
+}
+
+.drag_line_hidden {
+ stroke: #999;
+ stroke-width: 0;
+ pointer-events: none;
+}
+
+.d3-tip {
+ line-height: 1;
+ font-weight: bold;
+ padding: 6px;
+ background: rgba(0, 0, 0, 0.6);
+ color: #fff;
+ border-radius: 4px;
+ pointer-events: none;
+ }
+
+text.node-label {
+ font-weight: bold;
+ font-family: Tahoma, Geneva, sans-serif;
+ color: rgb(100,100,100);
+ pointer-events: none;
+}
+
+text {
+ pointer-events: none;
+}
+
+g.gnode {
+
+}
+
+circle.outline_node.selected {
+ visibility: visible;
+}
+
+circle.outline_node {
+ visibility: hidden;
+}
+
+.brush .extent {
+ fill-opacity: .1;
+ stroke: #fff;
+ shape-rendering: crispEdges;
+}
+
+.noselect {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
diff --git a/doc/img/forna-container-screenshot.png b/doc/img/forna-container-screenshot.png
new file mode 100644
index 0000000..3edddad
Binary files /dev/null and b/doc/img/forna-container-screenshot.png differ
diff --git a/example.html b/example.html
index 8b21cb2..4263086 100644
--- a/example.html
+++ b/example.html
@@ -1,26 +1,22 @@
-
-This is an RNA container.
+This is an RNA container.
-
This after the RNA container.
-
-
-
-
-
-
-
-
+
+
-var options = {'structure': '((..((....)).(((....))).))',
- 'sequence': 'CGCUUCAUAUAAUCCUAAUGACCUAU'
-};
+
+ container.addRNA(options.structure, options);
+
diff --git a/example_transition.html b/example_transition.html
new file mode 100644
index 0000000..a219811
--- /dev/null
+++ b/example_transition.html
@@ -0,0 +1,30 @@
+
+
+
+This is an RNA container.
+
+
+
+This after the RNA container.
+
+
+
+
+
+
+
diff --git a/d3.js b/js/d3.js
similarity index 100%
rename from d3.js
rename to js/d3.js
diff --git a/jquery.js b/js/jquery.js
similarity index 100%
rename from jquery.js
rename to js/jquery.js
diff --git a/tests.js b/js/tests.js
similarity index 100%
rename from tests.js
rename to js/tests.js
diff --git a/fornaf.js b/src/fornaf.js
similarity index 82%
rename from fornaf.js
rename to src/fornaf.js
index 90cf981..5d827b5 100644
--- a/fornaf.js
+++ b/src/fornaf.js
@@ -11,7 +11,7 @@ function FornaContainer(element, passedOptions) {
self.options = {
"displayAllLinks": false,
- "labelInterval": 0,
+ "labelInterval": 10,
"applyForce": true,
"initialSize": [200,200],
"allowPanningAndZooming": true
@@ -53,25 +53,13 @@ function FornaContainer(element, passedOptions) {
};
self.displayParameters = {
- "nodeStrokeWidth": 0.8,
- "nodeStrokeWidthDefault": 0.8,
- "nodeLabelFillDefault": d3.rgb(50,50,50),
- "nodeLabelFill": d3.rgb(50,50,50),
- "linkOpacityDefault": 0.8,
- "linkOpacity": 0.8,
- "proteinLinkOpacityDefault": 0.8,
- "proteinLinkOpacity": 0.8,
- "pseudoknotLinkOpacityDefault": 0.8,
- "pseudoknotLinkOpacity": 0.8,
- "labelLinkOpacityDefault": 0.8,
- "labelTextFillDefault": d3.rgb(50,50,50),
- "labelTextFill": d3.rgb(50,50,50),
- "labelNodeFillDefault": 'white',
- "labelNodeFill": 'white',
- "backgroundColorDefault": "white",
- "backgroundColor": "white",
- "proteinBindingHighlighting": true,
- "proteinBindingHighlightingDefault": true
+ "displayBackground": "true",
+ "displayNumbering": "true",
+ "displayNodeOutline": "true",
+ "displayNodeLabel": "true",
+ "displayLinks": "true",
+ "displayPseudoknotLinks": "true",
+ "displayProteinLinks": "true"
};
self.colorScheme = 'structure';
@@ -82,14 +70,15 @@ function FornaContainer(element, passedOptions) {
self.rnas = {};
self.extraLinks = []; //store links between different RNAs
- self.addRNA = function(structure, passedOptions) {
+
+ self.createInitialLayout = function(structure, passedOptions) {
// the default options
var options = {
'sequence': '',
- 'structure': '',
'name': 'empty',
'positions': [],
- 'labelInterval': 10
+ 'labelInterval': 10,
+ 'avoidOthers': true
};
if (arguments.length == 2) {
@@ -99,8 +88,7 @@ function FornaContainer(element, passedOptions) {
}
}
- console.log('structure:', structure);
- rg = new RNAGraph(options.sequence, options.structure, options.name);
+ rg = new RNAGraph(options.sequence, structure, options.name);
rnaJson = rg.recalculateElements()
@@ -111,13 +99,26 @@ function FornaContainer(element, passedOptions) {
rnaJson = rnaJson.elementsToJson()
.addPositions("nucleotide", options.positions)
- .addLabels(options.labelInterval)
+ .addLabels(1, options.labelInterval)
.reinforceStems()
.reinforceLoops()
.connectFakeNodes()
+ return rnaJson;
+ }
+
+ self.addRNA = function(structure, passedOptions) {
+ var rnaJson = self.createInitialLayout(structure, passedOptions);
+
+ if (arguments.length === 1)
+ passedOptions = {}
- self.addRNAJSON(rnaJson);
+ if ('avoidOthers' in passedOptions)
+ self.addRNAJSON(rnaJson, passedOptions.avoidOthers);
+ else
+ self.addRNAJSON(rnaJson, true);
+
+ return rnaJson;
}
self.addRNAJSON = function(rnaGraph, avoidOthers) {
@@ -126,7 +127,7 @@ function FornaContainer(element, passedOptions) {
// Each RNA will have uid to identify it
// when it is modified, it is replaced in the global list of RNAs
//
- var max_x;
+ var max_x, min_x;
if (avoidOthers) {
if (self.graph.nodes.length > 0)
@@ -134,9 +135,11 @@ function FornaContainer(element, passedOptions) {
else
max_x = 0;
+ min_x = d3.min(rnaGraph.nodes.map(function(d) { return d.x; }));
+
rnaGraph.nodes.forEach(function(node) {
- node.x += max_x;
- node.px += max_x;
+ node.x += (max_x - min_x);
+ node.px += (max_x - min_x);
});
}
@@ -151,6 +154,22 @@ function FornaContainer(element, passedOptions) {
self.center_view();
};
+ self.transitionRNA = function(previousRNAJson, newStructure, options) {
+ //transition from an RNA which is already displayed to a new structure
+ var newRNAJson = self.createInitialLayout(newStructure, options);
+ console.log('newRNAJson:', newRNAJson);
+
+ vis_nodes.selectAll('g.gnode').each(function(d) { console.log('d before', d); });
+ var gnodes = vis_nodes.selectAll('g.gnode').data(newRNAJson);
+
+ gnodes.each(function(d) { console.log('d after', d); });
+
+ gnodes.transition().attr('transform', function(d) {
+ console.log('d after', d);
+ return 'translate(' + [d.x, d.y] + ')'}).duration(1000);
+
+ };
+
self.recalculateGraph = function(rnaGraph) {
// Condense all of the individual RNAs into one
// collection of nodes and links
@@ -296,7 +315,7 @@ function FornaContainer(element, passedOptions) {
r.struct_name = rnas[uid].struct_name;
r.nodes = rnas[uid].nodes;
r.links = rnas[uid].links;
- r.rna_length = rnas[uid].rna_length;
+ r.rnaLength = rnas[uid].rnaLength;
r.elements = rnas[uid].elements;
r.nucs_to_nodes = rnas[uid].nucs_to_nodes;
r.pseudoknot_pairs = rnas[uid].pseudoknot_pairs;
@@ -319,12 +338,9 @@ function FornaContainer(element, passedOptions) {
};
function setSize() {
- console.log('element', $(element));
var svgW = $(element).width();
var svgH = $(element).height();
- console.log('svgW', svgW, 'svgH', svgH);
-
self.options.svgW = svgW;
self.options.svgH = svgH;
@@ -346,7 +362,6 @@ function FornaContainer(element, passedOptions) {
svg.attr("width", svgW)
.attr("height", svgH);
- console.log('svgW', svgW, 'svgH', svgH);
self.center_view();
}
@@ -371,15 +386,9 @@ function FornaContainer(element, passedOptions) {
self.changeColorScheme = function(newColorScheme) {
var protein_nodes = vis_nodes.selectAll('[node_type=protein]');
- protein_nodes.style('fill', 'grey')
- .style('fill-opacity', 0.5)
+ protein_nodes.classed("protein", true)
.attr('r', function(d) { return d.radius; });
- /*
- var fake_nodes = vis_nodes.seletAll('[node_type=fake]');
- fake_nodes.style('fill', 'transparent');
- */
-
var gnodes = vis_nodes.selectAll('g.gnode');
var circles = vis_nodes.selectAll('g.gnode').selectAll('circle');
var nodes = vis_nodes.selectAll('g.gnode').select('[node_type=nucleotide]');
@@ -409,7 +418,7 @@ function FornaContainer(element, passedOptions) {
scale = d3.scale.linear()
.range(["#98df8a", "#dbdb8d", "#ff9896"])
.interpolate(d3.interpolateLab)
- .domain([1, 1 + (d.rna.rna_length - 1) / 2, d.rna.rna_length]);
+ .domain([1, 1 + (d.rna.rnaLength - 1) / 2, d.rna.rnaLength]);
return scale(d.num);
});
@@ -424,7 +433,7 @@ function FornaContainer(element, passedOptions) {
nodes.style('fill', function(d) {
if (typeof self.customColors == 'undefined') {
return 'white';
- }
+ }
if (self.customColors.color_values.hasOwnProperty(d.struct_name) &&
self.customColors.color_values[d.struct_name].hasOwnProperty(d.num)) {
@@ -489,9 +498,14 @@ function FornaContainer(element, passedOptions) {
.append("svg:svg")
.attr("width", self.options.svgW)
.attr("height", self.options.svgH)
- .style("display", "block")
.attr("id", 'plotting-area');
+ // set css for svg
+ var style = svg.append('svg:style');
+ $.get("../css/fornac.css", function(content){
+ style.text(content.replace(/[\s\n]/g, ""));
+ });
+
self.options.svg = svg;
var svg_graph = svg.append('svg:g')
@@ -693,10 +707,15 @@ function FornaContainer(element, passedOptions) {
d1.py += d3.event.dy;
});
- self.force.resume();
+ self.resumeForce();
d3.event.sourceEvent.preventDefault();
}
+ self.resumeForce = function() {
+ if (self.animation)
+ self.force.resume();
+ }
+
function dragended(d) {
var toDrag = selectedNodes(d);
@@ -818,7 +837,7 @@ function FornaContainer(element, passedOptions) {
.addPseudoknots()
.addPositions('nucleotide', nucleotide_positions)
.addUids(uids)
- .addLabels(self.options.labelInterval)
+ .addLabels(1, self.options.labelInterval)
.addPositions('label', label_positions)
.reinforceStems()
.reinforceLoops()
@@ -839,7 +858,7 @@ function FornaContainer(element, passedOptions) {
if (d.source.rna == d.target.rna) {
var r = d.source.rna;
- r.add_pseudoknots();
+ r.addPseudoknots();
r.pairtable[d.source.num] = 0;
r.pairtable[d.target.num] = 0;
@@ -989,17 +1008,17 @@ function FornaContainer(element, passedOptions) {
self.setFriction = function(value) {
self.force.friction(value);
- self.force.resume();
+ self.resumeForce();
};
self.setCharge = function(value) {
self.force.charge(value);
- self.force.resume();
+ self.resumeForce();
};
self.setGravity = function(value) {
self.force.gravity(value);
- self.force.resume();
+ self.resumeForce();
};
self.setPseudoknotStrength = function(value) {
@@ -1008,108 +1027,60 @@ function FornaContainer(element, passedOptions) {
};
self.displayBackground = function(value) {
- if (value === true) {
- self.displayParameters.backgroundColor=self.displayParameters.backgroundColorDefault;
- } else {
- self.displayParameters.backgroundColor='transparent';
- }
- rect.attr('fill', self.displayParameters.backgroundColor);
- //vis_nodes.selectAll('[label_type=label]').attr('fill', self.displayParameters["backgroundColor"]);
+ self.displayParameters.displayBackground = value;
+ self.updateStyle();
};
self.displayNumbering = function(value) {
- if (value === true) {
- self.displayParameters.labelTextFill=self.displayParameters.labelTextFillDefault;
- self.displayParameters.labelLinkOpacity=self.displayParameters.labelLinkOpacityDefault;
- self.displayParameters.labelNodeFill = self.displayParameters.labelNodeFillDefault;
- } else {
- self.displayParameters.labelTextFill='transparent';
- self.displayParameters.labelLinkOpacity=0;
- self.displayParameters.labelNodeFill = 'transparent';
- }
-
- self.updateNumbering();
- };
-
- self.updateNumbering = function() {
- vis_nodes.selectAll('[node_type=label]').style('fill', self.displayParameters.labelNodeFill);
- vis_nodes.selectAll('[label_type=label]').style('fill', self.displayParameters.labelTextFill);
- vis_links.selectAll('[link_type=label_link]').style('stroke-opacity', self.displayParameters.labelLinkOpacity);
+ self.displayParameters.displayNumbering = value;
+ self.updateStyle();
};
self.displayNodeOutline = function(value) {
- if (value === true) {
- self.displayParameters.nodeStrokeWidth=self.displayParameters.nodeStrokeWidthDefault;
- } else {
- self.displayParameters.nodeStrokeWidth=0;
- }
- svg.selectAll('circle').style('stroke-width', self.displayParameters.nodeStrokeWidth);
- svg.selectAll('circle').style('stroke', 'gray');
-
+ self.displayParameters.displayNodeOutline = value;
+ self.updateStyle();
};
self.displayNodeLabel = function(value) {
- if (value === true) {
- self.displayParameters.nodeLabelFill=self.displayParameters.nodeLabelFillDefault;
- } else {
- self.displayParameters.nodeLabelFill='transparent';
- }
- vis_nodes.selectAll('[label_type=nucleotide]').attr('fill', self.displayParameters.nodeLabelFill);
+ self.displayParameters.displayNodeLabel = value;
+ self.updateStyle();
};
self.displayLinks = function(value) {
- if (value === true) {
- self.displayParameters.linkOpacity=self.displayParameters.linkOpacityDefault;
- } else {
- self.displayParameters.linkOpacity=0;
- }
-
- svg.selectAll("[link_type=real],[link_type=basepair],[link_type=backbone],[link_type=pseudoknot],[link_type=protein_chain],[link_type=chain_chain]").style('stroke-opacity', self.displayParameters.linkOpacity);
+ self.displayParameters.displayLinks = value;
+ self.updateStyle();
};
self.displayPseudoknotLinks = function(value) {
- if (value === true) {
- self.displayParameters.pseudoknotLinkOpacity=self.displayParameters.pseudoknotLinkOpacityDefault;
- } else {
- self.displayParameters.pseudoknotLinkOpacity=0;
- }
-
- svg.selectAll("[link_type=pseudoknot]").style('stroke-opacity', self.displayParameters.pseudoknotLinkOpacity);
+ self.displayParameters.displayPseudoknotLinks = value;
+ self.updateStyle();
};
self.displayProteinLinks = function(value) {
- if (value === true) {
- self.displayParameters.proteinLinkOpacity=self.displayParameters.proteintLinkOpacityDefault;
- } else {
- self.displayParameters.proteinLinkOpacity=0;
- }
-
- svg.selectAll("[link_type=protein_chain]").style('stroke-opacity', self.displayParameters.proteinLinkOpacity);
+ self.displayParameters.displayProteinLinks = value;
+ self.updateStyle();
+ };
+
+ self.updateStyle = function() {
+ // Background
+ rect.classed("transparent", !self.displayParameters.displayBackground);
+ // Numbering
+ vis_nodes.selectAll('[node_type=label]').classed("transparent", !self.displayParameters.displayNumbering);
+ vis_nodes.selectAll('[label_type=label]').classed("transparent", !self.displayParameters.displayNumbering);
+ vis_links.selectAll('[link_type=label_link]').classed("transparent", !self.displayParameters.displayNumbering);
+ // Node Outline
+ svg.selectAll('circle').classed("hidden_outline", !self.displayParameters.displayNodeOutline);
+ // Node Labels
+ vis_nodes.selectAll('[label_type=nucleotide]').classed("transparent", !self.displayParameters.displayNodeLabel);
+ // Links
+ svg.selectAll("[link_type=real],[link_type=basepair],[link_type=backbone],[link_type=pseudoknot],[link_type=protein_chain],[link_type=chain_chain]").classed("transparent", !self.displayParameters.displayLinks);
+ // Pseudoknot Links
+ svg.selectAll("[link_type=pseudoknot]").classed("transparent", !self.displayParameters.displayPseudoknotLinks);
+ // Protein Links
+ svg.selectAll("[link_type=protein_chain]").classed("transparent", !self.displayParameters.displayProteinLinks);
+ // Fake Links
+ vis_links.selectAll("[link_type=fake]").classed("transparent", !self.options.displayAllLinks);
};
-
- self.displayProteinBindingHighlighting = function(value) {
- if (value == true) {
- self.displayParameters.proteinBindingHighlighting=self.displayParameters.proteinBindingHighlightingDefault;
- } else {
- self.displayParameters.proteinBindingHighlighting=false;
- }
-
- //self.displayNodeOutline(true);
- /*
-
- if (self.displayParameters.proteinBindingHighlighting) {
- var protein_links = svg.selectAll('[link_type=protein_chain]');
- protein_links.each(function(d) {
- var boundNodes = svg.selectAll("circle")
- var onlyThese = boundNodes.filter(function(d1) {
- return d1.node_type == 'nucleotide' && (d1 == d.source || d1 == d.target );
- });
-
- onlyThese.style('stroke-width', 3).style('stroke', 'red')
- })
- }
- */
- }
function nudge(dx, dy) {
node.filter(function(d) { return d.selected; })
@@ -1145,46 +1116,37 @@ function FornaContainer(element, passedOptions) {
link_lines.append("svg:title")
.text(link_key);
- link_lines.attr("class", "link")
- .style("stroke", "#999")
- .style("stroke-opacity", self.displayParameters.linkOpacity)
- .style("stroke-width", function(d) {
- return 2;
- })
- .attr('visibility', function(d) {
- if (d.link_type == 'fake')
- return 'hidden';
- else
- return 'visible';
- })
+ link_lines
+ .classed("link", true)
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; })
.attr("link_type", function(d) { return d.link_type; } )
+ .attr("class", function(d) { return d3.select(this).attr('class') + " " + d.link_type; })
.attr('pointer-events', function(d) { if (d.link_type == 'fake') return 'none'; else return 'all';});
- //all_links.exit().each(function(d) { console.log('link exiting', d); }).remove();
+ all_links.attr('class', '')
+ .classed('link', true)
+ .attr("link_type", function(d) { return d.link_type; } )
+ .attr("class", function(d) { return d3.select(this).attr('class') + " " + d.link_type; })
+
all_links.exit().remove();
/* We don't need to update the positions of the stabilizing links */
- fake_links = vis_links.selectAll("[link_type=fake]");
- if (self.options.displayAllLinks) {
- fake_links.style('stroke-width', 1);
- } else {
- fake_links.style('stroke-width', 0);
- }
- //fake_links.style('stroke', 'blue')
-
+ /*
basepair_links = vis_links.selectAll("[link_type=basepair]");
- basepair_links.style('stroke', 'red');
+ basepair_links.classed("basepair", true);
+
+ fake_links = vis_links.selectAll("[link_type=fake]")
+ fake_links.classed("fake", true);
intermolecule_links = vis_links.selectAll("[link_type=intermolecule]");
- intermolecule_links.style('stroke', 'blue');
+ intermolecule_links.classed("intermolecule", true);
plink = vis_links.selectAll("[link_type=protein_chain],[link_type=chain_chain]");
- plink.style("stroke-dasharray", ("3,3"));
-
+ plink.classed("chain_chain", true);
+ */
if (self.displayFakeLinks)
xlink = all_links;
@@ -1222,33 +1184,6 @@ function FornaContainer(element, passedOptions) {
.ease("elastic")
.attr("r", 6.5);
- node_fill = function(d) {
- node_fills = {};
-
- node_fills.nucleotide = 'white';
- node_fills.label = 'white';
- //node_fills.pseudo = 'transparent';
- //node_fills.pseudo = 'transparent';
- //node_fills.middle = 'transparent';
- //node_fills.middle = 'transparent';
- node_fills.middle = 'white';
- node_fills.protein = 'grey';
-
- return node_fills[d.node_type];
- };
-
- node_stroke = function(d) {
- node_strokes = {};
-
- node_strokes.nucleotide = 'gray';
- node_strokes.label = 'transparent';
- node_strokes.pseudo = 'transparent';
- node_strokes.middle = 'transparent';
- node_strokes.protein = 'gray';
-
- return node_strokes[d.node_type];
- };
-
node_tooltip = function(d) {
node_tooltips = {};
@@ -1261,7 +1196,6 @@ function FornaContainer(element, passedOptions) {
return node_tooltips[d.node_type];
};
-
xlink.on('click', link_click);
var circle_update = gnodes.select('circle');
@@ -1273,8 +1207,6 @@ function FornaContainer(element, passedOptions) {
nucleotide_nodes.append("svg:circle")
.attr('class', "outline_node")
.attr("r", function(d) { return d.radius+1; })
- .style('stroke_width', 1)
- .style('fill', 'red')
var node = gnodes_enter.append("svg:circle")
.attr("class", "node")
@@ -1286,14 +1218,6 @@ function FornaContainer(element, passedOptions) {
}
})
.attr("node_type", function(d) { return d.node_type; })
- .style('stroke-width', function(d) {
- if (d.node_type == 'protein') {
- return 10;
- } else if (d.node_type == 'label') {
- return 0;
- }})
- .style('stroke-width', self.displayParameters.nodeStrokeWidth)
- .style("fill", node_fill)
var labels = gnodes_enter.append("text")
.text(function(d) { return d.name; })
@@ -1301,7 +1225,6 @@ function FornaContainer(element, passedOptions) {
.attr('font-size', 8.0)
.attr('font-weight', 'bold')
.attr('y', 2.5)
- .attr('fill', self.displayParameters.nodeLabelFill)
.attr('class', 'node-label')
.attr("label_type", function(d) { return d.node_type; })
.append("svg:title")
@@ -1359,9 +1282,8 @@ function FornaContainer(element, passedOptions) {
if (self.animation) {
self.force.start();
}
-
- self.updateNumbering();
- self.displayProteinBindingHighlighting(true);
+
+ self.updateStyle();
};
setSize();
diff --git a/rnagraph.js b/src/rnagraph.js
similarity index 99%
rename from rnagraph.js
rename to src/rnagraph.js
index 3bebb1b..65c90cd 100644
--- a/rnagraph.js
+++ b/src/rnagraph.js
@@ -647,8 +647,13 @@ function RNAGraph(seq, dotbracket, struct_name) {
return elements.concat(self.pt_to_elements(pt, level, i, j));
};
- self.addLabels = function(labelInterval) {
- if (arguments.length === 0)
+ self.addLabels = function(startNumber, labelInterval) {
+ if (arguments.length === 0) {
+ startNumber = 1;
+ labelInterval = 10;
+ }
+
+ if (arguments.length === 1)
labelInterval = 10;
if (labelInterval === 0)
@@ -710,7 +715,7 @@ function RNAGraph(seq, dotbracket, struct_name) {
newX = self.nodes[i-1].x + offsetVec[0];
newY = self.nodes[i-1].y + offsetVec[1];
- new_node = {'name': i,
+ new_node = {'name': i + startNumber - 1,
'num': -1,
'radius': 6,
'rna': self,
diff --git a/rnautils.js b/src/rnautils.js
similarity index 100%
rename from rnautils.js
rename to src/rnautils.js
diff --git a/simplernaplot.js b/src/simplernaplot.js
similarity index 100%
rename from simplernaplot.js
rename to src/simplernaplot.js
index 208ffc2..2f88d2e 100644
--- a/simplernaplot.js
+++ b/src/simplernaplot.js
@@ -78,6 +78,7 @@ simple_xy_coordinates = function(pair_table)
loop(k, l, pair_table);
}
}
+
polygon = Math.PI*(count-2)/count; /* bending angle in loop polygon */
remember[++r] = j;
begin = i_old < 0 ? 0 : i_old;
@@ -110,6 +111,5 @@ simple_xy_coordinates = function(pair_table)
alpha += Math.PI-angle[i+1];
}
-
return poss;
}
diff --git a/test.html b/test.html
index 998dbd8..5452075 100644
--- a/test.html
+++ b/test.html
@@ -3,14 +3,13 @@
QUnit Example
-
+
-
-
-
-
+
+
+