javascript - Apply zoom pan and axis rescale in d3 -
i have created scattered chart in d3. it's working fine have requirement add zooming , axis rescaling chart.
since pretty new d3 not able it.i have seen example able apply zooming, panning etc code in chart.
here code-
var margin = { top: 35, right: 10, bottom: 40, left: 80 }, width = width - margin.left - margin.right, height = height - margin.top - margin.bottom; var xvalue = function(d){ return d[measurearray[1]]; }, x = d3.scale.linear() .range([0, width*.98]), xmap = function(d,i) { return x(xvalue(d)); }, make_x_axis = function() { return d3.svg.gridaxis() .scale(x) .orient("bottom") }, xaxis = d3.svg.axis() .scale(x) .orient("bottom") .tickformat(function(d) { return d; }); var yvalue = function(d){ return d[measurearray[0]]; }, y = d3.scale.linear() .range([height*.98, 0]), ymap = function(d,i){ return y(yvalue(d)); }, make_y_axis = function() { return d3.svg.gridaxis() .scale(y) .orient("left") }, yaxis = d3.svg.axis() .scale(y) .orient("left") .tickformat(function(d) { // if(typeof displayy !=="undefined" && displayy =="yes"){ // if(yaxisformat==""){ return d; }); var zvalue = function(d){ return d[measurearray[2]]; }, zscale = d3.scale.linear() .range([height*.98, 0]), zmap = function(d) { return zscale(zvalue(d)); }; var color = d3.scale.category10(); var svg = d3.select("body") .append("svg") .attr("id", "svg_" + div) .attr("viewbox", "0 0 "+(width + margin.left + margin.right)+" "+(height + margin.top + margin.bottom+ 17.5 )+" ") .classed("svg-content-responsive", true) .append("g") .attr("transform", "translate(" + (margin.left*.7) + "," + (margin.top+3) + ")"); var tooltip = d3.select("#"+divid).append("div") .attr("class", "tooltip") .style("opacity", 0); data.foreach(function(d) { d[measurearray[2]] = +d[measurearray[2]] d[measurearray[1]] = +d[measurearray[1]]; d[measurearray[0]] = +d[measurearray[0]]; }); x.domain([d3.min(data, xvalue)-1, d3.max(data, xvalue)+1]); y.domain([d3.min(data, yvalue)-1, d3.max(data, yvalue)+1]); // } if(typeof chartdata[divid]["displayx"]!="undefined" && chartdata[divid]["displayx"]!="" && chartdata[divid]["displayx"]!="yes"){}else{ svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xaxis) .append("text") .attr("class", "label") .attr("x", width) .attr("y", -6) .style("text-anchor", "end") .text(measurearray[1]); } // y-axis if(typeof chartdata[divid]["displayy"]!="undefined" && chartdata[divid]["displayy"]!="" && chartdata[divid]["displayy"]!="yes"){}else{ svg.append("g") .attr("class", "y axis") .call(yaxis) .append("text") .attr("class", "label") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text(measurearray[0]); } var max = maximumvalue(data, measurearray[2]); var min = minimumvalue(data, measurearray[2]); var temp = {}; temp["min"] = min; temp["max"] = max; svg.selectall(".circle") .data(data) .enter().append("circle") .attr("index_value", function(d, i) { return "index-" + d[columns[1]].replace(/[^a-za-z0-9]/g, '', 'gi'); }) .attr("class", function(d, i) { return "bars-bubble-index-" + d[columns[1]].replace(/[^a-za-z0-9]/g, '', 'gi')+div; }) .attr("r", function(d,i){ // var scale = d3.scale.linear().domain([temp["max"], temp["min"]]).range(["38", "12"]); // var radius = scale(data[i][measurearray[2]]); return 6; }) .attr("cx", xmap) .attr("cy", ymap) .attr("opacity",".6") .attr("fill", 'red') .attr("id",function(d,i) { return d[columns[0]]+":"+d[columns[1]]; }) .attr("onclick", fun);
working fiddle.
you can this:
//define zoom behavior var zoom = d3.behavior.zoom() .on("zoom", draw); //make rectangle receiving zoom/pan action. svg.append("rect") .attr("class", "pane") .attr("width", width) .attr("height", height) .call(zoom); //make clip path circle don't go out of graph. svg.append("clippath") .attr("id", "clip") .append("rect") .attr("x", x(0)) .attr("y", y(1)) .attr("width", x(1) - x(0)) .attr("height", y(0) - y(1));
add following class style(so rectangle pane not visible) note: fill none:
rect.pane { cursor: move; fill: none; pointer-events: all; }
after defining domain, set zoom x , y
x.domain([d3.min(data, xvalue) - 1, d3.max(data, xvalue) + 1]); y.domain([d3.min(data, yvalue) - 1, d3.max(data, yvalue) + 1]); // set zoom x , y zoom.x(x); zoom.y(y);
make group circle within clippath
circlegroup = svg.append("g").attr("clip-path", "url(#clip)"); circlegroup.selectall(".circle")...
define draw function called on zoom , pan:
function draw() { svg.select("g.x.axis").call(xaxis);//zoom of x axis svg.select("g.y.axis").call(yaxis);//zoom of y axis //update position of circle on zoom/pan svg.selectall("circle").attr("cx", xmap) .attr("cy", ymap) }
working code here
Comments
Post a Comment