$.fn.violinChart = function(data, geneData, settings) { if (typeof settings.dimension == 'undefined') settings.dimension = {w: 820, h: 450}; if (typeof settings.padding == 'undefined') settings.padding = {t: 0, r: 60, b: 120, l: 40}; width = settings.dimension.w - settings.padding.l - settings.padding.r; height = settings.dimension.h - settings.padding.t - settings.padding.b; //var geneData = [{conc:3.75, func:'Hormone',col:'red'},{conc:2.1, func:'Hormone',col:'blue'}]; // append the svg object to the body of the page var svg = d3.select($(this).get(0)) .append("svg") .attr("width", settings.dimension.w) .attr("height", settings.dimension.h) .append("g") .attr("transform", "translate(" + settings.padding.l + "," + settings.padding.t + ")"); var colors = []; data.forEach(function(e) { colors[e.label] = e.color; }) var yLabels = ['','pg/L','','','ng/L','','','ug/L','','','mg/L','','','g/L']; var y = d3.scaleLog() .domain([0.1,Math.pow(10,15)]) .range([height, 0]) svg.append("g"). call( d3.axisLeft(y) .ticks(16) .tickFormat(function(d,i){ return yLabels[i] }) ) var x = d3.scaleBand() .range([ 0, width ]) .domain(data.map(function(d) { return d.label})) .padding(0.05) svg.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)) .selectAll("text") .attr("x", -10) .attr("y", 4) .attr("transform", "rotate(-55)") .style("text-anchor", "end") var histogram = d3.histogram() .domain(y.domain()) .thresholds(y.ticks(7)) .value(d => d) var sumstat = d3.nest() .key(function(d) { return d.label;}) .rollup(function(d) { input = d.map(function(g) {return g.value;}) bins = histogram(input) return(bins) }) .entries(data) var maxNum = 0 for ( i in sumstat ){ allBins = sumstat[i].value lengths = allBins.map(function(a){return a.length;}) longuest = d3.max(lengths) if (longuest > maxNum) { maxNum = longuest } } var xNum = d3.scaleLinear() .range([0, x.bandwidth()]) .domain([-maxNum,maxNum]) svg .selectAll("violin") .data(sumstat) .enter() .append("g") .attr("transform", function(d){return("translate(" + x(d.key) +" ,0)") } ) .append("path") .style("fill",function(d) {return (colors[d.key])}) .datum(function(d){return(d.value)}) .attr("class","violin_title") .attr("d", d3.area() .x0(function(d){ return(xNum(-d.length)) } ) .x1(function(d){ return(xNum(d.length)) } ) .y(function(d){ return(y(d.x0)) } ) .curve(d3.curveCatmullRom) ) if (geneData ) { var x_diff=0; geneData.forEach(function(val,i) { if (geneData.length == 2) { x_diff = -2+4*(1-i); } else { x_diff = -3+3*(1-i); } svg.append("rect") .attr("y", y(val.conc)-4) .attr("x", x(val.func)+x.bandwidth()/2-4 + x_diff) .attr("width",8) .attr("height",8) .attr("fill",val.col) .attr("stroke","black") .attr("title", val.tooltip) }); } }; $.fn.violinOlink = function(data, settings) { if (typeof settings.dimension == 'undefined') settings.dimension = {w: 820, h: 450}; if (typeof settings.padding == 'undefined') settings.padding = {t: 130, r: 60, b: 120, l: 40}; //if (typeof settings.legend == 'undefined') settings.padding = {t: 130, r: 60, b: 120, l: 40}; var color = ['lightblue', 'pink']; var width = settings.dimension.w - settings.padding.l - settings.padding.r; var height = settings.dimension.h - settings.padding.t - settings.padding.b; // append the svg object to the body of the page var svg = d3.select($(this).get(0)) .append("svg") .attr("width", settings.dimension.w) .attr("height", settings.dimension.h) .append("g") .attr("transform", "translate(" + settings.padding.l + "," + settings.padding.t + ")"); var y = d3.scaleLinear() .domain([d3.min(data,function(d) {return Math.floor(parseFloat(d.value)-0.3)}),d3.max(data,function(d) {return Math.ceil(parseFloat(d.value)+0.3)})]) .range([height, 0]) svg.append("g"). call(d3.axisLeft(y)); var x = d3.scaleBand() .range([ 0, width ]) .domain(data.map(function(d) { return d.visit})) .padding(0.05); svg.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)); var histogram = d3.histogram() .domain(y.domain()) .thresholds(y.ticks(20)) .value(d => d); var median = d3.nest() .key(function(d) { { return d.sex;}}) .key(function(d) { { return d.visit;}}) .rollup(function(d) { input = d.map(function(g) {return g.value;}) med = d3.median(input) return(med) }) .entries(data); var sumstat = d3.nest() .key(function(d) { { return d.sex;}}) .key(function(d) { { return d.visit;}}) .rollup(function(d) { input = d.map(function(g) {return g.value;}) bins = histogram(input) return(bins) }) .entries(data) var maxNum = 40 var xNum = d3.scaleLinear() .range([0, x.bandwidth()]) .domain([-maxNum,maxNum]) for (i in sumstat) { var factor = (i == 0)? -1 : 1; svg .selectAll("myViolin") .data(sumstat[i].values) .enter() .append("g") .attr("transform", function(d){return("translate(" + x(d.key) +" ,0)") } ) .append("path") //.style("fill",function(d) {return (colors[d.key])}) .datum(function(d){return d.value}) //.attr("class","violin_title") //.style("stroke", "none") .style("fill", color[i]) .attr("d", d3.area() .x0(function(d){ return(xNum(0)) } ) .x1(function(d){ return(xNum(factor*d.length)) } ) .y(function(d){ return(y(d.x0)) } ) .curve(d3.curveCatmullRom) ); svg .selectAll("myViolin") .data(median[i].values) .enter() .append("g") .attr("transform", function(d){return("translate(" + x(d.key) +" ,0)") } ) .append("line") .style("stroke","black") .attr("stroke-width",2) .attr("x1",xNum(0)) .attr("x2",xNum(factor*4)) .attr("y1",function(d) {return y(d.value)}) .attr("y2",function(d) {return y(d.value)}); // y-label text svg.append("text") .attr("transform", "rotate(-90)") .attr("y", -30) .attr("x",0 - (height / 2)) .style("text-anchor", "middle") .text("Scaled NPX"); // x-label text svg.append("text") //.attr("transform", "rotate(-90)") .attr("y", height+30) .attr("x", width / 2) .style("text-anchor", "middle") .text("Visit"); } // Legend if (settings.legend !== '') { var legend = svg.selectAll(".legend") .data(d3.map(data, function(d){return d.sex;}).values()) .enter().append("g") .attr("class", "legend") .attr("transform", function(d, i) { return "translate(0," + i * (settings.legend.w+2) + ")"; }); legend.append("rect") .attr("x", settings.legend.x) .attr("y", settings.legend.y) .attr("width", settings.legend.w) .attr("height", settings.legend.w) .style("fill", function(d, i) {return color[i]; }); legend.append("text") .attr("x", settings.legend.x+settings.legend.w+2) .attr("y", settings.legend.y+settings.legend.w/2) .attr("dy", ".35em") .style("text-anchor", settings.legend.txtAnchor) .text(function(d) { return d.sex=='m'?'Male':'Female'; }) } }; $.fn.lineChartBlood = function(data, geneData, referenceData, settings) { if (typeof settings.dimension == 'undefined') settings.dimension = {w: 820, h: 400}; if (typeof settings.padding == 'undefined') settings.padding = {t: 20, r: 60, b: 30, l: 40}; width = settings.dimension.w - settings.padding.l - settings.padding.r; height = settings.dimension.h - settings.padding.t - settings.padding.b; // append the svg object to the body of the page var svg = d3.select($(this).get(0)) .append("svg") .attr("width", settings.dimension.w) .attr("height", settings.dimension.h) .append("g") .attr("transform", "translate(" + settings.padding.l + "," + settings.padding.t + ")"); var x = d3.scaleLinear() .domain(d3.extent(data, function(d) { return d.label; })) .range([ 0, width ]); svg.append("g") .attr("transform", "translate(0," + height + ")") .call( d3.axisBottom(x) ) var yLabels = ['','pg/L','','','ng/L','','','ug/L','','','mg/L','','','g/L']; var y = d3.scaleLog() .domain([0.1,Math.pow(10,15)]) .range([height, 0]) svg.append("g") .attr("transform", "translate(-2,0)") .call( d3.axisLeft(y) .ticks(15) .tickFormat(function(d,i){ return yLabels[i] }) ) svg.append("path") .datum(data) .attr("fill", "none") .attr("stroke", "steelblue") .attr("stroke-width", 1.5) .attr("d", d3.line() .x(function(d) { return x(d.label) }) .y(function(d) { return y(d.value)+1.5 }) .curve(d3.curveBundle.beta(1)) ) if (referenceData) { svg.append("g") .attr("class","reference_genes") .attr("transform", "translate(" + width +",0)") .call( d3.axisRight(y) .tickValues(referenceData.map(function(d) {return d.conc})) .tickFormat(function(d,i) { return referenceData[i].gene_name}) ) } if (geneData ) { var x_diff=0; geneData.forEach(function(val,i) { if (geneData.length == 2) { x_diff = -2+4*(1-i); } else { x_diff = -3+3*(1-i); } svg.append("rect") .attr("y", y(val.conc)-4) .attr("x", x(val.label)-2 + x_diff) .attr("width",8) .attr("height",8) .attr("fill",val.col) .attr("stroke","black") .attr("title", val.tooltip) }) } }; $.fn.barChartConc = function(data, inSettings) { var plot = {}; var extraDefaults = { yLabels: '', yTickFormat: '', minY: 0, dimension: {w: 850, h: 300}, padding: {t: 20, r: 20, b: 85, l: 50}, bgColor: '', barWidth: 11, xLabelsHide: false, extendedTooltip: false, xLabels:'', use_link: true, }; var settings = addDefaultPlotSettings(inSettings, extraDefaults); plot.settings = settings; // Inner dimension var width = plot.width = settings.dimension.w - settings.padding.l - settings.padding.r; // inner width var height = plot.height = settings.dimension.h - settings.padding.t - settings.padding.b; // inner height /* var xScale = d3.scaleBand() .domain(d3.extent(data, function(d) { return d.label; })) .range([ 0, width ]); */ var xScale = plot.x = d3.scaleBand() .range([1, width]) .domain(data.map(function(d) {return d.label; })) var xAxis = d3.axisBottom(xScale) .tickValues(settings.xLabels) if (settings.xLabelsHide) { xAxis .tickFormat('') .tickSize(0) } var yScale; var yMin, yMax, yAxis; if (settings.yLabels) { yScale = plot.y = d3.scaleLog() .range([height, 0]) .domain(settings.yDomain) yAxis = d3.axisLeft(yScale) .tickFormat(function(i,d) { return settings.yLabels[d]; }) } else { yMin = plot.yMin = 0; yMax = plot.yMax = Math.max(d3.max(data, function(d) { return parseFloat(d.value); }), settings.minY); yScale = plot.y = d3.scaleLinear() .range([height, 0]) .domain(yDomain) .nice(5); yAxis = d3.axisLeft(yScale) .ticks(5); if (settings.yTickFormat) { yAxis.tickFormat(d3.format(settings.yTickFormat)) } } var vis = plot.vis = d3.select($(this).get(0)) .append("svg") .attr("class", "barchart") .attr("width", width + settings.padding.l + settings.padding.r) .attr("height", height + settings.padding.t + settings.padding.b) .append("g") .attr("transform", "translate(" + settings.padding.l + "," + settings.padding.t + ")") .attr("width", width) .attr("height", height); $(this).on('click', '[url]', function() { document.location.href = $(this).attr('url'); }); if (settings.bgColor) { vis.append("rect") .attr("class", "chart_field") .attr("width", width) .attr("height", height+4) .attr("transform", "translate(0,-4)") .style("fill", settings.bgColor); } var bar_g = vis.selectAll(".bar_g") .data(data) .enter() .append("g") .attr("class", "bar_g") .attr("transform", function(d) { return 'translate('+xScale(d.label)+', 0)'; }) .attr("title", function(d) { return d.tooltip; }); var link = bar_g.append("a") .each(function(d) { if (d.url && settings.use_link) d3.select(this).attr("xlink:href", d.url); }); if (settings.extendedTooltip) { var bar_transp = link.append("rect") .attr("class","bartrans") .attr("y", 0) .attr("x", function(d) { return xScale.bandwidth()/2 - settings.barWidth/2 ; }) .attr("width", settings.barWidth) .attr("height", height) .style("fill", "transparent"); } var bar_rect = link.append("rect") .attr("class", "bar") .attr("y", function(d) { return (d.na == 1)?0:yScale(d.value); }) .attr("x", function(d) { return xScale.bandwidth()/2 - settings.barWidth/2 ; }) .attr("width", settings.barWidth) .attr("height", function(d) { return (d.na == 1)?height:(height-yScale(d.value));}) .style("fill", function(d){ if (d.na==1) { return "#FAFAFA"; } else if (typeof d.color_group!='undefined') { return colorbrewer[d.color_group[0]][d.color_group[1]][d.color_group[2]]; } else { return d.color; } }); var bar_text = bar_g.filter(function(d){ return d.na == 1; }) .append("text") .attr("class", "na_text") .style("text-anchor", "middle") .attr("transform", "rotate(-90)") .attr("y", settings.barWidth/2+6) .attr("x", -height/2) .text("N/A"); if (settings.valueLabels) { link.append("text") .attr("class", "valueLabel") .style("text-anchor", "middle") .attr("x", function(d, i) { return xScale.bandwidth()/2; }) .attr("y", function(d) { return (d.na == 1)?0:yScale(d.value)-2; }) .text(function(d) { return (d.na == 1)?'':d.value; }); } vis.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll(".tick text") .attr("class", "barchartlabel") .attr("y", 10) .attr("x", 0) //.attr("transform", "rotate(-55)") .style("text-anchor", "middle") .each(function(d, i) { if (data[i].tooltip) { d3.select(this).attr('title', data[i].tooltip) } if (data[i].url) { d3.select(this).attr('url', data[i].url).style('cursor', 'pointer'); } }); // x axis label vis.selectAll(".x.axis") .append("text") .attr("y", 20) .attr("x", width/2) .text(settings.xAxisLabel); // y axis label vis.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("y", -8) .style("text-anchor", "middle") .text(settings.yAxisLabel); // Legend if (settings.legend !== '') { var legend = vis.selectAll(".legend") .data(d3.map(data, function(d){return d.legend;}).values()) .enter().append("g") .attr("class", "legend") .attr("transform", function(d, i) { return "translate(0," + i * (settings.legend.w+2) + ")"; }); legend.append("rect") .attr("x", settings.legend.x) .attr("y", settings.legend.y) .attr("width", settings.legend.w) .attr("height", settings.legend.w) .style("fill", function(d, i) {return d.color; }); legend.append("text") .attr("x", settings.legend.x+settings.legend.w+2) .attr("y", settings.legend.y+settings.legend.w/2) .attr("dy", ".35em") .style("text-anchor", settings.legend.txtAnchor) .text(function(d) { return d.legend; }) } return plot; }; $.fn.lineChartOlink = function(data, inSettings) { var plot = {}; var extraDefaults = { yLabels: '', yTickFormat: '', minY: 0, dimension: {w: 820, h: 450}, padding: {t: 0, r: 60, b: 120, l: 40}, bgColor: '', barWidth: 11, xLabelsHide: false, extendedTooltip: false }; var settings = addDefaultPlotSettings(inSettings, extraDefaults); plot.settings = settings; // Inner dimension var width = plot.width = settings.dimension.w - settings.padding.l - settings.padding.r; // inner width var height = plot.height = settings.dimension.h - settings.padding.t - settings.padding.b; // inner height var svg = plot.vis = d3.select($(this).get(0)) .append("svg") .attr("width", settings.dimension.w) .attr("height", settings.dimension.h) .append("g") .attr("transform", "translate(" + settings.padding.l + "," + settings.padding.t + ")"); var sumstat = d3.nest() .key(function(d) { return d.label;}) .entries(data); var median_line= d3.nest() .key(function(d) { return d.visit;}).sortKeys(d3.ascending) .rollup(function(v) { return d3.median(v, function(d) {return d.value;})}) .entries(data); var x = d3.scaleLinear() .domain(d3.extent(data, function(d) { return d.visit; })) .range([ 0, width ]); svg.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x).ticks(2)); if (!settings.yRange) { settings.yRange = {}; settings.yRange.max = d3.max(data, function(d) { return parseFloat(d.value); }); settings.yRange.min = d3.min(data, function(d) { return parseFloat(d.value); }); } // Add Y axis var y = d3.scaleLinear() .domain([settings.yRange.min,settings.yRange.max]) .range([ height, 0 ]); if (settings.yAxisShow) { svg.append("g") .call(d3.axisLeft(y)); } // color palette var res = sumstat.map(function(d){ return d.key }) // Draw the line svg.selectAll(".line") .data(sumstat) .enter() .append("path") .attr("class","pea_line") .attr("fill", "none") .attr("stroke", settings.color) .attr("stroke-width", 1) .attr("d", function(d){ return d3.line() .x(function(d) { return x(d.visit); }) .y(function(d) { return y(d.value); }) (d.values) }) svg .datum(median_line) .append("path") .attr("fill", "none") .attr("stroke", "black") .attr("stroke-width", 3) .attr("d", d3.line() .x(function(d) { return x(d.key); }) .y(function(d) { return y(d.value); }) ) return plot; } function lollipopChart(data, id, settings) { var defaultColorScale = ['#CCCCFF', '#0000FF']; if (typeof settings === 'undefined') settings = {}; if (typeof settings.colorscale === 'undefined') settings.colorscale = defaultColorScale; if (typeof settings.width === 'undefined') settings.width = 600; if (typeof settings.barheight === 'undefined') settings.barheight = 20; if (typeof settings.bgcolor === 'undefined') settings.bgcolor = '#FFFFFF'; if (typeof settings.maxvalue === 'undefined') settings.maxvalue = 40; if (typeof settings.xAxisLabel === 'undefined') settings.xAxisLabel = ''; if (typeof settings.padding === 'undefined') { settings.padding = { top: 30, bottom: 0, left: 200, right: 40 }; } if (typeof settings.xLabelTransform === 'undefined') settings.xLabelTransform = ''; if (typeof settings.valueLabels === 'undefined') settings.valueLabels = false; if (typeof settings.grid === 'undefined') settings.grid = false; if (typeof settings.showRows === 'undefined') settings.showRows = false; var barHeight = settings.barheight; var chartHeight = settings.barheight * data.length; var height = chartHeight + settings.padding.top + settings.padding.bottom; var chartWidth = settings.width - settings.padding.left - settings.padding.right; var svg = d3.select(id) .attr('tabindex', 1) .append('svg') .attr('class', 'chart cluster') .attr('width', settings.width) .attr('height', height); if (settings.bgcolor !== '#FFFFFF') { svg.append('rect') .attr('class', 'background') .attr('width', settings.width) .attr('height', height) .attr('fill', settings.bgcolor); } var chart = svg .append('g') .attr('width', chartWidth) .attr('height', chartHeight) .attr('transform', 'translate(' + settings.padding.left + ',' + settings.padding.top + ')'); // Bar color var color = d3.scaleLinear() .domain([0, settings.maxvalue]) .range(settings.colorscale); // X axis var x = d3.scaleLinear() .range([0, chartWidth]) .domain([0, 100]); var xAxis = d3.axisTop().scale(x).tickSizeOuter(0); if (settings.grid) xAxis.tickSizeInner(-chartHeight); // Y axis var y = d3.scaleBand() .range([0, chartHeight]) .domain(data.map(function (d) { return d.name; })); var yAxis = d3.axisLeft().scale(y).tickSizeOuter(0); chart.append('g') .attr('class', 'x axis') .call(xAxis); chart.selectAll('.x.axis') .append('text') .attr('class', 'xAxisLabel') .attr('y', -20) .attr('x', chartWidth / 2) .style('text-anchor', 'middle') .style('fill', '#000') .text(settings.xAxisLabel) var bar_g = chart.selectAll(".bar_g") .data(data) .enter() .append("g") .attr("class", function (d) { return d.class ? "bar_g " + d.class : "bar_g"; }) var link = bar_g.append("a") .each(function (d) { d3.select(this).attr("xlink:href", d.url).attr("title", d.value_tooltip); }) // The bar's var bar_line = link.append("line") .attr("class", "bar") .style("stroke", "grey") .style("stroke-width", 0.5) .attr("y1", function (d) { return y(d.name) + settings.barheight / 2; }) .attr("x1", 0) .attr("y2", function (d) { return y(d.name) + settings.barheight / 2; }) .attr("x2", function (d) { return x(d.value) }) var bar_circle = link.append("circle") .attr("class", "gene") .attr("gene_name", function (d, i) { return d.name }) //.attr("transform", "translate(0,0)") .attr("cy", function (d, i) { return y(d.name) + settings.barheight / 2; }) .attr("cx", function (d, i) { return x(d.value) }) .attr("r", 5) .style("stroke", "black") .style("fill", function(d,i) {return d.color}) if (settings.valueLabels) { bar.append('text') .text(function (d) { return d.value; }) .attr('text-align', 'right') .attr('dominant-baseline', 'middle') .attr('y', barHeight / 2) .attr('x', function (d) { return x(d.value) + 2; }); } chart.append('g') .attr('class', 'y axis') .attr('width', settings.padding.left - 5) .call(yAxis); chart.selectAll('.y.axis text') .attr('width', settings.padding.left - 5) .each(function (d, i) { var node = d3.select(this); if (data[i].url) { var txt = node.text(); node.text(''); node.append('a').attr("xlink:href", data[i].url).text(txt).style('cursor', 'pointer'); } if (data[i].value_tooltip) { node.attr('title', data[i].value_tooltip); d3.select(this).attr('title', data[i].value_tooltip); } }); /* svg.selectAll('.x.axis .tick text') .attr("transform", settings.xLabelTransform) .attr("text-anchor", settings.xLabelTransform.indexOf('rotate')!==-1? "end":"middle") .each(function (name, i) { var node = d3.select(this); if (typeof tooltips[i] !== 'undefined') { node.attr('title', tooltips[i]); } if (data[i][0].url) { } }); */ }