Thursday 26 November 2020

create svg elements based on coordinates from webpage and sql database

Hej all,

I have a question that is similar to Drawing connective elements between fixed positions on several html elements, but I am looking for a solution that works for svg (I had no time to work on this project since I posted the question until now unfortunately, so I am still a total beginner in web development).

I am trying to visualize the alignment of different DNA sequences in my web application (django is my web framework). Each DNA sequence is displayed as a graph in a <div>. Each graph contains subelements (the yellow boxes) that represent subsequences in the DNA sequence. I create a graph by looping through a dictionary containing the raw values fetched from the database. The dictionary is built like this:

{'1': {'organism': 'sequence 1', 'env_length': 10000, 'frame': '+', 'alns': {'aln_1': {'s_id': 2, 'q_id': 1, 'aln_len': 2700, 'q_start': 1800, 'q_end': 4500, 's_start': 1100, 's_end': 3800}, 'aln_2': {'s_id': 2, 'q_id': 1, 'aln_len': 500, 'q_start': '8000', 'q_end': 8500, 's_start': 7000, 's_end': 7500}}, 'env_genes': {'g1': {'env_name': 'gene_1', 'env_start': 1850, 'env_end': 4700, 'env_strand': '+', 'gene_class': 'normal'}, 'g2': {'env_name': 'gene_2', 'env_start': 8000, 'env_end': 8500, 'env_strand': '+', 'gene_class': 'normal'}}}, '2': {'organism': 'sequence 2', 'env_length': 8500, 'frame': '+', 'alns': {'aln_1': {'s_id': 3, 'q_id': 2, 'aln_len': 2700, 'q_start': 1100, 'q_end': 3800, 's_start': 1, 's_end': 2700, 's_strand': '+'}}, 'env_genes': {'g1': {'env_name': 'gene_1', 'env_start': 1100, 'env_end': 1500, 'env_strand': '+', 'gene_class': 'normal'}, 'g2': {'env_name': 'gene_2', 'env_start': 1600, 'env_end': 1800, 'env_strand': '+', 'gene_class': 'normal'}}}, '3': {'organism': 'sequence 3', 'env_length': 3000, 'frame': '+', 'env_genes': {'g1': {'env_name': 'gene_1', 'env_start': 1, 'env_end': 2700, 'env_strand': '+'}}}}

The elements are created like this in html:

<div class="graph" style='--graph-length: '>
          <hr class="line seq">
          
</div>

and styled using css like this:

.graph { position: relative; }

.env_gene_right {
  position: absolute;
  top: 0;
  width: calc((var(--stop) - var(--start)) / var(--graph-length)*100% - 18px);
  left: calc(var(--start) / var(--graph-length)*100%);
  height: 2em;
  background-color: cornflowerblue;
  display: block;
  border-radius: 3px;
  border: 1px solid cornflowerblue;
}

.env_gene_right:after {
  content: " ";
  position: absolute;
  right: -15px;
  top: 0px;
  border-top: 15px solid transparent;
  border-right: none;
  border-left: 15px solid cornflowerblue;
  border-bottom: 15px solid transparent;
}

.env_gene_left {
  position: absolute;
  top: 0;
  width: calc((var(--stop) - var(--start)) / var(--graph-length)*100% - 18px);
  left: calc(var(--start) / var(--graph-length) * 100%);
  height: 2em;
  background-color: cornflowerblue;
  display: block;
  border-radius: 3px;
  border: 1px solid cornflowerblue;
}

.env_gene_left:before {
  content: " ";
  position: absolute;
  left: -15px;
  top: 0px;
  border-top: 15px solid transparent;
  border-right: 15px solid cornflowerblue;
  border-left: none;
  border-bottom: 15px solid transparent;
}
.line {
  position: absolute;
  left: 0;
  right: 0;
  height: 0px;
}

Each of those graphs may represent sequences of different actual length, but the length of the graph displayed in the browser is the same. As these sequences may be similar, I want to visualize where the sequences are similar through svg elements (blue) that connects two graphs, like this:

enter image description here

My problem is: How do I best create the connecting svg figures (blue)? I was thinking to use an <svg polygon\>, but then I do not really know how to get the actual coordinates for the polygon relative to where the graph is placed on the website (e.g the first blue element: if my start value for the block is 1800 and the end is 4500 (these values are saved in my sqlite3 database), how do I calculate the coordinates where the polygon should be drawn on the website?). I have tried to use some javascript, e.g document.getElementsByClassName to get the start and end positions of the graph (in px) in the browser window, then recalculated how many pixels correspond to one basepair (the length unit for dna sequences) and tried to get the positions from that, but the svg did not show at all.

Another idea would be to create all divs within an svg element, and then create svg polygons inside this larger svg. But in that case, how do I get the positions of the graphs in the svg? Could I use Javascripts query selector?

So finally: what is the best way to do this using svg, html and javascript/jquery? E.g a tutorial covering similar things would also help. The reason I want to do this using svg is that the user should be able to interact with each specific element (such as performing click or on hover actions on the yellow boxes, blue polygons etc). If that is possible using another javascript library I am absolutely open to that.

Every hint is apprechiated!

EDIT: The svgs have to be able to overlap one another!



from create svg elements based on coordinates from webpage and sql database

No comments:

Post a Comment