Координаты кисти D3 в масштабе преобразования CSS

Кисть D3 не работает должным образом в масштабе преобразования css. Когда svg находится под элементом div, а элемент div преобразован с использованием шкалы CSS, операция кисти показывает неправильные координаты.

Чтобы продемонстрировать этот случай, вот jsFiddle.

Это простая модификация из примера Brushable Network от Bostock.

Я просто поместил SVG в элемент div и увеличил масштаб элемента div на 50% с помощью шкалы преобразования CSS (0,5). И координаты чистки не обновляются из-за увеличения.

#test {
transform: scale(0.5);
}

Спасибо.

Deok


person intuinno    schedule 08.07.2015    source источник
comment
Вы можете найти аналогичную проблему для одного события мыши здесь. Он предлагает использовать следующий код для преобразования исходных координат. Но было бы здорово, если бы кто-нибудь мог указать подходящий подход к мероприятию кисти.   -  person intuinno    schedule 08.07.2015
comment
Ваш jsfiddle выдает ошибку.   -  person Lars Kotthoff    schedule 08.07.2015
comment
Сожалею, что правильная ссылка - jsfiddle.net/intuinno/5cpgkqhu   -  person intuinno    schedule 09.07.2015


Ответы (2)


Если вы используете преобразование на основе svg:

transform="scale(0.5)"

Тогда он будет хорошо играть с кистью:

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

svg = svg.append("g")
    .attr("transform","scale(0.5)");

Обновлен скрипка.

Чтобы исправить расчеты, вам понадобятся две вещи.

1.) Масштабируйте экстент прямо напротив div:

.extent {
   transform: scale(2);
}

2.) Исправьте расчеты экстентов:

   .on("brush", function() {
      var extent = d3.event.target.extent();
      node.classed("selected", function(d) {
        return extent[0][0] <= d.x && d.x < extent[1][0] && 
               extent[0][1] <= (d.y/2) && (d.y/2) < extent[1][1]; // scale y opposite div transform
      });
   });

Новый пример здесь.

person Mark    schedule 08.07.2015
comment
Спасибо за добрый ответ. Однако у меня нет доступа к svg из-за настроек в моем проекте. Итак, я ищу решение для преобразования на основе css. - person intuinno; 08.07.2015
comment
@intuinno, у вас нет доступа к SVG? если вы оставите преобразование в CSS, вам придется учесть его в вычислениях кисти. - person Mark; 09.07.2015
comment
да. Звучит странно, что у меня нет доступа к svg. Моя ситуация: я использую визуализацию d3 внутри объекта jsplumb. Объект jsplumb обрабатывает масштабирование в div с помощью преобразования css. Мне нужно закрасить какую-то область на SVG в div. Поэтому я не могу применить ваше решение. Не могли бы вы сообщить мне больше, чтобы учесть это при расчете кистей? - person intuinno; 09.07.2015
comment
@intuinno, см. новый ответ. - person Mark; 09.07.2015

Если вы используете преобразование CSS, вы должны применить его ко всем классам, связанным узлами:

 .node {
  stroke: #fff;
  stroke-width: 1.5px;
  transform: scale(0.5);
 }

 .node .selected {
        stroke: red;
  }

.link {
   stroke: #999;
     transform: scale(0.5);
  }

.brush .extent {
  fill-opacity: .1;
  stroke: #fff;
  shape-rendering: crispEdges;
  transform: scale(0.5);
}

Когда вы добавляете transform: scale(0.5);, вы можете очистить весь узел. Попробуйте использовать слева направо над положением узла.

 var width = 960,height = 500;
  var svg = d3.select("#body").append("svg")
        .attr("width", width)
        .attr("height", height);


    graph.links.forEach(function(d) {
        d.source = graph.nodes[d.source];
        d.target = graph.nodes[d.target];
    });

    var link = svg.append("g")
        .attr("class", "link")
        .selectAll("line")
        .data(graph.links)
        .enter().append("line")
        .attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    var node = svg.append("g")
        .attr("class", "node")
        .selectAll("circle")
        .data(graph.nodes)
        .enter().append("circle")
        .attr("r", 4)
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });

    var brush = svg.append("g")
        .attr("class", "brush")
        .call(d3.svg.brush()
            .x(d3.scale.identity().domain([0, width]))
            .y(d3.scale.identity().domain([0, height]))
            .on("brush", function() {
                var extent = d3.event.target.extent();
                node.classed("selected", function(d) {
                    return extent[0][0] <= d.x && d.x < extent[1][0]
                        && extent[0][1] <= d.y && d.y < extent[1][1];
                });
            }));

Заполните jsfiddle здесь.

person Gabriel    schedule 08.07.2015
comment
Спасибо за ответ. Однако я не уверен, что вы поделились правильной ссылкой jsfiddle. В jsfiddle, которым вы поделились, ошибка все еще существует. Не могли бы вы проверить еще раз? Thansk. - person intuinno; 09.07.2015
comment
Это правильная ссылка, потому что domain([0, width]) лучшая кисть находится слева направо. начните с левого положения и перетащите его в правое положение страницы, кисть будет работать правильно. - person Gabriel; 09.07.2015
comment
Нет, на мой взгляд, координаты кисти немного отличаются от положения мыши. Я думаю, что это не решает проблему кисти с преобразованием css. Мне жаль. - person intuinno; 09.07.2015