set d3 zoom scaleExtent to positive values

d3.js, zooming

Solution

The scale proceeds in a geometric series -- that is, the scale step before 1 is not 0, but 0.5. Limiting your scale extent to

.scaleExtent([0.5, 10])

should do what you want. I've also added `.nice()` to your scale definitions to get round numbers at the ends.

As for the clipping, no, this is not implicit in the translation. You need to clip explicitly using a clip path, which in your case can be defined as follows.

cp = svgContainer.append("defs").append("clipPath").attr("id", "cp")
        .append("rect")
        .attr("x", padding)
        .attr("y", padding)
        .attr("width", w - 2 * padding)
        .attr("height", h - 2 * padding)

All you then need to do is use it when adding the elements:

msBars = svgContainer.selectAll('line.matched_peak')
                    .data(jsonFragmentIons)
                    .enter()
                    .append("line")
                    .attr("clip-path", "url(#cp)")

Complete example here.

Problem

Well, first of all, here is a jsfiddle to illustrate what I would like to ask So I am trying to implement a zoom behaviour. I managed to limit the zooming by setting a translate to the zoom function, (which I don't really quite understand, Just got it from another SO question), and a scaleExtent([1,10]) on the zoom behaviour So this is the zoom behavior: ``` zoom = d3.behavior.zoom() .x(xScale) .y(yScale) .scaleExtent([1, 10]) .on("zoom", zoomed) ``` and this is the zoomed function: ``` zoomed = -> t = zoom.translate() s = zoom.scale() tx = t[0] ty = t[1] tx = Math.min(0, Math.max(w * (1-s), t[0])) ty = Math.min(0, Math.max((h-padding) * (1-s), t[1])) zoom.translate([tx, ty]) svgContainer.select("g.x.axis").call xAxis svgContainer.select("g.y.axis").call yAxis svgContainer.selectAll("line.matched_peak") .attr("x1", (d) -> return xScale(d.m_mz) ) .attr("y1", h - padding) .attr("x2", (d) -> return xScale(d.m_mz) ) .attr("y2", (d) -> return yScale(d.m_intensity) ) ``` However, setting the scaleExtent to `.scaleExtent([1, 10])` , makes that one particular point with a value of 1 in the y scale is never going to be displayed (first one on the left in the jsfiddle). But setting `.scaleExtent([0, 10])` disables the limit to zoom, and the user may zoom and pan below 0 in the y axis. Also tried `.scaleExtent([0.1, 10])` but this also allows zoom and pan below 0. So How could I allow zoom only to positive values from 0 (including a value of 1) ? And what function can be used to avoid the lines show beyond the axis? Is not that implicit when I use the translate function in the zoom?

Original source