Commit df83037c authored by Raphael Müller's avatar Raphael Müller
Browse files

Merge branch 'feature2' into 'development'

Feature2

See merge request !3
parents 47f89e3d 0fb77945
......@@ -5,7 +5,7 @@ var app = new Vue({
id: "my-genome",
start: 1706479,
end: 1718084,
tooltip: null
tooltip: "name: {name}</br>description: {description}</br>start: {start}</br>end: {end}"
},
feature_data: [
{ name: "Gene 1",
......@@ -95,7 +95,6 @@ var app = new Vue({
end: 1716321,
strand: '+',
type: "gene",
color: '#454aff',
color_border: '#000000'
},
{ name: "Gene 11",
......@@ -103,9 +102,7 @@ var app = new Vue({
start: 1717235,
end: 1718084,
strand: '-',
type: "gene",
color: '#454aff',
color_border: '#000000'
type: "rRNA"
}
]
}
......
Vue.component("axis",{
template:
/***********************************
* TODO:
* add logic to print human readable tick sizes, i.e.
* 10 kb instead of 10,000 bp
*/
Vue.component( "axis", {
template:
`
<div class="gv-axis" @click="my_method()">
TODO: im the axis component
</div>
<svg :x="x" :y="y" :width="width" :height="height" ><!--:viewBox="xOffset +' '+ vOffset +' '+ width + xOffset +' '+ vOffset + height"><!-- -->
<line x1="0" :y1="2*vOffset" :x2="width" :y2="2*vOffset" style="stroke:rgb(0,0,0);stroke-width:1" />
<line x1="0" :y1="2*vOffset" x2="0" :y2="vOffset" stroke="black" />
<line :x1="width" :y1="2*vOffset" :x2="width" :y2="vOffset" stroke="black" />
<line v-for="tick in ticks" :x1="tick.panelPos" :y1="2*vOffset" :x2="tick.panelPos" :y2="vOffset+2" stroke="black"/>
<text v-for="tick in ticks" :style="'font: '+vOffset+'px roboto;'"class="small" :x="tick.panelPos" :y="vOffset" text-anchor="middle" fill="black">{{ tick.genomePos }}</text>
</svg>
<!-- -->
`,
props: {
todoprop1: {
validator (value) {
return true
}
},
todoprop2: {
validator (value) {
return true
}
}
x: Number,
y: Number,
start: Number,
stop: Number,
genomeSize: Number,
width: Number,
height: Number,
xOffset: Number,
vOffset: Number,
},
methods: {
my_method(){
console.log(this.todo)
console.log(this.Todo)
},
genomeToPixel( pos ) {
return (this.width*(pos-this.start))/(this.length)
}
},
computed: {
Todo(){
return this.todo.charAt(0).toUpperCase() + this.todo.substr(1);
computed:{
power(){
return Math.floor(Math.log10(this.length))
},
length(){
return (this.stop - this.start)
},
genomeSectionSize(){
return (this.start > this.stop) ? (this.genomeSize-this.start + this.end) : Math.abs(this.stop-this.start) // genome section in bp
},
tickSize(){
return Math.pow(10, this.power-1)
//return Math.pow( 10, Math.round( Math.log10( this.genomeSectionSize / this.noTicks ) ) ) // axis tick size in log 10 bp
},
noTicks(){
return Math.floor(this.length/this.tickSize)+2
},
ticks(){
const firstTickPos = Math.round(this.start/this.tickSize)*this.tickSize//Math.pow( 10, Math.floor( Math.log10( this.start ) ) )
let ticks = new Array(this.noTicks)
for(i=0; i<ticks.length; i+=1){
ticks[i] = {}
ticks[i].genomePos = firstTickPos + i*this.tickSize
ticks[i].panelPos = this.genomeToPixel(ticks[i].genomePos)
}
return ticks
},
},
data: function(){
return {
todo: "todo"
//noTicks: 10
//ticks: []
}
},
})
}
} )
Vue.component("feature",{
template:
`
<div class="gv-feature" @click="my_method()">
TODO: im the feature component
</div>
<svg :height="svgHeight" :width="svgWidth" :x="svgX" :y="svgY">
<polygon :points="arrow_coordinates" :style=featureStyle @click="clickEvent" @mouseover="hoverEvent" />
</svg>
`,
props: {
todoprop1: {
validator (value) {
return true
props: ['svgWidth', 'svgHeight', 'svgX', 'svgY', 'color', 'borderColor', 'featureId'],
computed: {
featureStyle () {
return {
'fill': this.color,
'stroke': this.borderColor,
'stroke-width': 1
}
},
todoprop2: {
validator (value) {
return true
}
}
},
methods: {
my_method(){
console.log(this.todo)
console.log(this.Todo)
arrow_coordinates () {
let points = [
'0, ' + this.svgHeight * 0.25,
'0, ' + this.svgHeight * 0.75,
this.svgWidth * 0.7 + ', ' + this.svgHeight * 0.75,
this.svgWidth * 0.7 + ', ' + this.svgHeight * 0.95,
this.svgWidth + ', ' + this.svgHeight * 0.5,
this.svgWidth * 0.7 + ', ' + this.svgHeight * 0.05,
this.svgWidth * 0.7 + ', ' + this.svgHeight * 0.25
]
return points.join(' ')
},
},
computed: {
Todo(){
return this.todo.charAt(0).toUpperCase() + this.todo.substr(1);
methods: {
clickEvent (evt) {
this.$emit('click', this.featureId)
},
hoverEvent (evt) {
this.$emit('hover', this.featureId)
}
},
data: function(){
return {
todo: "todo"
}
},
}
})
Vue.component("genome-viewer",{
template: `
<div>
<div class="container-lin-dna">
<!--<div class="container-lin-dna">
<div :id="genomeStats.id" class="lin-dna" :data-cluster-start="genomeStats.start" :data-cluster-end="genomeStats.end" style="width: 100%; height: 50px;">
<div v-for="feature in featureData" :key="feature.name" class="region-to-display" :data-region-name="feature.name" :data-region-description="feature.description" :data-region-start="feature.start" :data-region-end="feature.end" :data-region-strand="feature.strand" :data-region-type="feature.type">
</div>
</div>
</div>
<!-- new stuff -->
<!-- TODO: axis -->
<axis>
</axis>
<!-- TODO: lanes -->
<lane v-for="lane in lanes" :key="lane.id">
</lane>
<!-- TODO: features -->
<feature v-for="feature in featureData" :key="feature.name">
</feature>
-->
<svg id="genome-vuer" ref="genomeVuer" height='100%' width='100%'>
<!-- -->
<axis :x="to_w(0)" :y="to_h(0)" :xOffset="10" :vOffset="10" :height="one_height" :width="width" :start="axisStart" :stop="axisStop" :genomeSize="length*100">
</axis>
<!-- -->
<lane v-for="lane in lanes" :key="lane.id" :x="to_w(0)" :y="to_h(lane)" :height="2*one_height" :width="to_w(100)">
</lane>
<feature v-for="(feature, index) in featureData" :key="feature.name" :feature-id="feature.name" :svg-width="genomeToPixel(feature.end)-genomeToPixel(feature.start)" :svg-height="one_height" :svg-x="genomeToPixel(feature.start)" :svg-y="to_h(lane(feature.strand))+ one_height/2" :color="getColor(feature)" :border-color="(feature.color_border)?feature.color_border : defaultBorderColor" @click="featureClick">
</feature>
<!-- -->
</svg>
</div>`,
props: {
genomeStats: {
......@@ -41,11 +42,144 @@ Vue.component("genome-viewer",{
return true
}
}
}
},
defaultColor: {
default: "#000000"
},
defaultBorderColor: {
default: "#000000"
},
colorMap: {
default: function(){
return {
'region':'#bdbdbd', // greyLighten
'gene':'#757575', // greyDarken
'cds': '#000000', // black
'rRNA': '#795548', // brown
'tRNA': '#4caf50', // green
'ncRNA': '#ff9800' // orange
}
}
},
},
computed:{
stops(){
return this.featureData.map(f => f.end)
},
starts(){
return this.featureData.map(f => f.start)
},
genomeStart(){
return Math.min(...this.starts)
},
genomeStop(){
return Math.max(...this.stops)
},
axisStart(){
return this.genomeStart - this.tickSize
},
axisStop(){
return this.genomeStop + this.tickSize
},
genome_size(){},
length(){
if(this.genomeStats.start < this.genomeStats.end){
return this.genomeStop - this.genomeStart
}else{
// TODO: if genome is circular
}
},
one_height(){
return this.height/(1 + 2 * this.lanes.length)
},
tickSize(){
return Math.pow(10,Math.floor(Math.log10(this.length))-1)
},
},
mounted() {
var svg_el = this.$refs.genomeVuer.getBoundingClientRect()
this.width = svg_el.width
this.height = svg_el.height
//this.height / length([axis and lanes * 2])
// lanes are twize as big as the axis
// so height / (1 + no_of_lanes * 2)
//var one_height = this.svg_size[1]/(1 + 2 * this.lanes.length)
//let svg_el = this.$refs.genomeVuer.getBoundingClientRect()
//console.log(svg_el)
////console.log(svg_el)
//this.width = svg_el.width
//this.height = svg_el.height
////return [svg_el.clientWidth, svg_el.clientHeight]
//this.one_height = this.height/(1 + 2 * this.lanes.length)
},
methods:{
getColor(feature){
if(feature.hasOwnProperty("color")){
return feature.color
}else{
if(feature.hasOwnProperty("type")){
if(this.colorMap.hasOwnProperty(feature.type)){
return this.colorMap[feature.type]
}else{
return this.defaultColor
}
}else {
return this.defaultColor
}
}
},
lane(str){
return (str=="+")? 1 : -1
},
to_h(param){
//param is a value between -n and +n, where n is the number of lanes divided by 2
//if param is 0 => axis
//if param < 0 => lane on top
//if param > 0 => lane on bottom
let zero = this.lanes.length * this.one_height
if(param < 0){
return zero + 2 * this.one_height * (param)
}else if(param > 0){
return zero + this.one_height * (param)
}
return zero
},
to_w(param){
//param is a value between 0 and 100, where 100 is the full length of the svg
return (this.width*param)/100
},
genomeToPixel(pos){
return (this.width*(pos - (this.axisStart)))/(this.length+2*this.tickSize)
},
featureClick (featureId) {
console.log(featureId)
},
fill_in_tooltip_template (feature, template) {
let tooltip = template
//TODO: Iterate over custom properties
for ( let property of ['name', 'description', 'start', 'end', 'strand', 'type'] ){
tooltip = tooltip.replace( "{" + property + "}", feature[property] )
}
return( tooltip )
},
get_tooltip (e){
let element = e.currentTarget
let id = element.getAttribute( "name" )
let feature = null
for(let entry of this.featureData){
if(entry.name === id){
feature = entry
}
}
console.log( this.fill_in_tooltip_template( feature, this.genomeStats.tooltip ) )
},
},
data: function(){
return {
lanes: [-1, 1]
lanes: [-1, 1],
width: 0,
height: 0
}
},
})
Vue.component("lane",{
template:
`
<div class="gv-lane" @click="my_method()">
TODO: im the lane component
</div>
<svg :height="height" :x="x" :y="y">
<line :x1="x+10" :y1="height/2" :x2="width" :y2="height/2" stroke="#39FF14" stroke-width="2" stroke-dasharray="20, 5" />
</svg>
`,
props: {
todoprop1: {
x: {
validator (value) {
return true
}
},
todoprop2: {
y: {
validator (value) {
return true
}
}
},
height: {
validator (value) {
return true
}
},
width: {
validator (value) {
return true
}
},
},
methods: {
my_method(){
......@@ -24,9 +34,18 @@ Vue.component("lane",{
},
},
computed: {
Todo(){
return this.todo.charAt(0).toUpperCase() + this.todo.substr(1);
},
// y() {
// return y;
// },
// x() {
// return lib.map(0, this.o.xMin, this.o.xMax, 0, this.svg.w);
// },
// tickXs() {
// const ticks = lib.range(this.o.xMin, this.o.xMax, 10)
// return ticks.map(tick =>
// lib.map(tick, this.o.xMin, this.o.xMax, 0, this.svg.w)
// );
// },
},
data: function(){
return {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment