d3 / d3-zoom

Pan and zoom SVG, HTML or Canvas using mouse or touch input.
https://d3js.org/d3-zoom
ISC License
507 stars 143 forks source link

Zoom with ScaleBand #134

Closed SnehaSSD closed 6 years ago

SnehaSSD commented 6 years ago

Hi,

I am currently using d3 v4. My x scale is a scaleBand where i am taking country name for the display and my y scale is scaleTime. When i am trying to get new xScale in zoom function its throwing error at rescaleX . I looked at many examples online but all of them either have a linerScale or scaleTime.

var countryArr = ["USA", "UK", "Poland", "Sweden"];
var firstDay = moment(day).subtract(1, 'days').toDate();
var lastDay = moment(day).add(1, 'days').toDate();

// define scale
var yScale = d3.scaleTime().range([0, width]); 
yScale.domain([firstDay, lastDay]);
var xScale = d3.scaleBand().range([0, height]);
xScale.domain(countryArr);

// define zoom
var zoom = d3.zoom()
    .scaleExtent([1, 1])
    .translateExtent([[margin.left, margin.top], [width, height]])
    .on("zoom", zoomed);

d3.select("#main-canvas").call(zoom);

function zoomed() {
    //console.log(d3.event.transform.y);
    var new_x = d3.event.transform.rescaleX(xScale);  // ERROR at this line
    var new_y = d3.event.transform.rescaleY(yScale); 
}
ullyw
mbostock commented 6 years ago

Per the README for transform.rescaleX:

Returns a copy of the continuous scale x whose domain is transformed. … The scale x must use d3.interpolateNumber; do not use continuous.rangeRound as this reduces the accuracy of continuous.invert and can lead to an inaccurate rescaled domain.

So no, you can’t use transform.rescaleX with a band scale. However, per d3/d3#2442, you can use the zoom behavior to modify a band scale’s range (rather than a continuous scale’s domain, as is more common). Here’s a demo:

https://beta.observablehq.com/@mbostock/d3-zoomable-bar-chart

alexvpickering commented 6 years ago

How would you go about hiding the bars as they are dragged to the left past the y-axis?

Akshita-Negi commented 6 years ago

You could use clip path where it can be defined as

svg.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) // width = width of graph area .attr("height", height); // height = height of graph area

Check out : https://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172

On Wed, Apr 25, 2018 at 9:30 PM, Alex Pickering notifications@github.com wrote:

How would you go about hiding the bars as they are dragged to the left past the y-axis?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/d3/d3-zoom/issues/134#issuecomment-384340195, or mute the thread https://github.com/notifications/unsubscribe-auth/AK5lCPIhyRajcn_FFlXFQQcww6zxGN8Eks5tsJ2OgaJpZM4Suuy7 .