UNPKG

bio-vis-expression-bar

Version:

Simple barchart to show expression levels across experiments

258 lines (220 loc) 7.66 kB
var jQuery = require('jquery'); var science = require('science'); var colorbrewer = require('colorbrewer'); var d3 = require('d3'); require('string.prototype.startswith'); require('jquery-ui'); var exts = require('./d3Extensions.js'); var BarPlot = function (parent) { this.parent = parent; this.opt = parent.opt; }; BarPlot.prototype.renderScales = function(i){ var xAxis; var barWidth = this.calculateBarWidth(); if(((100*barWidth)/this.opt.width) < 35){ xAxis = d3.axisBottom(axisScale).ticks(3); } else { xAxis = d3.axisBottom(axisScale).ticks(5); } var axisScale = this.ScaleRangeX(); //Create the Axis xAxis = d3.axisBottom(axisScale).ticks(5); //Create an SVG group Element for the Axis elements and call the xAxis function var xAxisGroup = this.parent.svgFootContainer .append('g').call(xAxis) .attr('class', 'x axis') .attr('font-size', (this.parent.opt.fontSize/1.4)); var blockWidth = (this.parent.opt.width - this.parent.opt.labelWidth) / this.parent.totalRenderedGenes; var gXOffset = (blockWidth * i) + this.parent.opt.labelWidth; xAxisGroup.attr('transform', 'translate(' + gXOffset + ',0)'); }; BarPlot.prototype.renderGlobalScale = function(){ this.parent.svgFootContainer.attr('height', 20); $(`#${this.parent.chartSVGidFoot}`).css('display', 'block'); this._responseToScroll(); return; }; BarPlot.prototype.calculateBarWidth = function(){ var availableWidth = this.opt.width - this.opt.labelWidth; var widthPerBar = (availableWidth / this.parent.totalRenderedGenes ) - 10; // 10 px of border. maybe dynamic? return widthPerBar; }; BarPlot.prototype.rangeX = function(){ var barWidth = this.calculateBarWidth(); // barWidth /= 2; // This is divided to by 2 to allow the lines to be present in the chart var x = d3.scaleLinear().range([0, barWidth]); x.domain([this.parent.data.min,this.parent.maxInData()]); return x; } BarPlot.prototype.ScaleRangeX = function(){ var barWidth = this.calculateBarWidth(); var x = d3.scaleLinear().range([0, barWidth]); x.domain([this.parent.data.min,this.parent.maxInData()]); return x; } BarPlot.prototype.renderGeneBar = function( i){ var parent = this.parent; var data = this.parent.data.renderedData; var dat = data[i]; var barHeight = this.opt.barHeight; var labelWidth = this.opt.labelWidth; var x= this.rangeX(); var sc = parent.opt.sc; var blockWidth = (parent.opt.width - parent.opt.labelWidth) / parent.totalRenderedGenes; var gXOffset = (blockWidth * i) + labelWidth; var self = this; var bar = parent.barGroup.append('g'); bar.attr('transform', 'translate(' + gXOffset + ',' + barHeight + ')'); var gene = ''; for(var j in dat){ var d = dat[j]; var y = (barHeight * d.renderIndex) ; var rect = bar.append('rect') .attr('y', y) .attr('height', barHeight - 2) .attr('fill', 'white') .attr('width', x(0)) .on('mouseenter', function(event, da){ var pos = d3.select(this).position(this); var index = ((pos.top ) / parent.opt.barHeight)-1; var tooltip = parent.opt.renderProperty + ': ' + exts.numberWithCommas(da.value) + '\nsem: ' + exts.numberWithCommas(da.stdev) ; parent.showTooltip(tooltip, this, self.parent.tooltip, self.parent.tooltipBox, false); parent.showHighlightedFactors(da, this); } ) .on('mouseleave', function(){ parent.hideTooltip(); parent.hideHighlightedFactors(); }); rect.data([d]); //Bind the data to the rect bar.append('line').attr('x1', 0) .attr('y1', y + (barHeight/2)) .attr('x2', 0) .attr('y2', y + (barHeight/2) ) .attr('stroke-width', 1 ) .attr('stroke', 'black'); }; }; BarPlot.prototype.refreshBar = function(gene, i){ var data = this.parent.data.renderedData; var dat = data[i]; var x=this.rangeX(); var sc = this.opt.sc; var colorFactor = this.opt.colorFactor; var self = this; var colors = null; var barHeight = this.opt.barHeight; var headerOffset = 0; if(! this.parent.isFactorPresent(colorFactor)){ colorFactor = this.parent.getDefaultColour(); } var getY = function(d,j){ return (barHeight * dat[j].renderIndex); }; if(colorFactor != 'renderGroup'){ colors = this.parent.factorColors[colorFactor]; } //Refresh the bar sizes and move them if they where sorted var bar = this.parent.barGroup.selectAll('g').filter(function (d, j) { return j == i;}); rects = bar.selectAll('rect').transition() .duration(1000) //.ease("cubic-in-out") .attr('width', function(d,j) { var val = dat[j].value; if(isNaN(val)){ val = 0; } return x(val); }) .attr('fill', function(d,j){ //var ret = sc(dat[j].id%20); var ret = "#222222" if(colorFactor != 'renderGroup'){ // console.log(dat[j]); // console.log(dat[j].factors[colorFactor]); ret=colors[dat[j].factors[colorFactor]]; } return ret; }) .attr('y', getY ) .each(function(r,j){ var d = dat[j]; var rect = d3.select(this); rect.data([d]); }); var lines = bar.selectAll('line') .transition() .duration(1000) //.ease("cubic-in-out") // .attr('x1', gXOffset) .attr('y1', function(d,j) {return getY(d,j) + ((barHeight-2)/2.0) }) .attr('y2', function(d,j) {return getY(d,j) + ((barHeight-2)/2.0) } ) .attr('x2', function(d,j) { var ret =x(dat[j].value + dat[j].stdev); if(isNaN(ret)){ ret = 0; } return ret} ) .attr('x1', function(d,j) { var left = dat[j].value - dat[j].stdev; if(isNaN(left)){ left = 0; } if(left < 0){ left = 0 } return x(left); }); }; BarPlot.prototype.refreshScale = function(){ var axisScale = this.parent.x; var xAxis; var barWidth = this.calculateBarWidth(); if(((100*barWidth)/this.opt.width) < 35){ xAxis = d3.axisBottom(axisScale).ticks(3); } else { xAxis = d3.axisBottom(axisScale).ticks(5); } var toUpdate = this.parent .svgFootContainer.selectAll("g.x.axis") toUpdate.transition() .duration(1000) .call(xAxis); } BarPlot.prototype.showHighithRow = function(){ var self = this; if(typeof self.parent.selectionBox !== 'undefined'){ self.parent.selectionBox.attr('visibility', 'visible'); } } BarPlot.prototype.hideHidelightRow = function(){ var self = this; if(typeof self.parent.selectionBox !== 'undefined'){ self.parent.selectionBox .attr('visibility', 'hidden'); self.parent.selectionBoxGene.attr('visibility', 'hidden'); self.parent.selectionBoxTitles.attr('display', 'none'); } } BarPlot.prototype._responseToScroll = function(){ var plotContainer = this.parent.plotContainer; var sortDiv = this.parent.sortDivId; var chartSVGidHead = this.parent.chartSVGidHead; var chartSVGidFoot = this.parent.chartSVGidFoot; var lastScrollLeft = 0; $(`#${plotContainer}`).on("scroll",function(){ // Amount of Scroll horizontally var documentScrollLeft = $(`#${plotContainer}`).scrollLeft(); // Move elements horizontally in response if (lastScrollLeft != documentScrollLeft){ lastScrollLeft = documentScrollLeft; $(`#${chartSVGidHead}`).css('position', 'relative'); $(`#${chartSVGidHead}`).css('left', -lastScrollLeft); $(`#${chartSVGidFoot}`).css('position', 'relative'); $(`#${chartSVGidFoot}`).css('left', -lastScrollLeft); $(`#${sortDiv}`).css('left', -lastScrollLeft); } }); } module.exports.BarPlot = BarPlot;