genome-browser.ts 2.75 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { select, Selection } from "d3-selection"

import GeneComponent, { GeneData } from "./sequence/gene";
import GenomeAxis from "./sequence/genome-axis";
import { drag } from "d3-drag";



export interface GenomeBrowserData {
  width: number,
  genomeWindow: {
    center: number,
    size: number
  },
  eventHandler?: {
    dragstarted: (elem: SVGElement) => void,
    dragged: () => void,
    dragended: (elem: SVGElement) => void
  },
  currentMousePosition: number,
  genes: GeneData[],
  x: number,
  y: number
}


export default function () {
  const genomeAxis = GenomeAxis();
  const geneComponent = GeneComponent();

  function genomeBrowser(
    _selection: Selection<SVGElement, Array<GenomeBrowserData>, HTMLElement, any>,
    width: number,
    height: number
  ) {
    _selection.each(function (_data: Array<GenomeBrowserData>) {
      const container = select(this);
      const genomeBrowser = container
        .selectAll<SVGGElement, GenomeBrowserData>("g.genome-browser")
        .data(_data);

      //ENTER
      const genomeBrowerE = genomeBrowser
        .enter()
        .append<SVGGElement>("g")
        .classed("genome-browser", true);

      genomeBrowerE.append("rect")
        .classed("genome-browser-background", true)
        .style("fill-opacity", 0);


      genomeBrowerE.append("g").classed("axis", true);
      genomeBrowerE.append("g").classed("genes", true);

      //EXIT
      genomeBrowser.exit().remove();

      //UPDATE
      const genomesBrowserU = genomeBrowser.merge(genomeBrowerE);
      genomesBrowserU
        .select<SVGRectElement>("rect.genome-browser-background")
        .attr("width", width)
        .attr("height", height)
        .call(
          drag<SVGRectElement, GenomeBrowserData>()
            .on("start", d => {
              if (d.eventHandler) {
                console.log(this);
                d.eventHandler.dragstarted(this);
              }
            })
            .on("drag", d => {
              if (d.eventHandler) {
                d.eventHandler.dragged();
              }
            })
            .on("end", d => {
              if (d.eventHandler) {
                d.eventHandler.dragended(this);
              }
            })
        );
      genomesBrowserU
        .select<SVGElement>("g.axis")
        .datum(({ genomeWindow: { center, size } }): [number, number] => getGenomeWindow(center, size))
        .call(genomeAxis, width, 0);

      genomesBrowserU
        .select<SVGElement>(".genes")
        .datum(({ genes }) => genes)
        .call(geneComponent, genomeAxis.scale(), 40)


    });
  }
  return genomeBrowser;
}


function getGenomeWindow(center: number, genomeWindowSize: number): [number, number] {
  const halfWindow = genomeWindowSize / 2;
  return [center - halfWindow, center + halfWindow]

}