How to draw vertical and horzontial line for bubble in d3.js -
i have generated graph this
http://prcweb.co.uk/lab/what-makes-us-happy/
i want make x-line , y-line indiduval bubbles when hover.is possible??. suggestions welcomed.
main.js
// helpers function parsedata(d) { var keys = _.keys(d[0]); return _.map(d, function(d) { var o = {}; _.each(keys, function(k) { if( k == 'country' ) o[k] = d[k]; else o[k] = parsefloat(d[k]); }); return o; }); } function getbounds(d, paddingfactor) { // find min , maxes (for scales) paddingfactor = typeof paddingfactor !== 'undefined' ? paddingfactor : 1; var keys = _.keys(d[0]), b = {}; _.each(keys, function(k) { b[k] = {}; _.each(d, function(d) { if(isnan(d[k])) return; if(b[k].min === undefined || d[k] < b[k].min) b[k].min = d[k]; if(b[k].max === undefined || d[k] > b[k].max) b[k].max = d[k]; }); b[k].max > 0 ? b[k].max *= paddingfactor : b[k].max /= paddingfactor; b[k].min > 0 ? b[k].min /= paddingfactor : b[k].min *= paddingfactor; }); return b; } function getcorrelation(xarray, yarray) { function sum(m, v) {return m + v;} function sumsquares(m, v) {return m + v * v;} function filternan(m, v, i) {isnan(v) ? null : m.push(i); return m;} // clean data (because know values missing) var xnan = _.reduce(xarray, filternan , []); var ynan = _.reduce(yarray, filternan , []); var include = _.intersection(xnan, ynan); var fx = _.map(include, function(d) {return xarray[d];}); var fy = _.map(include, function(d) {return yarray[d];}); var sumx = _.reduce(fx, sum, 0); var sumy = _.reduce(fy, sum, 0); var sumx2 = _.reduce(fx, sumsquares, 0); var sumy2 = _.reduce(fy, sumsquares, 0); var sumxy = _.reduce(fx, function(m, v, i) {return m + v * fy[i];}, 0); var n = fx.length; var ntor = ( ( sumxy ) - ( sumx * sumy / n) ); var dtorx = sumx2 - ( sumx * sumx / n); var dtory = sumy2 - ( sumy * sumy / n); var r = ntor / (math.sqrt( dtorx * dtory )); // pearson ( http://www.stat.wmich.edu/s216/book/node122.html ) var m = ntor / dtorx; // y = mx + b var b = ( sumy - m * sumx ) / n; // console.log(r, m, b); return {r: r, m: m, b: b}; } d3.json('ceral.json', function(data) { var xaxis = 'weight', yaxis = 'height'; var xaxisoptions = ["bp_systolic", "bp_diastolic","height", "weight", "bmi","a1c","cholestrol"] var yaxisoptions = ["bp_systolic", "bp_diastolic","height","weight", "bmi","a1c","cholestrol"]; var descriptions = { "bp_systolic" : "bp_systolic (mm hg)", "bp_diastolic" : "bp_diastolic (mm hg)", "weight" : "weight (lbs)", "height" : "height (inches)", "bmi" : "bmi (kg/m2)", "a1c" : "a1c (%)", "cholestrol":"cholestrol (mg/dl)" }; var description = { "bp_systolic" : "bp_systolic (mm hg)", "bp_diastolic" : "bp_diastolic (mm hg)", "weight" : "weight (lbs)", "height" : "height (inches)", "bmi" : "bmi (kg/m2)", "a1c" : "a1c (%)", "cholestrol":"cholestrol (mg/dl)" }; var line; var keys = _.keys(data[0]); // alert(keys); var data = parsedata(data); // alert(data.tosource()); var bounds = getbounds(data, 1); // alert(bounds.tosource()); // svg , d3 stuff var svg = d3.select("#chart") .append("svg") .attr("width", 1000) .attr("height", 640); var xscale, yscale; svg.append('g') .classed('chart', true) .attr('transform', 'translate(80, -60)'); // build menus d3.select('#x-axis-menu') .selectall('li') .data(xaxisoptions) .enter() .append('li') .text(function(d) {return d;}) .classed('selected', function(d) { return d === xaxis; }) .on('click', function(d) { xaxis = d; // alert(xaxis); updatechart(); updatemenus(); }); d3.select('#y-axis-menu') .selectall('li') .data(yaxisoptions) .enter() .append('li') .text(function(d) {return d;}) .classed('selected', function(d) { return d === yaxis; }) .on('click', function(d) { yaxis = d; // alert(xaxis); updatechart(); updatemenus(); }); // country name d3.select('svg g.chart') .append('text') .attr({'id': 'countrylabel', 'x': 0, 'y': 130}) .style({'font-size': '40px', 'font-weight': 'bold', 'fill': '#ddd'}); // best fit line (to appear behind points) d3.select('svg g.chart') .append('line') .attr('id', 'bestfit'); // axis labels d3.select('svg g.chart') .append('text') .attr({'id': 'xlabel', 'x': 400, 'y': 670, 'text-anchor': 'middle'}) .text(descriptions[xaxis]); d3.select('svg g.chart') .append('text') .attr('transform', 'translate(-60, 330)rotate(-90)') .attr({'id': 'ylabel', 'text-anchor': 'middle'}) .text(descriptions[yaxis]); // render points updatescales(); var pointcolour = d3.scale.category20b(); d3.select('svg g.chart') .selectall('circle') .data(data) .enter() .append('circle') .attr('cx', function(d) { // alert(d.tosource()); // alert(d[xaxis]); // alert(xscale(d[xaxis]).tosource()); return isnan(d[xaxis]) ? d3.select(this).attr('cx') : xscale(d[xaxis]); }) .attr('cy', function(d) { return isnan(d[yaxis]) ? d3.select(this).attr('cy') : yscale(d[yaxis]); }) .attr('fill', function(d, i) {return pointcolour(i);}) .style('cursor', 'pointer') .on('mouseover', function(d) { d3.select('svg g.chart #countrylabel') .html("id:"+d.patient_id+" ["+d[xaxis]+","+d[yaxis]+"] ") .transition() .style('opacity', 1) }) .on('mouseout', function(d) { d3.select('svg g.chart #countrylabel') .transition() .duration(1500) .style('opacity', 0); }) updatechart(true); updatemenus(); // render axes d3.select('svg g.chart') .append("g") .attr('transform', 'translate(0, 630)') .attr('id', 'xaxis') .call(makexaxis); d3.select('svg g.chart') .append("g") .attr('id', 'yaxis') .attr('transform', 'translate(-10, 0)') .call(makeyaxis); //// rendering functions function updatechart(init) { updatescales(); d3.select('svg g.chart') .selectall('circle') .transition() .duration(500) .ease('quad-out') .attr('cx', function(d) { return isnan(d[xaxis]) ? d3.select(this).attr('cx') : xscale(d[xaxis]); }) .attr('cy', function(d) { return isnan(d[yaxis]) ? d3.select(this).attr('cy') : yscale(d[yaxis]); }) .attr('r', function(d) { return isnan(d[xaxis]) || isnan(d[yaxis]) ? 0 : 5; }); // update axes d3.select('#xaxis') .transition() .call(makexaxis); d3.select('#yaxis') .transition() .call(makeyaxis); // update axis labels d3.select('#xlabel') .text(descriptions[xaxis]); d3.select('#ylabel') .text(descriptions[yaxis]); // update correlation var xarray = _.map(data, function(d) {return d[xaxis];}); var yarray = _.map(data, function(d) {return d[yaxis];}); var c = getcorrelation(xarray, yarray); var x1 = xscale.domain()[0], y1 = c.m * x1 + c.b; var x2 = xscale.domain()[1], y2 = c.m * x2 + c.b; // fade in d3.select('#bestfit') .style('opacity', 0) .attr({'x1': xscale(x1), 'y1': yscale(y1), 'x2': xscale(x2), 'y2': yscale(y2)}) .transition() .duration(1500) .style('opacity', 1); d3.select('#line') .style('opacity', 0) .attr({'x1': 0, 'y1': 100, 'x2': 100, 'y2':160}) .transition() .duration(1500) .style('opacity', 1); } // function updatescales() { xscale = d3.scale.linear() .domain([bounds[xaxis].min, bounds[xaxis].max]) .range([-10, 780]); yscale = d3.scale.linear() .domain([bounds[yaxis].min, bounds[yaxis].max]) .range([630, 100]); } function makexaxis(s) { s.call(d3.svg.axis() .scale(xscale) .orient("bottom")); } function makeyaxis(s) { s.call(d3.svg.axis() .scale(yscale) .orient("left")); } function updatemenus() { d3.select('#x-axis-menu') .selectall('li') .classed('selected', function(d) { return d === xaxis; }); d3.select('#y-axis-menu') .selectall('li') .classed('selected', function(d) { return d === yaxis; }); } })
main.html
<!doctype html> <meta charset="utf-8"> <html lang="en"> <head> <meta charset="utf-8"> <title>plotter</title> <link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/svg.css"> <style> #ymenu { margin-left: 30px; } line { stroke: black; stroke-width: 1px; } </style> </head> <body> <div id="wrapper"> <div id="chart"> </div> <div id="ymenu"> <h1>x axis</h1> <!-- <h2>↑ y axis</h2> <ul id="y-axis-menu"></ul> <h2>→ x axis</h2> --> <ul id="x-axis-menu"></ul> </div> <div id="menu"> <h1>y axis</h1> <ul id="y-axis-menu"></ul> </div> </div> <script src="js/d3.v3.min.js"></script> <script src="js/underscore-min.js"></script> <script src="js/main.js"></script> <!-- twitter --> <div id="fb-root"></div> </body> </html>
data
[{"patient_id":"22","bp_systolic":"130","unit_systolic":"mm hg","bp_diastolic":"80","unit_diastolic":"mm hg","weight":"174.633063","unit_weight":"lbs","height":"69.99986","unit_height":"inches","bmi":"25.109628","unit_bmi":"kg/m2","a1c":"5.9","unit_a1c":"%","cholestrol":"241","unit_cholestrol":"mg/dl"}, {"patient_id":"27","bp_systolic":"108","unit_systolic":"mm hg","bp_diastolic":"80","unit_diastolic":"mm hg","weight":"0","unit_weight":"lbs","height":"0","unit_height":"inches","bmi":"0","unit_bmi":"kg/m2","a1c":"0","unit_a1c":"%","cholestrol":"0","unit_cholestrol":"mg/dl"}, {"patient_id":"33","bp_systolic":"0","unit_systolic":"mm hg","bp_diastolic":"0","unit_diastolic":"mm hg","weight":"0","unit_weight":"lbs","height":"0","unit_height":"inches","bmi":"0","unit_bmi":"kg/m2","a1c":"0","unit_a1c":"%","cholestrol":"0","unit_cholestrol":"mg/dl"}, {"patient_id":"48","bp_systolic":"132","unit_systolic":"mm hg","bp_diastolic":"80","unit_diastolic":"mm hg","weight":"0","unit_weight":"lbs","height":"0","unit_height":"inches","bmi":"0","unit_bmi":"kg/m2","a1c":"0","unit_a1c":"%","cholestrol":"0","unit_cholestrol":"mg/dl"}, {"patient_id":"50","bp_systolic":"160","unit_systolic":"mm hg","bp_diastolic":"74","unit_diastolic":"mm hg","weight":"0","unit_weight":"lbs","height":"0","unit_height":"inches","bmi":"0","unit_bmi":"kg/m2","a1c":"0","unit_a1c":"%","cholestrol":"0","unit_cholestrol":"mg/dl"}, {"patient_id":"51","bp_systolic":"118","unit_systolic":"mm hg","bp_diastolic":"76","unit_diastolic":"mm hg","weight":"0","unit_weight":"lbs","height":"0","unit_height":"inches","bmi":"0","unit_bmi":"kg/m2","a1c":"7.3","unit_a1c":"%","cholestrol":"214","unit_cholestrol":"mg/dl"}, {"patient_id":"70","bp_systolic":"137","unit_systolic":"mm hg","bp_diastolic":"72","unit_diastolic":"mm hg","weight":"0","unit_weight":"lbs","height":"0","unit_height":"inches","bmi":"0","unit_bmi":"kg/m2","a1c":"0","unit_a1c":"%","cholestrol":"0","unit_cholestrol":"mg/dl"}, {"patient_id":"100","bp_systolic":"100","unit_systolic":"mm hg","bp_diastolic":"60","unit_diastolic":"mm hg","weight":"0","unit_weight":"lbs","height":"0","unit_height":"inches","bmi":"0","unit_bmi":"kg/m2","a1c":"0","unit_a1c":"%","cholestrol":"0","unit_cholestrol":"mg/dl"}, {"patient_id":"103","bp_systolic":"130","unit_systolic":"mm hg","bp_diastolic":"60","unit_diastolic":"mm hg","weight":"0","unit_weight":"lbs","height":"0","unit_height":"inches","bmi":"0","unit_bmi":"kg/m2","a1c":"0","unit_a1c":"%","cholestrol":"0","unit_cholestrol":"mg/dl"}, {"patient_id":"124","bp_systolic":"115","unit_systolic":"mm hg","bp_diastolic":"70","unit_diastolic":"mm hg","weight":"295.3793502","unit_weight":"lbs","height":"68.999862","unit_height":"inches","bmi":"43.71111","unit_bmi":"kg/m2","a1c":"0","unit_a1c":"%","cholestrol":"0","unit_cholestrol":"mg/dl"}, {"patient_id":"126","bp_systolic":"120","unit_systolic":"mm hg","bp_diastolic":"70","unit_diastolic":"mm hg","weight":"0","unit_weight":"lbs","height":"0","unit_height":"inches","bmi":"0","unit_bmi":"kg/m2","a1c":"0","unit_a1c":"%","cholestrol":"0","unit_cholestrol":"mg/dl"}]
Comments
Post a Comment