score:2

Few things here:

1.) You aren't applying a clip-path to the line. This is why it overruns the grid.

2.) Your grid is black because you've appended a rect to it (so it can receive the pan/zoom mouse events) but you aren't setting it's fill to something (it's black by default). Note, you can't set it's fill to none since then it won't get the mouse events.

3.) You shouldn't share the axis definition like you are doing:

.call(xAxis.innerTickSize(6).tickPadding(-20).tickFormat(""));

The pan and zoom functionality is going to need to redraw the axis(es) and grid(s), keep a reference to each one you create.

4.) In your zoom event, don't re-append a new line. Select the existing one and update it's data:

d3.select(".line")
  .attr("d", line(data));

Putting this all together:

<!DOCTYPE html>
<meta charset="utf-8">
<title>Zoom + Pan</title>
<style>
  svg {
    font: 10px sans-serif;
    shape-rendering: crispEdges;
  }
  
  rect {
    fill: transparent;
  }
  
  .axis path,
  .axis line {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
  }
  
  .line {
    fill: none;
    stroke: steelblue;
    stroke-width: 1.5px;
    clip-path: url(#clip);
  }
  
  .grid .tick {
    stroke: lightgrey;
    opacity: 0.7;
  }
  
  .grid path {
    stroke-width: 0;
  }
</style>

<body>
  <script src="//d3js.org/d3.v3.min.js"></script>
  <script>
    var margin = {
        top: 20,
        right: 20,
        bottom: 30,
        left: 40
      },
      width = 600 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;

    var x = d3.scale.linear()
      .domain([0, 10])
      .range([0, width]);

    var y = d3.scale.linear()
      .domain([0, 10])
      .range([height, 0]);

    var zoom = d3.behavior.zoom()
      .x(x)
      .y(y)
      .scaleExtent([1, 32])
      .on("zoom", zoomed);

    var svg = d3.select("body").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 + ")")
      .call(zoom);

    var xAxis1 = d3.svg.axis()
      .scale(x)
      .orient("bottom")
      .ticks(5)
      .innerTickSize(-6)
      .outerTickSize(0)
      .tickPadding(7);

    var yAxis1 = d3.svg.axis()
      .scale(y)
      .orient("left")
      .ticks(5)
      .innerTickSize(-6)
      .outerTickSize(0)
      .tickPadding(7);

    var xAxis2 = d3.svg.axis()
      .scale(x)
      .orient("top")
      .ticks(5)
      .innerTickSize(6)
      .tickPadding(-20)
      .tickFormat("");

    var yAxis2 = d3.svg.axis()
      .scale(y)
      .orient("left")
      .ticks(5)
      .innerTickSize(6)
      .tickPadding(-20)
      .tickFormat("");

    var xGrid = d3.svg.axis()
      .scale(x)
      .orient("bottom")
      .tickSize(-height, -height, 0)
      .tickFormat("");

    var yGrid = d3.svg.axis()
      .scale(y)
      .orient("left")
      .ticks(5)
      .tickSize(-width, -width, 0)
      .tickFormat("");
      
    // Add x grid
    svg.append("g")
      .attr("class", "x grid")
      .attr("transform", "translate(0," + height + ")")
      .call(xGrid);

    // Add y grid
    svg.append("g")
      .attr("class", "y grid")
      .call(yGrid);

    svg.append("g")
      .attr("class", "x1 axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis1);

    svg.append("g")
      .attr("class", "y1 axis")
      .call(yAxis1);

    /* append additional X axis */
    svg.append("g")
      .attr("class", "x2 axis")
      .attr("transform", "translate(" + [0, 0] + ")")
      .call(xAxis2);

    /* append additional y axis */
    svg.append("g")
      .attr("class", "y2 axis")
      .attr("transform", "translate(" + [width, 0] + ")")
      .call(yAxis2);

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

    var data = [];

    for (var k = -100; k < 101; k++) {
      data.push({
        x: k / 10,
        y: 0.5 * k * k / 100
      });
    }

    var line = d3.svg.line()
      .x(function(d) {
        return x(d.x);
      })
      .y(function(d) {
        return y(d.y);
      })
      .interpolate("linear");

    svg.append("path")
      .attr("class", "line")
      .attr("d", line(data))

    function zoomed() {
      svg.select(".x1.axis").call(xAxis1);
      svg.select(".y1.axis").call(yAxis1);
      svg.select(".x2.axis").call(xAxis2);
      svg.select(".y2.axis").call(yAxis2);
      svg.select(".x.grid").call(xGrid);
      svg.select(".y.grid").call(yGrid);

      d3.select(".line")
        .attr("d", line(data));
    }
  </script>


Related Query

More Query from same tag