Skip to content
Advertisement

My rectangle don’t have the good coordinates without a zoom event in d3

I’m doing a zoom in a chart. But i have a problem. My rectangles need a zoom event to display at the correct position, if they do not have this event, they are displayed at wrong coordinates.

I have done a jsfiddle https://jsfiddle.net/Natko/mr1250un/90/

The problem is in this part of the code (i think)

   this.chart.selectAll()
        .data(this.viewpoint)
        .join("g")
        .attr("x", d => this.x(d.x))
        .attr("y", d => this.y(d.y))
        .append("rect")
        .attr("id", 'rectangle')
        .attr("width", 10)
        .attr("height", 10)
        .attr('fill', 'orange')
    }

All the attributes are working except the x and y coordinates. But when i’m updating the coordinates with my zoom event, they are displayed in the right place.

change(d) {
    var newX = d.transform.rescaleX(this.x);
    var newY = d.transform.rescaleY(this.y);

    this.xAxis.call(d3.axisBottom(newX))
    this.yAxis.call(d3.axisLeft(newY))

      this.chart.selectAll("#rectangle")
       .attr("x", d => newX(d.x) - 2)
       .attr("y", d => newY(d.y) - 5 )
  },

And here is the this.x and this.y

  this.x = d3.scaleLinear()
    .range([0, width - margin.left - margin.right]);

  this.y = d3.scaleLinear()
    .range([height - margin.top - margin.bottom, 0]);

  this.xAxis = this.chart.append("g")
    .attr(
      "transform",
      `translate(0, ${height - margin.top - margin.bottom})`
    );

  this.yAxis = this.chart.append("g");

Anyone have an idea to fix my problem ?

Advertisement

Answer

Your code has multiple errors and here are the main points:

  1. You add a <g> element and set its transform (I saw it in the fiddle, not in the question’s code sample) according to x and y, it’s OK.

  2. You add a <rect> under each <g> and assign the same id to all. It will not work, id should be unique. You don’t need the attribute at all, omit it.

  3. You cannot use x and y attributes for a <g> element. You should use transform: g.attr('transform', 'translate(x, y)')

  4. In ‘change’, you try to set the <rect> coordinates within its <g> instead of assign new transform to the <g> element itself. Keep the <rect> as is.

  5. You can calculate transform with a simple formula: transformedX = originalX * e.transform.k + e.transform.x, where e is a D3 zoom event.

Advertisement