математический перевод в SVG javascript - PullRequest
1 голос
/ 04 марта 2020

Я должен работать над сценарием визуализации, написанным на javascript и svg, используя d3.

Теперь я сталкиваюсь с различными системами координат.

  • Математические координаты (слева направо, снизу вверх) для исходных данных
  • SVG координаты (слева направо, сверху вниз) для svg canvas

Предлагает ли d3 или svg способ настроить холст с преобразованием для принятия математической модели, или я просто сделаю преобразование координат в коде?

1 Ответ

0 голосов
/ 05 марта 2020

Существует несколько различных решений, от хакерских transform = "scale(1,-1)" до чистых JavaScript функций для преобразования координат.

Однако самое простое идиоматическое решение c D3 - с использованием шкалы . Например, шкала, подобная этой ...

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

... будет довольно легко инвертировать вертикальную ось SVG сверху вниз, к более распространенной восходящей математической оси.

Вот демо. Сначала нормальный код с нанесением нескольких окружностей с помощью 0, 0, 2, 2, 4, 4 et c. как данные:

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>

Теперь тот же код, но с использованием шкалы для инвертирования вертикальных координат:

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>
...