/* global d3:true */ /* global _F:true */ (function() { 'use strict'; var URL = 'http://fantom.gsc.riken.jp/5/sstar/'; var _series = _F('Series'); var _sample = _F('Sample'); var _name = _F('Time Course'); var _id = _F('Time Course Id'); var _time = _F('Time', Number); var _timePoint = _F('Time Desc'); var _species = _F('Species'); var _donor = _F('Donor'); var _key = _F('key'); var _values = _F('values'); var _timeSort = _time.order().asc; var _donorSort = _donor.order().desc; var _sort = function(a,b) { return _timeSort(a,b) || _donorSort(a,b); }; var _timeCourseUrl = function(d) { return URL+d.id; }; var _sampleUrl = function(d) { return URL+'FF:'+_sample(d); }; function SeriesChart() { var width = 500, dy = 20, r = 3.5, ddy = 0, height = 900, margin = { top: 0, right: 200, bottom: 40, left: 200 }; var color = d3.scale.category10(); function chart(selection) { selection.each(function(_data) { var series = _series(_data[0]); var nestedData = d3.nest() .key(_name) //.sortKeys(d3.ascending) .key(_time) // .sortKeys(d3.ascending) .sortValues(_sort) .entries(_data); var xValues = []; nestedData.forEach(function(d) { var times = d.values.map(function(d) { d[_timePoint.key] = _timePoint(d.values[0]).trim(); d[_time.key] = _time(d.values[0]); return d[_time.key]; }); d.id = _id(d.values[0].values[0]); d.species = _species(d.values[0].values[0]); d.timeRange = d3.extent(times); xValues = xValues.concat(times); }); nestedData = nestedData .sort(_F('timeRange.1') .order(d3.descending)); height = dy*nestedData.length; var svg = d3.select(this) .append('svg') .attr('width', width+margin.left+margin.right) .attr('height', height+margin.top+margin.bottom) .append('g') .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); svg.append('g') .append('text') .attr('dy', -0) .attr('dx', width/2) .style('text-anchor', 'middle') .attr('class','title') .text(series); var xExtent = d3.extent(_data, _time); var xMax = xExtent[1]; var xUnit = 'mins', xUnitScale = 1; var xScale, xAxis = d3.svg.axis(); if(series === 'Early response') { //console.log(nestedData); xScale = d3.scale.log().clamp(true) .domain([1, xMax]) .range([0, width]); xValues .push(1000,10000); xValues = xValues.sort(d3.ascending); xAxis .scale(xScale) .tickValues(xValues) .tickFormat(function(d) { if (d === 0) { return '0:00'; } if (d < 60) { return '0:'+d; } d = d3.round(d/60,2); if (d === 1) { return d+'hr'; } if (d <= 5) { return d%1 === 0 ? d : ''; } if (d <= 5) { return d%1 === 0 ? d : ''; } if (d < 72) { return d%12 === 0 ? d : ''; } d = d/24; if (d === 4) { return d+'days'; } if (d === 28) { return d+'days'; } return d%2 === 0 ? d: ''; }); } else if (series === 'Development') { xUnitScale = 1/60/24; xUnit = 'days'; //console.log(xExtent); xScale = d3.scale.linear() .domain(xExtent) .range([0, width]); xAxis .scale(xScale).tickValues(xValues) .tickFormat(function(d, i) { // mins var v = d3.round(d*xUnitScale,2); if (v < 0) { return i % 2 === 0 ? 'E'+(v+20) : ''; } return 'N'+v; }); } else { if (xMax > 100) { xUnitScale = 1/60; xUnit = 'hrs'; } if (xMax > 10000) { xUnitScale = 1/60/24; xUnit = 'days'; } xScale = d3.scale.linear() .domain([0, xMax]) .range([0, width]); xAxis .scale(xScale).tickValues(xValues) .tickFormat(function(d) { // mins var v = d3.round(d*xUnitScale,2); if (d === xMax) { return v+xUnit; } if (v%2 !== 0) { return ''; } return v; }); } svg.append('g') .attr('transform', 'translate(0,' + (height+margin.bottom/2) + ')') .call(xAxis); var gSample = svg.selectAll('.sample').data(nestedData).enter() .append('g') .attr('transform', function(d, i) { return 'translate(0,' + (dy*i) + ')'; }) .attr('class',function(d) { return 'sample '+_species(d.values[0].values[0]); }); gSample .append('a') .attr('xlink:href', _timeCourseUrl) .attr('class','sample-name') .append('text') .style('text-anchor', 'end') .attr('dy', dy) .attr('dx', -10) .text(_key); gSample .append('g') .attr('transform', function() { return 'translate(0,' + dy + ')'; }) //.each(function(d) { //d3.select(this).call(xAxis.tickValues(d.timeValues)); //}) //.call(xAxis) ; gSample .append('line') .attr('class','sample-axis') //.attr("y1", 0) .attr('y1', dy) .attr('y2', dy) //.attr('x1', 0) .attr('x2', width); gSample .append('line') .attr('class','sample-range') .attr('y1', dy) .attr('y2', dy) .attr('x1', function(d) { return xScale(d.timeRange[0]); }) .attr('x2', function(d) { return xScale(d.timeRange[1]); }) .style('stroke', function(d) { return color(_species(d.values[0].values[0])); }); var times = gSample .selectAll('.point').data(_values).enter() .append('g') .attr('class', function(d) { return 'point '+_species(d); }); var points = times .selectAll('a').data(_values).enter() .append('a') .attr('xlink:href', _sampleUrl) .append('circle') .attr('r', r) .attr('cx', function(d) { return xScale(+_time(d)); }) .attr('cy', function(d, i) { return dy-i*ddy; }) //function(d) { return dy/2+(_doner(d)-1)*ddy; }) .style('fill', function(d) { return color(_species(d)); }); points .append('title') .text(function(d) { return _sample(d)+' '+_donor(d)+' @'+d['Time Desc']; }); times.on('mouseenter', function(d) { //d3.selectAll('svg') // .classed('hover', true); var N = d.values.length-1; var duration = 300; d3.select(this).selectAll('circle') .transition() //.delay(function(d, i) { return i / N * duration; }) .duration(duration) .attr('r', 1.5*r) .attr('cy', function(d, i) { return dy-(N-i)*2.5*r; }); }); times.on('mouseleave', function() { d3.select(this).selectAll('circle') .transition() .duration(500) .attr('r', r) .attr('cy', function(d, i) { return dy-i*ddy; }); }); }); } chart.color = function(_) { if (arguments.length < 1) { return color; } color = _; return chart; }; chart.width = function(_) { if (arguments.length < 1) { return width; } width = _; return chart; }; chart.margin = function(_) { if (arguments.length < 1) { return margin; } margin = _; return chart; }; return chart; } function SeriesLegend() { var //width = 830, dy = 20, gap = 3, //height = 200, margin = { top: 10, right: 30, bottom: 20, left: 730 }; var color = d3.scale.category10(); function chart(selection) { selection.each(function(data) { data = data || color.domain(); //console.log(data); var g=d3.select(this).append('g') .attr('transform', 'translate(' + [margin.left,margin.top] + ')'); var legend = g .selectAll('.legend') .data(data) .enter().append('g') .attr('class', function(d) { return 'legend '+d; }) .attr('transform', function(d,i) { return 'translate(0,' + (i * (dy+gap)) + ')'; }); legend.append('rect') .attr('x', 0) .attr('width', dy) .attr('height', dy) .style('fill', color); legend.append('text') .attr('x', dy+gap) .attr('y', 9) .attr('dy', '.35em') .style('text-anchor', 'start') .text(function(d) { return d; }); legend.on('mouseenter', function(d) { d3.selectAll('svg') .classed('hover hover-'+d, true); }); legend.on('mouseleave', function(d) { d3.selectAll('svg') .classed('hover hover-'+d, false); }); }); } chart.color = function(_) { if (arguments.length < 1) { return color; } color = _; return chart; }; chart.margin = function(_) { if (arguments.length < 1) { return margin; } margin = _; return chart; }; return chart; } d3.tsv('table.tsv', function(data) { var nestedData = d3.nest() .key(_series) .sortKeys(d3.ascending) .entries(data); var color = d3.scale.category10().domain(['Human','Mouse']); //var width = 800; var width = 800; var seriesChart = new SeriesChart() .color(color) .width(width) .margin({ top: 60, right: 200, bottom: 40, left: 200 }); var seriesLegend = new SeriesLegend() .color(color) .margin({ top: 35, right: 30, bottom: 20, left: width+230 }); var charts = d3.select('#timecourseChart') .selectAll('.series').data(nestedData).enter() .append('div') .attr('class', 'series'); charts .append('div').datum(_values) .call(seriesChart); d3.select('svg').append('g').datum(color.domain()) .call(seriesLegend); }); })();