Повторный рендеринг HTML после масштабирования с помощью Dagre d3

#javascript #d3.js #svg #dagre-d3

#javascript #d3.js #svg #dagre-d3

Вопрос:

Редактировать Я нашел решение, включающее использование немного более старой версии библиотеки dagre-d3 (4.11). Если кто-нибудь сможет найти проблему в последней версии, это тоже поможет. Спасибо

Я использую Dagre d3 для рисования некоторых графиков.

При первоначальном рендеринге моего графика я делаю

 g = new dagreD3.graphlib.Graph()
          .setGraph({})
          .setDefaultEdgeLabel(function() { return {}; });
var svg = d3.select("svg"),
            inner = svg.select("g");
            svgGroup = svg.append("g");
var render = new dagreD3.render();

        render(d3.select("svg g"), g);

        var zoom = d3.behavior.zoom().on("zoom", function() {
              inner.attr("transform", "translate("   d3.event.translate   ")"  
                    "scale("   d3.event.scale   ")");
              currentZoomScale = d3.event.scale;
              currentPosition = d3.event.translate;

            });
        svg.call(zoom);
  

Затем, когда пользователь нажимает на определенный узел, я хочу добавить HTML к метке этого узла. Это не отображается, если я не перерисовываю график, что я делаю следующим образом:

 g.node(id).label  = "<div>"   inputTemplate   "</div>";

var zoom = d3.behavior.zoom()
        .scale(currentZoomScale)
        .on("zoom", function() {
        inner.attr("transform", "translate("   d3.event.translate   ")"   "scale("   d3.event.scale   ")")
                    });
        svg.call(zoom);

        d3.select("svg").on("dblclick.zoom", null);
        inner.attr("transform", "translate("   currentPosition   ")"   "scale("   currentZoomScale   ")");
  

Я думал, что, поддерживая currentPosition и currentZoomScale , я смогу убедиться, что график хорошо сохраняется после масштабирования и повторного рендеринга. Но это не тот случай. Все мои узлы становятся меньше, если я уменьшаю масштаб, и больше, если я увеличиваю масштаб.

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

1. Что вы подразумеваете под «остается хорошо»?

Ответ №1:

Я не совсем понимаю проблему, но может ли это быть из-за того, что вы включили .scale(currentZoomScale) во вторую строку

 var zoom = d3.behavior.zoom()
        .scale(currentZoomScale)
        .on("zoom", function() {
        inner.attr("transform", "translate("   d3.event.translate   ")"   "scale("   d3.event.scale   ")")
                    });
        svg.call(zoom);

        d3.select("svg").on("dblclick.zoom", null);
        inner.attr("transform", "translate("   currentPosition   ")"   "scale("   currentZoomScale   ")");
  

и затем вы снова масштабируете его в innner.attr() ?

Ответ №2:

Мне кажется, что проблема заключается здесь:

 var svg = d3.select("svg"),
    inner = svg.select("g");
    svgGroup = svg.append("g");
  

Если вы посмотрите на порядок вашего кода, там нет <g> when you define inner . Итак, на данный момент inner так null и есть. При повторном рендеринге диаграммы группа теперь присутствует, и inner это больше не null выделение.

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

 var svg = d3.select("svg"),
    svgGroup = svg.append("g");//we first append the <g>..    
    inner = svg.select("g");//and only after that we select it