I don't think you can zoom/pan on an ordinal axis.

One work around is that you make a linear scale and make it look like an ordinal scale.

Define your ordinals like this:

var ordinals = ["a", "b", "c"];

Instead of ordinal scale make a linear scale:

var yscale = d3.scale.linear()
  .domain([0, ordinals.length])
  .range([height - - margin.bottom, 0]);

Next when you make the yscale make use of the tick format to return the label of your choice.

var yAxis = d3.svg.axis()
  .tickFormat(function(d) {
    return ordinals[d];//now for 0 it will return 'a' for 1 b and so on...

Make your zoom to use the new y scale like this:

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

Hide all ticks without label

var hideTicksWithoutLabel = function() {
  //hide ticks without label
  svg.selectAll(".y .tick")[0].forEach(function(g) {
    if ("text").text() == "") {"display", "none");
    } else {"display", "");

Now call this function after zoom.

working code here

Related Query

More Query from same tag