michelmm
michelmm

Reputation: 48

math to svg coordinate translation in javascript

I have to work on a visualization script written in javascript and svg using d3.

Now I am faced eith the different coordinates systems.

Does d3 or svg offer a way to setup a canvas with a transformation to adopt the math model, or shall I just do a coordiante conversion in code?

Upvotes: 1

Views: 171

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102188

There are several different solutions, from the hacky transform = "scale(1,-1)" to pure JavaScript functions for converting the coordinates.

However, the simplest idiomatic D3 solution is using a scale. For instance, a scale like this...

const scale = d3.scaleLinear()
    .domain([0, height])
    .range([height, 0])

... will quite easily invert the SVG top-bottom vertical axis, to the more common bottom-up math axis.

Here is a demo. First the normal code, plotting some circles with 0, 0, 2, 2, 4, 4 etc. as the data :

const data = d3.range(100).map((d, i) => ({
  x: i * 2,
  y: d * 2
}));
const svg = d3.select("svg");
const circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("r", 1)
  .attr("cx", d => d.x)
  .attr("cy", d => d.y)
svg {
  background-color: lavender;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>

Now the same code, but using a scale for inverting the vertical coordinates:

const data = d3.range(100).map((d, i) => ({
  x: i * 2,
  y: d * 2
}));
const scale = d3.scaleLinear()
  .domain([0, 150])
  .range([150, 0]);
const svg = d3.select("svg");
const circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("r", 1)
  .attr("cx", d => d.x)
  .attr("cy", d => scale(d.y))
svg {
  background-color: lavender;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>

Upvotes: 1

Related Questions