score:5

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.top - 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()
  .scale(yscale)
  .orient('left')
  .tickFormat(function(d) {
    return ordinals[d];//now for 0 it will return 'a' for 1 b and so on...
  })
  .tickPadding(8);

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

var zoom = d3.behavior.zoom()
  .x(x)
  .y(yscale)
  .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 (d3.select(g).select("text").text() == "") {
      d3.select(g).style("display", "none");
    } else {
      d3.select(g).style("display", "");
    }
  })
}

Now call this function after zoom.

working code here


Related Query

More Query from same tag