i working on heatmap. in make rectangles of heat map (width,height) programmatically depending upon data.
i want add sliders zooming on x-axis(time range) , y-axis(distance range). tried d3 scaling options works fine. scales(x-axis, y-axis) don't scale in proportion rectangles of graph. if rectangle between 10,20 miles y-axis scale. goes further 20 miles on scaling.
then tried viewbox on svg. works . scales kept in proportion graph exactly.
i want keep proportion of scales , graph on scaling not want increase size of scales labels makes graph ugly.
here code snippet how making graph
d3.json('datewisenewdataright.json',function(err,right_dat){ // console.log(right_dat); var dategroups=_.groupby(right_dat, "date"); var data = []; var x= 0,y=0; var tlength=0; var totaldates=object.keys(dategroups); var graphwidth=(total_width/totaldates.length)-6; for(var key in dategroups){ tlength=0; data = []; y=0; var segmentmiles=0; var currentgraphdata=dategroups[key]; var road=currentgraphdata[0]['road']; for(var = 0; < currentgraphdata.length-1; i++) { tlength+=currentgraphdata[i].miles; } (var = 0; < currentgraphdata.length-1; i++) { var height=0; segmentmiles=segmentmiles+currentgraphdata[i].miles; for(var j in times){ if(road!=currentgraphdata[i]['road']){ road=currentgraphdata[i]['road']; height=1; for(var k=0;k<times.length;k++){ data.push({value:20000,x:x,y:y, height:height ,width:col_width,name:"",tmc:"", length:"",road:""}); x=x+col_width; } break; } else{ col_width=graphwidth/24; var congestion= currentgraphdata[i][times[j]]; height=(currentgraphdata[i].miles/tlength)*total_height; //road=leftdat[i]['road']; data.push({value:congestion,x:x,y:y, height:height ,width:col_width,name:currentgraphdata[i]['name'],tmc:currentgraphdata[i]['tmc code'], length:currentgraphdata[i]['miles'],road:currentgraphdata[i]['road'],miles:segmentmiles}); // x=x+col_width; } x=x+col_width; } y=y+height; x=0; } plotsegmentnames(paneldata); var margin = { top: 50, right: 0, bottom: 10, left: 10 }; $('.heat-map-2').append('<div class="chart-right-'+key+' " style="width: '+graphwidth+'px;float:left;margin:3px;;overflow:hidden"></div>'); var graphdiv='.chart-right-'+key; var right_svg = d3.select(graphdiv) .append("svg") .attr("class", "chart") .attr("width",graphwidth) .attr("height", total_height ) .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var right_color_chart = right_svg.append("g") .attr("class", "rightheatmap"); right_color_chart.call(tip); var color = d3.scale.linear() .domain([d3.min(data), 1]) .range(["blue", "green"]); right_color_chart.selectall("rect") .data(data) .enter() .append("rect") .attr("x", function(d,i) {return d.x; }) .attr("y", function(d,i) { return d.y; }) .attr("width", col_width) .attr("height", function(d) { return d.height; }) .attr("road",function(d){ return d.road; }) .attr("miles", function(d) { return d.miles; }) .style("fill", function(d) {return choosecolor(d.value);}) .on('mouseover', tip.show) .on('mouseout', tip.hide); var right_xaxisscale = d3.time.scale(), right_xaxis = d3.svg.axis() .orient('bottom') .ticks(d3.time.hour,1) .tickformat(d3.time.format('%i %p')) .ticksubdivide(6); right_xaxis.scale(right_xaxisscale.range([0,graphwidth]).domain([timeformat.parse(times[0]),timeformat.parse(times[times.length-1])])); right_svg.append('g') .attr('class','x axis') .call(right_xaxis) .append('text') .attr('transform','translate('+total_width+',0)'); var yaxisscale = d3.scale.linear() .range([0,xaxisheight]) .domain([0,tlength]), yaxis = d3.svg.axis() .orient('right') .ticks(5) .scale(yaxisscale); right_svg.append('g') .attr('transform','translate('+1+','+0+')') .attr('class','y axis') .call(yaxis) // .append('text') // .text('length') // .attr('transform','translate(100,'+total_height+') rotate(-90)'); } var testtimes =times; var distancerange=[0,60]; $("#scale-slider") .slider({ animate:true, range: true, min: 0, max: 1440, step: 24, values: [0, 1440], slide: function (e, ui) { var slidertime= calculatesidertime(e,ui); testtimes=[slidertime.nob1time,slidertime.nob2time]; $('.x.axis').remove(); $('.y.axis').remove(); /* redrawheatmaps('left',left_color_chart,'leftheatmap',leftdat,testtimes,tlength); redrawheatmaps('right',right_color_chart,'rightheatmap',right_dat,testtimes,tlength);*/ redrawyheatmaps('left',left_color_chart,'leftheatmap',leftdat,testtimes,tlength,distancerange); redrawyheatmaps('right',right_color_chart,'rightheatmap',right_dat,testtimes,tlength,distancerange); } }) .on("slidechange", function( e, ui ) { }); $("#distance-slider") .slider({ animate:true, range: true, min: 0, max: 60, step: 5, values: [0, 60], slide: function (e, ui) { distancerange=ui.values; $('.x.axis').remove(); $('.y.axis').remove(); // left_color_chart.attr("transform", "translate("+ d3.event.translate + ")scale(" + d3.event.scale + ")"); redrawyheatmaps('left',left_color_chart,'leftheatmap',leftdat,testtimes,tlength,distancerange); redrawyheatmaps('right',right_color_chart,'rightheatmap',right_dat,testtimes,tlength,distancerange); $('.slider-distance1').html(ui.values[0]); $('.slider-distance2').html( ui.values[1]); } }) .on("slidechange", function( e, ui ) { }); });
just edit yaxisscale
's domain when scale event occurred.
first, remove y
method in zoom
. helps auto-scaling axis but, not case. i'll give explanation @ last.
zoom = d3.behavior.zoom() .scaleextent([0, 5]) .scale(1) .on("zoom", zoomed);
after, adjust yaxisscale
domain when scale value changed.
function zoomed() { yaxisscale.domain([0, tlength / d3.event.scale]); // added leftsvg.select(".y.axis").call(yaxis); zoomin(); }
why use division not multiplication? because if scale twice, axis values shown half in comparison original values.
if use zoom
's y
method, going auto-scale yaxisscale
using multiplication. so, said not case above.
Comments
Post a Comment