D3.js zooming with axis
<p>I have a project where I need to zoom on 3 axes independently.  I'm using scroll bars to accomplish this, but the axes aren't redrawing when the zoom happens.</p>

<p>Additionally, the clip path doesn't seem to be working as expected.</p>

<p>Eventually I want to add panning functionality to the chart as well, but I'm not sure where to start for this.</p>

<p><a href="http://jsfiddle.net/yo4mwLpj/" rel="nofollow">http://jsfiddle.net/yo4mwLpj/</a></p>

<p>Thanks in advance for the help.</p>

<pre><code>// cases vs deaths of a disease over time
var data = [
{"year": "1960", "cases":"887",   "deaths": "199"},
{"year": "1965", "cases":"218",   "deaths": "55"},
{"year": "1993", "cases":"37046", "deaths": "931"},
{"year": "1994", "cases":"38735", "deaths": "118"},
{"year": "1995", "cases":"19903", "deaths": "624"},
{"year": "1997", "cases":"4170",  "deaths": "125"},
{"year": "1998", "cases":"10000", "deaths": "0"}
];
data.forEach(function (d) {
   d.year   = d3.time.format("%Y").parse(d.year.toString());
   d.cases  = +d.cases;
   d.deaths = +d.deaths;
});

var margin = { top: 30, right: 40, bottom: 30, left: 50 },
   width = 500 - margin.left - margin.right,
   height = 270 - margin.top - margin.bottom;

var xScale = d3.time.scale()
   .domain(d3.extent(data, function (d) { return d.year; }))
   .range([0, width]);

var yScaleLeft = d3.scale.linear()
   .domain([0, d3.max(data, function (d) { return d.cases; })])
   .range([height, 0]);

var yScaleRight = d3.scale.linear()
   .domain([0, d3.max(data, function (d) { return d.deaths; })])
   .range([height, 0]);

var xAxis = d3.svg.axis()
   .scale(xScale)
   .orient("bottom").ticks(5);

var yAxisLeft = d3.svg.axis()
   .scale(yScaleLeft)
   .orient("left").ticks(5);

var yAxisRight = d3.svg.axis()
   .scale(yScaleRight)
   .orient("right").ticks(5);

var lineCases = d3.svg.line()
   .x(function (d) { return xScale(d.year); })
   .y(function (d) { return yScaleLeft(d.cases); });

var lineDeaths = d3.svg.line()
   .x(function (d) { return xScale(d.year); })
   .y(function (d) { return yScaleRight(d.deaths); });

var svg = d3.select("#chart").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")
   .attr("class", "x axis")
   .attr("transform", "translate(0," + height + ")")
   .call(xAxis);

svg.append("g")
   .attr("class", "y axis yleft")
   .call(yAxisLeft);

svg.append("g")
   .attr("class", "y axis yright")
   .call(yAxisRight)
   .attr('transform', 'translate(' + width + ',0)');

svg.append("path")
   .datum(data)
   .attr("class", "line lineLeft")
   .style("stroke", "red")
   .attr("d", lineCases(data))
   .attr("clip", "url(#clip)");

svg.append("path")
   .datum(data)
   .attr("class", "line lineRight")
   .attr("d", lineDeaths(data))
   .attr("clip", "url(#clip)");

svg.append("clipPath")
   .attr("id", "clip")
   .append("rect")
   .attr("width", width)
   .attr("height", height);

$("#slider-x").slider({
   orientation: "horizontal",
   range: "min",
   min: 1000,
   max: 10000, // make max be (maxDate-minDate).Days*1000, so you can zoom to one day
   value: 1000,
   slide: function( event, ui ) {
      zoomXWithSlider(ui.value/1000);
   }
});

$( "#slider-y-left" ).slider({
   orientation: "vertical",
   range: "min",
   min: 1000,
   max: 10000,
   value: 1000,
   slide: function( event, ui ) {
      zoomLeftWithSlider(ui.value/1000);
   }
});

$("#slider-y-right").slider({
   orientation: "vertical",
   range: "min",
   min: 1000,
   max: 10000,
   value: 1000,
   slide: function( event, ui ) {
      zoomRightWithSlider(ui.value/1000);
   }
});

function zoomXWithSlider(scale) {
   // Note: works only on the &lt;g&gt; element and not on the &lt;svg&gt; element
     // which is a common mistake
   svg.selectAll("path.line").attr("transform", "scale("+scale+", 1)");
   svg.select(".x.axis").call(xAxis);
}

function zoomLeftWithSlider(scale) {
   svg.select("path.line.lineLeft").attr("transform", "scale(1, "+scale+")");
   svg.select(".y.axis.yleft").call(yAxisLeft);
}

function zoomRightWithSlider(scale) {
   svg.select("path.line.lineRight").attr("transform", "scale(1, "+scale+")");
   svg.select(".y.axis.yright").call(yAxisRight);
}
</code></pre>