Масштабирование оси — проблема с переводом — d3.js версия 4 —

#javascript #d3.js #zooming #axis

#javascript #d3.js #масштабирование #ось

Вопрос:

короткая версия: я использую масштабирование по оси и обычное масштабирование. Я объединяю оба вместе, и масштабирование работает нормально. Единственная проблема в том, что перевод работает не так, как я хочу. Перевод по осям не равен 1 к 1. Поведение перевода зависит от масштабного коэффициента обычного масштабирования.

мой статус: у меня есть линейный график с нормальным масштабированием. В дополнение к этому у меня есть масштабирование по оси. Итак, если я нахожусь в области оси Y, я хочу только увеличить ось Y и только перемещать ось Y вокруг. То же самое для оси X.

Для этого я использовал экземпляр d3.zoom и вызвал (zoom) для 3 разных прямоугольников.

  1. покрывает всю область графика
  2. распространяется только на ось x
  3. распространяется только на ось y

Преобразование сохраняется в элементах. Функция масштабирования применяет все 3 разных преобразования масштабирования к масштабу при запуске.

Настройка всего:

 graph.zoomXY = d3.zoom()
    .scaleExtent([-10, 1000]);

graph.overlayX = graph.g//.select(".axis.x")
    .append("rect")
    .attr("fill", "rgba(255,0,0,0.5)")
    .attr("width", graph.rectWidth)
    .attr("height", 15)
    .attr("y", graph.rectHeight)
    .call(graph.zoomXY);

graph.overlayY = graph.g//.select(".axis.y")
    .append("rect")
    .attr("fill", "rgba(255,0,0,0.5)")
    .attr("width", 150)
    .attr("height", graph.rectHeight)
    .attr("x", -150)
    .call(graph.zoomXY);

//append the rectangle to capture zoom
graph.overlayRect = graph.g.append("rect")
    .attr("class", "overlay-rect")
    .attr("width", graph.rectWidth)
    .attr("height", graph.rectHeight)
    .style("fill", "none")     
    .call(graph.zoomXY)
    .on("dblclick.zoom", function() {
        resetZoom();
    } );
  

Вычисление масштаба:

 function zoomed() {

    getZoomedScales();
    updateGraph();

}

function getZoomedScales() {

    var transformX = d3.zoomTransform(graph.overlayX.node());
    var transformY = d3.zoomTransform(graph.overlayY.node());
    var transformXY = d3.zoomTransform(graph.overlayRect.node());

    graph.yScaleTemp = transformXY.rescaleY(transformY.rescaleY(graph.yScale));
    graph.xScaleTemp = transformXY.rescaleX(transformX.rescaleX(graph.xScale));

}
  

Масштабирование работает нормально. Но на изменение масштаба осей (graph.overlayY и graph.overlayX) влияет коэффициент масштабирования масштабирования, применяемый к graph.overlayRect. Если я изменю порядок, проблема будет просто устранена. Масштабный коэффициент масштабирования осей (graph.overlayY и graph.overlayX) приводит к искажению преобразования масштабирования в graph.overlayRect.

Откройте скрипку и измените масштабирование, находясь над областью графика. Затем наведите курсор мыши на одну из осей. Повторите и посмотрите, как это изменяет перевод.

Вот пример:https://jsfiddle.net/9j4kqq1v /

Комментарии:

1. Итак, я проверил d3.js исходный код и я нашли причину. D3.js v4 сохраняет данные масштабирования в dom-элементе, что вполне очевидно. Но когда запускается onmousedowned и добавляется событие mousemove, оно использует только данные масштабирования, добавленные к этому dom-элементу. Это означает, что другие коэффициенты масштабирования не учитываются. Таким образом, обходной путь состоял бы в том, чтобы применить масштабный коэффициент из xy-zoom к dom-элементам для x-zoom и y-zoom при наведении курсора мыши и отменить его при запуске mosueup. Таким образом, перетаскивание работает должным образом.

2. Благодарим вас за публикацию вашего jsfiddle. Это было очень полезно!!