Конвертируйте d3 svg координаты в координаты холста или попробуйте совпасть с одинаковой позицией для обоих - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть несколько d3 svg-элементов, в которых в качестве атрибута я передаю список координат x, y и наносю их на карту svg.Как в примере ниже:

var svg = iniMarker().append("g")
   .attr("data-lineData", JSON.stringify(lineData))
//Function to draw line
        var lineFunction = d3.svg.line()
            .x(function (d) { return d.x; })
            .y(function (d) { return d.y; });

Результирующая структура пути выглядит следующим образом:

<path d="M1100,850L1180,800" class="pPath" stroke-dasharray="94.33981323242188 94.33981323242188" stroke-dashoffset="0"></path>
<path d="M1180,800L1280,800" class="pPath" stroke-dasharray="100 100" stroke-dashoffset="0"></path>
<path d="M1280,800L1380,800" class="pPath" stroke-dasharray="100 100" stroke-dashoffset="0"></path>

В верхней части этого пути линии также есть круг, который принимает в качестве входных данных строкизначения координат:

var circle = svg.append("circle")
                .attr("r", 10)
                .attr("fill", "#fff")
                .attr("class", "marker")
                .attr("transform", function () {
                    return "translate(" + lineData[0].x + "," + lineData[0].y + ")";
                });

Данные, в которых я беру информацию о координатах, хранятся в этом формате:

var DataSet = [{
            "id": "",
            "isActive": true,
            "personId": "p1",
            "name": "test",
            "lineData": [
                { "timestamp": "2018/09/15 10:00:05 AM", "x": 1100, "y": 950 }]

Теперь мне нужно представить каждую из этих точек, взятых из этого списка координат на карте холста, точно наложенной на карту svg . И в этом случае проблема в том, что svg-координаты списка не совпадают с той же позицией координат холста.

На самом деле, если я пытаюсь сгенерировать некоторые координаты холста с помощьюиспользуя приведенную ниже функцию:

document.getElementById("canv").onclick = function (e) {
            var localX = e.clientX - e.target.offsetLeft;
            var localY = e.clientY - e.target.offsetTop;
}

Тогда координаты события onclick в значительной степени отличаются от координат SVG, которые я получил от DataSet obj в качестве позиции.

На самом деле для того, чтобысопоставляя их, я только что попытался передать объект DataSet для функции, чтобы получить координаты SVG и нанести их на карту холста, например:

DataSet.map(function (m) { if(m.isActive) return m.lineData; else return []; }).forEach(f => data = data.concat(f));

            data.forEach(e => {
                //here I call another function for plot the svg coordinates as points on the canvas map 
});

Но очевидно, что мне нужно преобразоватьсначала их, чтобы они соответствовали правильно.

Следуя предложению @enxaneta, мне нужно создать холст из этих объектов данных.Но проблема в том, что у меня уже есть координаты для svg, а не для формата canvas.

Мне нужно найти способ преобразовать список координат svg, который у меня есть, чтобы соответствовать или быть более похожимкак возможность для системы координат холста.

Я открыт для предложений.

1 Ответ

0 голосов
/ 26 сентября 2018

Ваш вопрос не очень понятен, но при условии, что у вас есть путь svg, вы можете преобразовать его в путь холста, используя объект Path2D : в следующем примере пути SVG красного цвета, пути холстаостаются черными.

var svgPathApple = Apple.getAttribute("d");
var svgPathLeaf = Leaf.getAttribute("d");

var c = document.getElementById("c");
var ctx = c.getContext("2d");
var cw = c.width = 500;
var ch = c.height = 500;

var apple = new Path2D(svgPathApple);
var leaf = new Path2D(svgPathLeaf);

ctx.stroke(apple);
ctx.stroke(leaf);
canvas,svg{border:1px solid #d9d9d9; width:45vw;}
path{fill: none; stroke:red;}
<svg viewBox="0 0 500 500">

	<path id="Apple" d="M376.349,171.58
		c0,0-37.276,22.484-36.094,60.946s31.438,61.577,42.012,63.313c4.127,0.678-24.314,57.988-42.039,72.189
		s-36.067,17.159-64.47,5.917c-28.403-11.242-48.521,0.724-65.089,6.871s-36.687-0.361-63.905-39.415
		s-57.396-129.585-15.976-173.964s87.574-26.627,100-20.71s34.32,5.325,59.172-5.917S363.922,153.237,376.349,171.58z"/>

	<path id="Leaf" d="M311.852,68.621c0,0,2.367,14.793-3.55,27.219
		s-28.189,55.061-60.473,47.337c-0.809-0.193-5.529-14.482,1.398-29.002C259.004,93.682,284.49,70.699,311.852,68.621z"/>

</svg>
<canvas id="c"></canvas>

ОБНОВЛЕНИЕ:

SVG обозначает масштабируемую векторную графику.Хотя ваш размер SVG такой же, как ваш холст, в действительности ваш SVG в четыре раза больше.Чтобы узнать реальный размер, вам нужно взглянуть на значение атрибута viewBox: «52 0 2104 1200».В переводе на обычный английский ширина вашего svg составляет 2104, а высота 1200. И это еще не все.Ваши координаты SVG начинаются с x = 52 и y = 0. Учитывая точку p = {x: 100, y: 100} в SVG, ваши координаты холста: x = (100 - 52)/2 и y = 100/2;

Далее следует простой пример, где я рисую круг на холсте и на элементе svg:

const canvas = document.getElementById("canv");
const ctx = canvas.getContext("2d");
let x = (100 - 52)/2, 
    y = 100/2,
    r = 10/2;


ctx.beginPath();
ctx.arc(x,y,5,0,2*Math.PI);
ctx.fill();
canvas,svg{border:1px solid;}
<svg version="1.1" id="svgMap" width="1052px" height="600px" viewBox="52 0 2104 1200">
  <circle  id="testCircle" cx="100" cy ="100" r="10" />
</svg>


<canvas width="1052" height="600" id="canv"></canvas> 

Надеюсь, это поможет.

...