Масштабирование приводит к выходу графика за границы области построения



У меня проблема с моим графом. Когда я увеличиваю масштаб, линия проходит по краю области холста и по оси x/Y. Я пробовал добавлять clippath, но это не похоже на работу. Если я проверю DOM в отладчике, то увижу, что прямоугольник clippath находится именно там, где ему нужно быть.



//The canvasGroup is the area between the axis
var clipGroup = canvasGroup.append("clipPath")
.attr("id", "canvasGroup-clipPath");

var clipRect = clipGroup.append("rect")
.attr("width", width)
.attr("height", height);

//Function that does the zooming
function doZoom()
{
paths.forEach(function(path)
{
path.attr("transform", d3.event.transform);
});

gX.call(xAxis.scale(d3.event.transform.rescaleX(xScale)));
gY.call(yAxis.scale(d3.event.transform.rescaleY(yScale)));
}

var zoom = d3.zoom()
.scaleExtent([1, 5])
.translateExtent([[0, 0], [width, height]])
.on("zoom", doZoom);

//Register the event listener
canvasGroup.call(zoom);

//now loop over the data sets and plot each one
//For brevity, I'm skipping the loop and only showing the call to create the line
var path = canvasGroup.append("path")
.attr("clip-path", "url(#canvasGroup-clipPath)")
.attr("fill", "steelblue")
.attr("class", "line")
.attr("id", lineId + "-line")
.style("stroke", lineColor)
.style("stroke-width", 1)
.style("fill", "none");

paths.push(path);
path.attr("d", function(d) { return plotline(i)});


Вот как это выглядит.
Прежде чем зум:
Заговор перед зумом
После увеличения:После масштабирования участок перекрывает ось Y

573   1  

1 ответ:

Проблема вызвана установкой пути отсечения на пути, представляющем ваши данные. При применении пути отсечения Обозревателю необходимо решить, какую систему координат следует использовать для содержимого элемента <clipPath>. Это контролируется clipPathUnits атрибут по умолчанию userSpaceOnUse:

UserSpaceOnUse
Содержание документа <clippath> элемент представляет значения в текущей пользовательской системе координат на месте в момент, когда <clippath> элемент является ссылочным (то есть пользовательская система координат для элемента, ссылающегося на <clippath> элемент через атрибутclip-path ).

Преобразуя путь в своей функции doZoom(), вы фактически устанавливаете новую систему координат для пути. И, помимо рисования самого пути, эта система координат будет использоваться для вычисления положения и размера пути отсечения. Таким образом, путем преобразования пути в соответствии с поведение масштабирования, вы применяете то же преобразование к контуру отсечения, перемещая его от желаемой позиции.

Хотя есть соблазн установить атрибут clipPathUnits на его другое допустимое значение objectBoundingBox, это, скорее всего, не то, что вы хотите для этого случая, поскольку это еще больше усложняет дело. При установке этого значения позиции и длины содержимого <clipPath> должны быть указаны как дроби из ограничительной коробки!

Зная все это, есть гораздо более простое решение этой проблемы! Вам просто нужно применить clip-path к элементу, который не будет преобразован во время масштабирования, например, к родительской группе. Учитывая неполный код, который вы предоставили, это вполне может сработать, установив путь отсечения в canvasGroup:

// Set the clipping path on the parent group.
canvasGroup.attr("clip-path", "url(#canvasGroup-clipPath)")    

// Append the path to the group as before.
var path = canvasGroup.append("path")
               .attr("fill", "steelblue")                  
               .attr("class", "line")
               // ...

Comments

    Ничего не найдено.